⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 starsclera.cpp

📁 barcode readers [ from Image]
💻 CPP
字号:
//
// CStarSclera -- find the sclera boundary given a point on its interior by searching
//                outwards in radial lines.
//
// Copyright (C) 2003, 2006 by Jon A. Webb (Contact via GMail; username is jonawebb)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#include "StarSclera.h"

#include <e32math.h>
#include <e32std.h>
#include "Image.h"
#include "RGBIndex.h"
#include "ImageSize.h"

using namespace Core;

namespace Algorithm
{

    EXPORT_C CStarSclera* CStarSclera::NewL(int nLines, int nStart, int nEnd, int nWidth, int nThresh)
    {
        CStarSclera* pMe = new (ELeave) CStarSclera(nLines, nStart, nEnd, nWidth, nThresh);
		CleanupStack::PushL(pMe);
        pMe->ConstructL();
		CleanupStack::Pop(pMe);
        return pMe;
    }

    CStarSclera::CStarSclera(int nLines, int nStart, int nEnd, int nWidth, int nThresh) :
        iLines(nLines), iStart(nStart), iEnd(nEnd), iWidth(nWidth), iThresh(nThresh),
            iCoords(NULL), iAllCoords(NULL), iMin(NULL), iAvg(NULL)
    {
    }

    CStarSclera::~CStarSclera(void)
    {
        delete[] iAvg;
        delete[] iMin;
        delete[] iCoords;
        delete[] iAllCoords;
    }

	// Fill in the relative x,y coordinates of the lines we will be tracing 
	// in the image. 
    void CStarSclera::ConstructL()
    {
		// Number of points in the lines
        const int nCoordLength = iEnd - iStart + iWidth * 2 + 1;
        ASSERT(nCoordLength > 0);
		// Create the array of points
        iAllCoords = new (ELeave) TPoint [iLines * nCoordLength];
        CleanupStack::PushL(iAllCoords);
		// Create the output array (one coordinate per line)
        iCoords = new (ELeave) TPoint* [iLines];
        CleanupStack::PushL(iCoords);
		// Create the array of minimum values (one for each point on the line)
        iMin = new (ELeave) int [nCoordLength];
        CleanupStack::PushL(iMin);
		// Create the array of average values (one for each point on the line)
        iAvg = new (ELeave) int [nCoordLength];
        CleanupStack::PushL(iAvg);
        int i=0;
        for (; i<iLines; i++) {
            // get pointer to the coords for this line
            iCoords[i] = iAllCoords + i * nCoordLength;
            // calculate the sin and cosine of the angle of this radial line
            TReal rAngle(2 * 3.14159 * i / iLines);
            TReal rCos, rSin;
            User::LeaveIfError(Math::Cos(rCos, rAngle));
            User::LeaveIfError(Math::Sin(rSin, rAngle));
            TInt32 nCos, nSin;
            // sin and cosine are scaled by 100.0 so we can do the calculation
			// using integers
            User::LeaveIfError(Math::Int(nCos, rCos * 100.0));
            User::LeaveIfError(Math::Int(nSin, rSin * 100.0));
            int j=0;
			// The line coordinate is sin(angle) * r, cos(angle) * r,
			// where r is the distance along the line
            for (; j<nCoordLength; j++) {
                iCoords[i][j].SetXY(nSin * (j+iStart-iWidth) / 100, 
                                    nCos * (j+iStart-iWidth) / 100);
            }
        }
		CleanupStack::Check(iAvg);
        CleanupStack::Pop(); // iAvg
		CleanupStack::Check(iMin);
        CleanupStack::Pop(); // iMin
		CleanupStack::Check(iCoords);
        CleanupStack::Pop(); // iCoords
		CleanupStack::Check(iAllCoords);
        CleanupStack::Pop(); // iAllCoords
    }

    // Calculate the sum of differences of minimum RGB values along the radial
    // lines stored in iCoords. The idea here is that the iris is colored and the
    // sclera is white, more or less. The minimum value of a whitish pixel will be
    // high, but the minimum value of a colored pixel will be low. So the difference
    // should be high at the sclera boundary.
    void CStarSclera::FindScleraL(CImage image, TPoint ptInt, TPoint* pBoundary)
    {
        IRgbIndex rRGB(image);
        IImageSize rSize(image);

        const int nCoordLength = iEnd - iStart + iWidth * 2 + 1;
        int i=0;
        for (; i<iLines; i++) {
            int j = 0;
            for (; j<nCoordLength; j++) {
                // first calculate the minimum RGB values along this line
                TPoint ptCoord(iCoords[i][j].iX + ptInt.iX, 
                               iCoords[i][j].iY + ptInt.iY);
                if (ptCoord.iX >= 0 && ptCoord.iX < rSize.Height() &&
                    ptCoord.iY >= 0 && ptCoord.iY < rSize.Width()) {
                        unsigned char* pRGB = rRGB[ptCoord.iX][ptCoord.iY];
                        iMin[j] = Min(pRGB[R], Min(pRGB[G], pRGB[B]));
                        iAvg[j] = (int(pRGB[R]) + int(pRGB[G]) + int(pRGB[B]))/3;
                    } else {
                        if (j>0) {
                            iMin[j] = iMin[j-1];
                            iAvg[j] = iAvg[j-1];
                        } else {
                            // this should never happen since the center coordinate
                            // should be sufficiently in the interior of the image
                            // that the first pixel looked at is in the image. But
                            // just in case...
                            iMin[j] = 0;
                            iAvg[j] = 0;
                        }
                    }
            }
            int nSumIris = 0, nSumSclera = 0, nAvgSclera = 0;
            // now form the difference of the first iWidth pixels
            // along the line with the second iWidth pixels
            for (j=0; j<iWidth; j++) {
                nSumIris += iMin[j];
            }
            for (; j<2*iWidth; j++) {
                nSumSclera += iMin[j];
                nAvgSclera += iAvg[j];
            }
            int nSum = - nSumIris;
            int nSum1 = 0, nSum2 = 0;
            int nBestIndex = -1;
            for (j=0; j<nCoordLength-2*iWidth; j++) {
				// nSum is the sum difference of the presumed sclera
				// and the presumed iris
                nSum = nSumSclera - nSumIris;
				// check if point is over threshold
                if (nSum1 > iThresh * iWidth && nSum1 > nSum && nSum1 > nSum2) {
                    nBestIndex = j;
                    break;
                }
                nSum2 = nSum1;
                nSum1 = nSum;
                // step to next sum
                nSumIris -= iMin[j]; // subtract left end
                nSumIris += iMin[j+iWidth]; // add right end
                nSumSclera -= iMin[j+iWidth]; // subtract left end
                nSumSclera += iMin[j+2*iWidth]; // add right end
                nAvgSclera -= iAvg[j+iWidth]; // subtract left end
                nAvgSclera += iAvg[j+2*iWidth]; // add right end
            }
            int nX = iCoords[i][nBestIndex + iWidth].iX + ptInt.iX;
            int nY = iCoords[i][nBestIndex + iWidth].iY + ptInt.iY;
			// see if there was a point found (over threshold) that is in
			// the interior of the image
            if (nBestIndex != -1 && nX >= 0 && nX < rSize.Height() &&
                nY >= 0 && nY < rSize.Width()) {
                pBoundary[i].SetXY(nX, nY);
            } else {
                pBoundary[i].SetXY(-1,-1);
            }
        }
    }

};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -