findpupil.cpp

来自「barcode readers [ from Image]」· C++ 代码 · 共 119 行

CPP
119
字号
//
// CFindPupil -- given the center of the eye, find the radius of the
//               pupil. Works by measuring the brightness of circles surrounding
//               the pupil. When the brightness suddenly increases, that is the
//               pupil edge.
//
// 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 "FindPupil.h"

#include "Image.h"
#include "ImageSize.h"
#include "RGBIndex.h"

using namespace Core;

namespace Algorithm
{
    EXPORT_C CFindPupil* CFindPupil::NewL(int nMinRadius, int nMaxRadius)
    {
        CFindPupil* pMe = new (ELeave) CFindPupil(nMinRadius, nMaxRadius);
        CleanupStack::PushL(pMe);
        pMe->ConstructL();
        CleanupStack::Pop(); // pMe
        return pMe;
    }

    CFindPupil::~CFindPupil(void)
    {
        delete[] ipSums;
        delete[] ipCount;
    }

    CFindPupil::CFindPupil(int nMinRadius, int nMaxRadius) :
        inMinRadius(nMinRadius),
        inMaxRadius(nMaxRadius),
        ipSums(NULL),
        ipCount(NULL)
    {
    }

    void CFindPupil::ConstructL()
    {
        ipSums = new (ELeave) int [inMaxRadius - inMinRadius + 1];
        CleanupStack::PushL(ipSums);
        ipCount = new (ELeave) int [inMaxRadius - inMinRadius + 1];
        CleanupStack::Pop(); // ipSums
    }

    void CFindPupil::FindPupilL(CImage image, TPoint ptCenter, int& nRadius)
    {
        IImageSize rSize(image);
        IRgbIndex rRGB(image);
        Mem::Fill(ipSums, inMaxRadius - inMinRadius + 1, 0);
        Mem::Fill(ipCount, inMaxRadius - inMinRadius + 1, 0);
        // first sum the pixels in each (filled) circle surrounding the center pixel
        int r = Max(0, ptCenter.iX - inMaxRadius);
        for (; r < Min(rSize.Height(), ptCenter.iX + inMaxRadius + 1); r++) {
            int c = Max(0, ptCenter.iY - inMaxRadius);
            for (; c < Min(rSize.Width(), ptCenter.iY + inMaxRadius + 1); c++) {
                int nDistSq = (r-ptCenter.iX) * (r-ptCenter.iX) + (c-ptCenter.iY) * (c-ptCenter.iY);
                int nRadius = inMaxRadius;
                int nPixel = Max(Max(rRGB[r][c][R], rRGB[r][c][G]), rRGB[r][c][B]);
                while (nRadius * nRadius >= nDistSq && nRadius >= inMinRadius) {
                    ipSums[nRadius - inMinRadius] += nPixel;
                    ipCount[nRadius - inMinRadius]++;
                    nRadius--;
                }
            }
        }
        // form the sums at the edge of each circle
        for (r = inMaxRadius - inMinRadius; r >= 0; r--) {
            ipSums[r] -= ipSums[r-1];
            ipCount[r] -= ipCount[r-1];
        }
        // find the biggest jump in average brightness
        int nPupil = ipSums[0], nPupilCount = ipCount[0];
        int nIris = 0, nIrisCount = 0;
        for (r = 1; r <= inMaxRadius - inMinRadius; r++) {
            nIris += ipSums[r];
            nIrisCount += ipCount[r];
        }
        int nBiggestDiff = (nIris/nIrisCount - nPupil/nPupilCount)/4;
        nRadius = -1;
        for (r = 1; r <= inMaxRadius - inMinRadius; r++) {
            if (nPupil != 0 && nIrisCount != 0) {
                int nDiff =  nIris / nIrisCount - nPupil * nPupilCount;
                if (nDiff > nBiggestDiff) {
                    nBiggestDiff = nDiff;
                    nRadius = r + inMinRadius;
                    break;
                }
            }
            nIris -= ipSums[r];
            nIrisCount -= ipCount[r];
            nPupil += ipSums[r];
            nPupilCount += ipCount[r];
        }
    }


};

⌨️ 快捷键说明

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