📄 facedetector.java
字号:
package visage_v3_2;
/*Autor: Adel Restom adel_restom@yahoo.com*/
import java.util.*;
import java.awt.*;
import svm.*;
/*
This class detects the eyes and nose locations in a given frame
*/
public class FaceDetector
{
final int fWidth = 320, fHeight = 240;
int[] labels, start, binaryPixels;
public int[] grayPixels,pixels;
int[][] s, ii, clustersMembers, eyes;
int faces, cluster;
svm_model model;
svm_node nodes[];
//////////////////////////////
public FaceDetector(svm_model model)
{
pixels = new int[fWidth * fHeight];
grayPixels = new int[fWidth * fHeight];
binaryPixels = new int[fWidth * fHeight];
s = new int[fWidth][fHeight];
ii = new int[fWidth][fHeight];
clustersMembers = new int[fWidth][fHeight];
labels = new int[fWidth * fHeight];
nodes = new svm_node[735];
this.model = model;
start = new int[model.nr_class];
start[0] = 0;
for (int i = 1; i < model.nr_class; i++)
start[i] = start[i - 1] + model.nSV[i - 1];
}
////////////////////////////////////////
public int[] detectAllFaces(Image image)
{
//Initializing
pixels = ImageProcessing.extractPixels(image,0,0,fWidth, fHeight, pixels);
grayPixels = ImageProcessing.toGrayscale(pixels, grayPixels);
binaryPixels = ImageProcessing.toBinary(grayPixels,binaryPixels,128);
ii = ImageProcessing.calculateIntegralImage(fWidth, fHeight, grayPixels, s, ii);
faces = 0;
int coords[];
//Apply biggest filter first
// SSRFilter filter1 = new SSRFilter(120,72, ii);
// coords = detectFaces(filter1);
//If no faces were found with the previous filter apply a smaller one, and so on...
// if (faces == 0)
{
SSRFilter filter2 = new SSRFilter(84, 54, ii);
coords = detectFaces(filter2);
}
if (faces == 0)
{
SSRFilter filter3 = new SSRFilter(60, 36, ii);
coords = detectFaces(filter3);
}
return coords;
}
////////////////////////////////////////
private int[] detectFaces(SSRFilter filter)
{
//Detect faces with the given filter
//If the pixel is a face candidate find it's cluster
int xCor, yCor, label = 0;
for (int i = 0; i < fWidth; i++)
for (int j = 0; j < fHeight; j++)
clustersMembers[i][j] = 0;
ConnectedComponents CC = new ConnectedComponents(labels, clustersMembers);
for (int y = 0; y < fHeight - filter.getHeight(); y++)
for (int x = 0; x < fWidth - filter.getWidth(); x++)
{
xCor = x + 1 + (filter.getWidth() / 2); //+1 : transition error in sectors calculation
yCor = y + 1 + (filter.getHeight() / 2);
if (filter.foundFaceCandidate(x, y) &&
ImageProcessing.isSkinPixel(pixels[yCor * fWidth + xCor]))
label = CC.findClustersLabels(xCor, yCor,fWidth);
}
//If there are face candidates
if (label != 0)
{
//Find root labels,and their centers
int centers[][] = CC.processClusters(filter.getArea()/48d,fWidth,fHeight);
//If there are valid clusters
if (centers != null)
{
//Find left/right pupils for each of the candidates
cluster = CC.getCluster();
int counter = findPupilsCandidates(filter,centers);
//if found some eyes
if( counter != -1 )
{
//Load templates to the array in order to classify them
Vector templates = loadEyesTemplates(counter);
//Classiffying templates
double cResults[] = classify(templates);
//Multiply classification results by clusters' areas
if( cluster > 1 )
cResults = multiplyByArea(CC.indecies,CC.clusters,CC.counters,cResults);
//Find the template with the highest score
int face[] = findBestEyesTemplate(cResults);
//Find nose tip
if( face != null )
{
Point noseTip = findNoseTip(face);
if( noseTip != null )
{
int coordinates[] = new int[6];
coordinates[0] = face[0];
coordinates[1] = face[1];
coordinates[2] = face[2];
coordinates[3] = face[3];
coordinates[4] = (int)noseTip.getX();
coordinates[5] = (int)noseTip.getY();
return coordinates;
}
}
}
}
}
return null;
}
//////////////////////////////////////////////
private Point findPupil(int x0, int y0,int width,int height,int labels[], int pupilsMembers[][],int limit)
{
int label = 0; //binarize the sector and look for the appropriate cluster
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
pupilsMembers[x][y] = 0;
ConnectedComponents CC = new ConnectedComponents(labels,pupilsMembers);
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
if( binaryPixels[ (y + y0) * fWidth + (x + x0)] == 1 )
label = CC.findClustersLabels(x, y, width);
if( label != 0 )
{
CC.findRootLabels();
return CC.findPupilsClustersCenters(x0,y0,CC.clusters,limit,width,height,grayPixels,fWidth);
}
else
return null;
}
/////////////////////////////////////////////
private int findPupilsCandidates(SSRFilter filter,int centers[][])
{
eyes = new int[cluster][5];
int width = filter.getWidth()/3;
int height = filter.getHeight()/2;
int labels[] = new int[width*height];
int pupilsMembers[][] = new int[width][height];
int limit = (int)filter.getArea()/(144*6);
int halfW, halfH, sixthW, counter = -1;
halfW = filter.getWidth() / 2;
halfH = filter.getHeight() / 2;
sixthW = filter.getWidth() / 6;
Point lp1,rp1;
int x, y;
for (int i = 1; centers[i][0] != Integer.MAX_VALUE; i++)//pass all clusters
{
x = centers[i][0];
y = centers[i][1];
//find left pupil in sector s1
lp1 = findPupil(x-halfW,y-halfH,width,height,labels,pupilsMembers,limit);
if( lp1 == null )
continue;
//find right pupil in sector s3
rp1 = findPupil(x+sixthW,y-halfH,width,height,labels,pupilsMembers,limit);
if( rp1 == null )
continue;
counter++;
eyes[counter][0] = (int)lp1.getX()+x-halfW;
eyes[counter][1] = (int)lp1.getY()+y-halfH;
eyes[counter][2] = (int)rp1.getX()+x+sixthW;
eyes[counter][3] = (int)rp1.getY()+y-halfH;
eyes[counter][4] = i;
}
return counter;
}
//////////////////////////////////////////
private svm_node[] extractEyesTemplate(int x0,int y0,int x1,int y1)
{
int xLen,yLen,sX,sY,cX,cY,oX,oY;
double xInc,yInc,nY,scale;
svm_node node;
svm_node template[] = new svm_node[735];
xLen = x1-x0;
yLen = y1-y0;
xInc = (double)xLen / 23d;
yInc = (double)yLen / 23d;
scale = Math.sqrt(Math.pow(xLen,2)+Math.pow(yLen,2))/23d;
oX = x0 - (int)(6*xInc) + (int)(8*yInc);
nY = (yLen != 0 ? (8*yInc*xLen) / yLen : 8*scale);
oY = y0-(int)nY;
sX = oX;
sY = oY; //derotate the template to a horizontal position
for (int y = 0; y < 21; y++)
{
cX = sX;
cY = sY;
for (int x = 0; x < 35; x++)
{
node = new svm_node();
node.index = y * 35 + x + 1;
if ( (cX >= 0) && (cX < fWidth) && (cY < fHeight) && (cY >= 0) )
node.value = grayPixels[cY * fWidth + cX] / 255d;
else
if( y == 0 )
node.value = 128d/255d;
else
node.value = template[ (y - 1) * 35 + x].value;
template[y * 35 + x] = node;
cX = sX+(int)((x+1)*xInc);
cY = sY+(int)((x+1)*yInc);
}
sX = oX-(int)((y+1)*yInc);
sY = oY+(int)((y+1)*xInc);
}
return template;
}
//////////////////////////////////////////
private Vector loadEyesTemplates(int counter)
{
svm_node[] template;
Vector templates = new Vector();
//Extract the templates and write them in the 'LibSVM' file format
for (int i = 0; i <= counter; i++)
{
template = extractEyesTemplate(eyes[i][0], eyes[i][1],
eyes[i][2], eyes[i][3]);
templates.add(template);
}
return templates;
}
/////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -