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 + -
显示快捷键?