某工J2EE大作业
首先要做的事
1.下载openCV
连接:https://pan.baidu.com/s/1eyzqcjnw17s_LpDXVmt-rA
提取码:tqn1
2.准备好IDEA web项目,服务器是tomcat(其实其他也行)
在opencv安装目录下[opencv->build->java]根据电脑类型,复制x86或x64的dll文件
查看电脑类型方法:[我的电脑->属性] 看是基于什么的处理器
复制后,找到刚刚建的项目的java JDK目录
不知道的可以在IDEA 项目管理->SDK下找到,如图:
找到后,进入bin目录,将刚刚复制的dll文件粘贴到bin目录下
将要使用的jar包记得放在webWEB-INF目录下!(包括openCV的jar包)
刚刚的目录下有openCV的jar包,复制放置在项目的webWEB-INF目录下
(因为部署服务器会构建工件在C盘部署,所以本地指定的库路径在服务器上是无法使用的
因此必须以资源的形式一并构建过去)
以上就完成了OpenCV的环境配置,可以愉快的编写代码了!
以下是网络上的一个简单直方图匹配,侵删,稍作改进以适应tomcat的图片网络传输,成功率比较低,诸位也可以另寻算法
public class FaceCompare {
// 初始化人脸探测器
static CascadeClassifier faceDetector;
static {
//System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//这一步我是放在tomcat里加载的,不然会出现加载两次的错误
//最好使用单例模式搞定它
faceDetector = new CascadeClassifier("lib/cascade_frontalface_default.xml");
//加载数据集,数据集怎么获得见下文
}
// 灰度化人脸
public static Mat conv_Mat(String img) {
Mat image0 = Imgcodecs.imread(img);
if(image0.empty()){
System.out.println("图片空!");
}
Mat image1 = new Mat();
// 灰度化
Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY);
// 探测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image1, faceDetections);
// rect中人脸图片的范围
for (Rect rect : faceDetections.toArray()) {
Mat face = new Mat(image1, rect);
return face;
}
return null;
}
public static double compare_image(Mat mat_1, Mat mat_2) {
Mat hist_1 = new Mat();
Mat hist_2 = new Mat();
//颜色范围
MatOfFloat ranges = new MatOfFloat(0f, 256f);
//直方图大小, 越大匹配越精确 (越慢)
MatOfInt histSize = new MatOfInt(1000000);
Imgproc.calcHist(Arrays.asList(mat_1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
Imgproc.calcHist(Arrays.asList(mat_2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);
// CORREL 相关系数
double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
return res;
}
//返回查询到的人脸编号
public static String find(Mat mat_1,String realPath){
String realName=null;
double hist=0;
double tempHist=0;
System.out.println("路径是:"+realPath);
System.out.println("第一张图片是:"+realPath+"p1000.jpg");
for (int i = 1000; i < 1003; i++) {
File file=new File(realPath+"p1000.jpg");
if(file.exists()&&file.isFile()){
System.out.println("是文件");
}
BufferedImage image=null;
try {
FileInputStream fin =new FileInputStream(realPath+"p"+i+".jpg");
image=ImageIO.read(fin);
} catch (IOException e) {
e.printStackTrace();
}
if((tempHist=compare_image(mat_1,BufImageToMat.bufferToMartix(image)))>hist){
hist=tempHist;
realName=""+i;
}
}
if(hist<0.2){
return "null";
}
return realName;
}
public static void main(String[] args) {
String basePicPath = "test";//本地测试使用的路径
double compareHist = compare_image(conv_Mat(basePicPath + "//p1000.jpg"), conv_Mat(basePicPath + "//test001.jpg"));
System.out.println(compareHist);
if (compareHist > 0.72) {
System.out.println("人脸匹配");
} else {
System.out.println("人脸不匹配");
}
//System.out.println(find(conv_Mat(basePicPath+"//test001.jpg")));
FileInputStream fin = null;
BufferedImage image = null;
try {
fin = new FileInputStream("test/test001.jpg");
//转为image
image = ImageIO.read(fin);
} catch (IOException e) {
e.printStackTrace();
}
BufImageToMat tool=new BufImageToMat();
//转为Mat开始比较,并传给FaceCompare类,返回数据库编号
Mat mat=tool.BufImg2Mat(image,BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
String num=FaceCompare.find(mat,"web/Picture/");
//test
System.out.println(num);
}
}
上面代码中提到的关于数据集部分
数据集的好坏决定了匹配的成功率
OpenCV提供了一些训练好的数据集可以供我们使用
在opencv安装目录【opencvsourcesdatahaarcascades】中
红线是三个正面人脸匹配的数据集,各有优劣,可以搜搜区别
可以看出老外还是比较闲,连cat face都做了hhh
(未完待续…)
有问题欢迎私聊



