环境搭建见:https://blog.csdn.net/v_gbird/article/details/80299931
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
接下来通过文件路径加载文件生成Mat对象
Mat src = Imgcodecs.imread(filePath+fileName,3);
加载方式为三通道,因此Mat中保存的是彩色对象,这也是方便后期对人脸所在位置进行标识,以及图片裁剪。之后需要将彩色图片转换为灰度图像,通过使用cvtColor函数实现:
Mat gray = new Mat();
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
opencv中关于人脸识别已经有相关的库,相关的文件在$OPENCV_HOME/sources/data目录下,在该目录下可以看到有三个文件夹
分别是依据haar特征、hogc特征、ibp级联对人脸识别训练的模型数据,本例中我们加载的是haar特征中已经训练好的face特征以及eye特征,分别是haarcascade_frontalface_alt文件和haarcascade_eye.xml文件。个人比较推荐讲该文件copy到项目的根目录下。并且创建分类器实例,相关代码如下:
CascadeClassifier eye_Classfier = new CascadeClassifier();
CascadeClassifier face_Classfier = new CascadeClassifier();
if(!eye_Classfier.load("./haarcascade_eye.xml")){
System.out.println("Load haarcascade_eye.xml failed");
System.exit(0);
}
if(!face_Classfier.load("./haarcascade_frontalface_alt.xml")){
System.out.println("Load haarcascade_frontalface_alt.xml");
System.exit(0);
}
public void detectMultiScale(Mat image, MatOfRect objects);
public void detectMultiScale(Mat image, MatOfRect objects, double scaleFactor, int minNeighbors, int flags, Size minSize, Size maxSize)
//
// C++: void detectMultiScale(Mat image, vector_Rect& objects, double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size())
//
//javadoc: CascadeClassifier::detectMultiScale(image, objects, scaleFactor, minNeighbors, flags, minSize, maxSize
MatOfRect eye_matOfRect = new MatOfRect();
MatOfRect face_matOfRect = new MatOfRect();
//find eyes
eye_Classfier.detectMultiScale(Contrast, eye_matOfRect);//, 1.1, 3, 3, new Size(30, 30), new Size(width, height));
System.out.println(eye_matOfRect.size().toString());
face_Classfier.detectMultiScale(Contrast, face_matOfRect);//, 1.1, 3, 3, new Size(30, 30), new Size(width, height));
System.out.println(face_matOfRect.size().toString());
Point p1 = new Point(eye_matOfRect.get(0, 0));
Point p2 = new Point(eye_matOfRect.get(1, 0));
Point pf = new Point(face_matOfRect.get(0, 0));
Double width = getWild(pf.x, p1.x, p2.x);
Double height = getHeight(pf.y, p1.y, p2.y);
Point init_ps = new Point(pf.x, pf.y - height);
Point init_pe = new Point(pf.x + width * 3, pf.y + height*4);
private Double getWild(Double start, Double y1, Double y2){ return (y1 + y2 - 2 * start)/2; }
private Double getHeight(Double start, Double y1, Double y2){ return ((y1+y2)/2 - start); }
private Rect getFinalRect(Point initX, Point initY, Double MaxX, Double MaxY){
Double x1 = initX.x;
Double x2 = initY.x;
Double y1 = initX.y;
Double y2 = initY.y;
Double minx = 0.0;
Double miny = 0.0;
Double maxX = 0.0;
Double maxY = 0.0;
if(x1 > x2){
if(x2 > 0) minx = x2;
else minx = 0.0;
if(x1 0 ) minx = x1;
else minx = 0.0;
if(x2 < MaxX) maxX = x2;
else maxX = MaxX;
}
if( y1 > y2){
if(y2 > 0) miny = y2;
else miny = 0.0;
if(y1 < MaxY) maxY = y1;
else maxY = MaxY;
}else{
if(y1 > 0) miny = y1;
else miny = 0.0;
if(y2 < MaxY) maxY = y2;
else maxY = MaxY;
}
System.out.println(miny);
Point ps = new Point(minx, miny);
Point pe = new Point(maxX, maxY);
System.out.println("Final : " + ps + pe);
Rect roi = new Rect(ps, pe);
return roi;
}
Rect roi = getFinalRect(init_ps, init_pe, src.width() + 0.0, src.height() + 0.0);
Mat dst = new Mat(src,roi);
Imgcodecs.imwrite("resultFace.jpg", dst);