📄 facedetector.java
字号:
private double[] classify(Vector templates)
{
double cResults[] = new double[templates.size()];
double[] decValues = new double[1];
for (int i = 0; i < templates.size(); i++)
{
svm.svm_predict_values(model, (svm_node[]) templates.get(i), decValues, start);
cResults[i] = decValues[0] * model.label[0];
}
return cResults;
}
//////////////////////////////////////////////////
private double[] multiplyByArea(int indecies[],int clusters[],int counters[],double cResults[])
{
for (int i = 0; i < cResults.length; i++)
if( cResults[i] > 0 )
cResults[i] *= counters[indecies[clusters[eyes[i][4]]]];
return cResults;
}
//////////////////////////////////////////////////
private int[] findBestEyesTemplate(double cResults[])
{
double max = 0d;
int index = 0;
for (int i=0 ; i< cResults.length ; i++)
if( cResults[i] > max )
{
max = cResults[i];
index = i;
}
if( max>0 )
{
faces++;
int face[] = new int[4];
face[0] = eyes[index][0];
face[1] = eyes[index][1];
face[2] = eyes[index][2];
face[3] = eyes[index][3];
return face;
}
else
return null;
}
//////////////////////////////////////////////////
private Point[] findNoseBridge(int length,int ii[][])
{
int val,max,nbcx = 0,counter = 0;
SSRFilter filter = new SSRFilter(length/2,1,ii);
Point candidates[] = new Point[length];
for(int y=0 ; y < length ; y++)
{
max = Integer.MIN_VALUE;
for(int x=0 ; x < length-filter.getWidth() ; x++)
{
val = filter.findNoseBridgeCandidate(x,y);
if( val > max )
{
max = val;
nbcx = x + 1 + (filter.getWidth() / 2);
}
}
if( max != Integer.MIN_VALUE )
{
counter++;
candidates[y] = new Point(nbcx, max);
}
}
if( counter > (length/5) )
return candidates;
else
return null;
}
////////////////////////////////////////////////
private int findNextCandidate(int i,Point candidates[])
{
while( (candidates[i] == null) && (i < candidates.length-1) )
{
i++;
}
return i;
}
////////////////////////////////////////////////
private int[] calculateGradiants(Point candidates[],int length)
{
int gradiants[] = new int[length],i=0,ind1=0,ind2=0;
for (int q = 0; q < gradiants.length; q++)
gradiants[q] = Integer.MAX_VALUE;
Point c1,c2;
while( true )
{
ind1 = findNextCandidate(ind2,candidates);
c1 = candidates[ind1];
if( c1 != null )
{
if (ind1 + 1 < length)
{
ind2 = findNextCandidate(ind1 + 1, candidates);
c2 = candidates[ind2];
if (c2 != null)
{
gradiants[ind2] = (int)(c2.getY() - c1.getY());
if( ind2 == length-1 )
break;
}
else
break;
}
else
break;
}
else
break;
}
return gradiants;
}
//////////////////////////////////////////////////
private Point findNoseTip(int face[])
{
int x1,y1,x2,y2,xLen,yLen,length,step,sX,sY,cX,cY;
double slope;
x1 = face[0];
y1 = face[1];
x2 = face[2];
y2 = face[3];
xLen = x2-x1;
yLen = y2-y1;
length = (int)Math.sqrt(Math.pow(xLen,2)+Math.pow(yLen,2));
step = Math.abs(yLen != 0 ? xLen/yLen : xLen);
step = ( step < 3 ? 3 : step );
slope = ( yLen < 0 ? -1 : 1);
int ROI[] = new int[length*length];
sX = x1;
sY = y1;
for (int y = 0; y < length; y++) //extract face 'Rigion Of Interest'
{
cX = sX;
cY = sY;
for (int x = 0; x < length; x++)
{
if ( (cX >= 0) && (cX < fWidth) && (cY < fHeight))
ROI[y * length + x] = grayPixels[cY * fWidth + cX];
else
ROI[y * length + x] = ROI[(y-1)*length+x];
cX++;
if ( (x + 1) % step == 0)
cY = (int) (cY + slope);
}
if ( (y + 1) % step == 0)
sX = (int) (sX - slope);
sY++;
}
int ii[][] = new int[length][length];
int s[][] = new int[length][length];
ii = ImageProcessing.calculateIntegralImage(length,length,ROI,s,ii);
Point candidates[] = findNoseBridge(length,ii); //find nose bridge candidates
if( candidates != null )
{
int gradiants[] = calculateGradiants(candidates, length);
int uMin1 = Integer.MAX_VALUE,uMin2 = Integer.MAX_VALUE,
lMin1 = Integer.MAX_VALUE,lMin2 = Integer.MAX_VALUE;
int lMinGrad,lMinIndex,uMinGrad,uMinIndex,minGrad,minIndex;
int uInd1=0,uInd2=0,lInd1=0,lInd2=0,gLength;
gLength = gradiants.length;
for(int i=0 ; i<gLength/4 ; i++)
if( gradiants[i] < uMin1 )
{
uMin1 = gradiants[i];
uInd1 = i;
}
for(int i=gLength/4 ; i<gLength/2 ; i++)
if( gradiants[i] < uMin2 )
{
uMin2 = gradiants[i];
uInd2 = i;
}
for(int i=gLength/2 ; i<3*gLength/4 ; i++)
if( gradiants[i] < lMin1 )
{
lMin1 = gradiants[i];
lInd1 = i;
}
for(int i=3*gLength/4 ; i<gLength ; i++)
if( gradiants[i] < lMin2 )
{
lMin2 = gradiants[i];
lInd2 = i;
}
if( (double)lMin2/(double)lMin1 >= 0.5 )
{
lMinGrad = lMin1;
lMinIndex = lInd1;
}
else
{
lMinGrad = lMin2;
lMinIndex = lInd2;
}
if( (double)uMin1/(double)uMin2 >= 0.5 )
{
uMinGrad = uMin2;
uMinIndex = uInd2;
}
else
{
uMinGrad = uMin1;
uMinIndex = uInd1;
}
if( (double)uMinGrad/(double)lMinGrad >= 0.5 )
{
minGrad = lMinGrad;
minIndex = lMinIndex;
}
else
{
minGrad = uMinGrad;
minIndex = uMinIndex;
}
int start;
if( minIndex >= gLength/2)
{
if (minIndex < 3 * gLength / 4)
start = gLength / 2;
else
start = 3 * gLength / 4;
}
else
start = 0;
int max = 0,index = 0;
for( int i=start ; i<=minIndex ; i++ ) //after finding the smallest gradiant ( nose trills ) find the largest
if( (gradiants[i] > max) && (gradiants[i] != Integer.MAX_VALUE) ) //gradiant above it ( nose tip )
{
max = gradiants[i];
index = i;
}
if( candidates[index] == null )
return null;
Point noseTip = new Point((int)candidates[index].getX(),index);
slope = (double)yLen / (double)xLen;
double angle = Math.atan(slope); //rotate ROI to it's original state
double x = Math.cos(angle)*noseTip.getX()-Math.sin(angle)*noseTip.getY();
double y = Math.sin(angle)*noseTip.getX()+Math.cos(angle)*noseTip.getY();
x += face[0];
y += face[1];
noseTip.setLocation(x,y);
return noseTip;
}
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -