📄 starsclera.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 + -