OPENCV+JAVA 人脸识别

骑猪看日落 2021-06-11 15:10 773阅读 0赞

http://opencv.org/releases.html

官方下载 安装文件 ,以win7为例,下载opencv-2.4.13.3-vc14.exe

安装后,在build目录下 D:\opencv\build\java,获取opencv-2413.jar,copy至项目目录

同时需要dll文件 与 各 识别xml文件,进行不同特征的识别(人脸,侧脸,眼睛等)

dll目录:D:\opencv\build\java\x64\opencv_java2413.dll

xml目录:D:\opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml(目录中有各类识别文件)

项目结构:

Center

具体代码:由于需要用到 opencv 的dll文件,故要么放在java library path 中,或放在jre lib 中,windows下可放在System32目录下

也可以在代码中 动态加载,如下:

  1. package opencv;
  2. import com.sun.scenario.effect.ImageData;
  3. import org.opencv.core.*;
  4. import org.opencv.core.Point;
  5. import org.opencv.highgui.Highgui;
  6. import org.opencv.imgproc.Imgproc;
  7. import org.opencv.objdetect.CascadeClassifier;
  8. import javax.imageio.ImageIO;
  9. import javax.swing.*;
  10. import java.awt.*;
  11. import java.awt.image.BufferedImage;
  12. import java.io.File;
  13. import java.io.IOException;
  14. import java.util.Arrays;
  15. import java.util.Vector;
  16. /**
  17. * Created by Administrator on 2017/8/17.
  18. */
  19. public class Test {
  20. static{
  21. // 导入opencv的库
  22. String opencvpath = System.getProperty("user.dir") + "\\opencv\\x64\\";
  23. String libPath = System.getProperty("java.library.path");
  24. String a = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
  25. System.load(opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll");
  26. }
  27. public static String getCutPath(String filePath){
  28. String[] splitPath = filePath.split("\\.");
  29. return splitPath[0]+"Cut"+"."+splitPath[1];
  30. }
  31. public static void process(String original,String target) throws Exception {
  32. String originalCut = getCutPath(original);
  33. String targetCut = getCutPath(target);
  34. if(detectFace(original,originalCut) && detectFace(target,targetCut)){
  35. }
  36. }
  37. public static boolean detectFace(String imagePath,String outFile) throws Exception
  38. {
  39. System.out.println("\nRunning DetectFaceDemo");
  40. // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
  41. CascadeClassifier faceDetector = new CascadeClassifier(
  42. "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml");
  43. Mat image = Highgui.imread(imagePath);
  44. // 在图片中检测人脸
  45. MatOfRect faceDetections = new MatOfRect();
  46. faceDetector.detectMultiScale(image, faceDetections);
  47. System.out.println(String.format("Detected %s faces",
  48. faceDetections.toArray().length));
  49. Rect[] rects = faceDetections.toArray();
  50. if(rects != null && rects.length > 1){
  51. throw new RuntimeException("超过一个脸");
  52. }
  53. // 在每一个识别出来的人脸周围画出一个方框
  54. Rect rect = rects[0];
  55. Core.rectangle(image, new Point(rect.x-2, rect.y-2), new Point(rect.x
  56. + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
  57. Mat sub = image.submat(rect);
  58. Mat mat = new Mat();
  59. Size size = new Size(300, 300);
  60. Imgproc.resize(sub, mat, size);//将人脸进行截图并保存
  61. return Highgui.imwrite(outFile, mat);
  62. // 将结果保存到文件
  63. // String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\faceDetection.png";
  64. // System.out.println(String.format("Writing %s", filename));
  65. // Highgui.imwrite(filename, image);
  66. }
  67. public static void setAlpha(String imagePath,String outFile) {
  68. /**
  69. * 增加测试项
  70. * 读取图片,绘制成半透明
  71. */
  72. try {
  73. ImageIcon imageIcon = new ImageIcon(imagePath);
  74. BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(),imageIcon.getIconHeight()
  75. , BufferedImage.TYPE_4BYTE_ABGR);
  76. Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
  77. g2D.drawImage(imageIcon.getImage(), 0, 0,
  78. imageIcon.getImageObserver());
  79. //循环每一个像素点,改变像素点的Alpha值
  80. int alpha = 100;
  81. for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
  82. for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
  83. int rgb = bufferedImage.getRGB(j2, j1);
  84. rgb = ( (alpha + 1) << 24) | (rgb & 0x00ffffff);
  85. bufferedImage.setRGB(j2, j1, rgb);
  86. }
  87. }
  88. g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
  89. //生成图片为PNG
  90. ImageIO.write(bufferedImage, "png", new File(outFile));
  91. }
  92. catch (Exception e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. private static void watermark(String a,String b,String outFile, float alpha) throws IOException {
  97. // 获取底图
  98. BufferedImage buffImg = ImageIO.read(new File(a));
  99. // 获取层图
  100. BufferedImage waterImg = ImageIO.read(new File(b));
  101. // 创建Graphics2D对象,用在底图对象上绘图
  102. Graphics2D g2d = buffImg.createGraphics();
  103. int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
  104. int waterImgHeight = waterImg.getHeight();// 获取层图的高度
  105. // 在图形和图像中实现混合和透明效果
  106. g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
  107. // 绘制
  108. g2d.drawImage(waterImg, 0, 0, waterImgWidth, waterImgHeight, null);
  109. g2d.dispose();// 释放图形上下文使用的系统资源
  110. //生成图片为PNG
  111. ImageIO.write(buffImg, "png", new File(outFile));
  112. }
  113. public static boolean mergeSimple(BufferedImage image1, BufferedImage image2, int posw, int posh, File fileOutput) {
  114. //合并两个图像
  115. int w1 = image1.getWidth();
  116. int h1 = image1.getHeight();
  117. int w2 = image2.getWidth();
  118. int h2 = image2.getHeight();
  119. BufferedImage imageSaved = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_ARGB);
  120. Graphics2D g2d = imageSaved.createGraphics();
  121. // 增加下面代码使得背景透明
  122. g2d.drawImage(image1, null, 0, 0);
  123. image1 = g2d.getDeviceConfiguration().createCompatibleImage(w1, w2, Transparency.TRANSLUCENT);
  124. g2d.dispose();
  125. g2d = image1.createGraphics();
  126. // 背景透明代码结束
  127. // for (int i = 0; i < w2; i++) {
  128. // for (int j = 0; j < h2; j++) {
  129. // int rgb1 = image1.getRGB(i + posw, j + posh);
  130. // int rgb2 = image2.getRGB(i, j);
  131. //
  132. // if (rgb1 != rgb2) {
  133. // //rgb2 = rgb1 & rgb2;
  134. // }
  135. // imageSaved.setRGB(i + posw, j + posh, rgb2);
  136. // }
  137. // }
  138. boolean b = false;
  139. try {
  140. b = ImageIO.write(imageSaved, "png", fileOutput);
  141. } catch (IOException ie) {
  142. ie.printStackTrace();
  143. }
  144. return b;
  145. }
  146. public static void main(String[] args) throws Exception {
  147. String a,b,c,d;
  148. a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzl.jpg";
  149. d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgx.jpg";
  150. //process(a,d);
  151. a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzlCut.jpg";
  152. d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgxCut.jpg";
  153. CascadeClassifier faceDetector = new CascadeClassifier(
  154. "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml");
  155. CascadeClassifier eyeDetector1 = new CascadeClassifier(
  156. "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye.xml");
  157. CascadeClassifier eyeDetector2 = new CascadeClassifier(
  158. "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye_tree_eyeglasses.xml");
  159. Mat image = Highgui.imread("C:\\Users\\Administrator\\Desktop\\opencv\\gakki.jpg");
  160. // 在图片中检测人脸
  161. MatOfRect faceDetections = new MatOfRect();
  162. //eyeDetector2.detectMultiScale(image, faceDetections);
  163. Vector<Rect> objects;
  164. eyeDetector1.detectMultiScale(image, faceDetections, 2.0,1,1,new Size(20,20),new Size(20,20));
  165. Rect[] rects = faceDetections.toArray();
  166. Rect eyea,eyeb;
  167. eyea = rects[0];eyeb = rects[1];
  168. System.out.println("a-中心坐标 " + eyea.x + " and " + eyea.y);
  169. System.out.println("b-中心坐标 " + eyeb.x + " and " + eyeb.y);
  170. //获取两个人眼的角度
  171. double dy=(eyeb.y-eyea.y);
  172. double dx=(eyeb.x-eyea.x);
  173. double len=Math.sqrt(dx*dx+dy*dy);
  174. System.out.println("dx is "+dx);
  175. System.out.println("dy is "+dy);
  176. System.out.println("len is "+len);
  177. double angle=Math.atan2(Math.abs(dy),Math.abs(dx))*180.0/Math.PI;
  178. System.out.println("angle is "+angle);
  179. for(Rect rect:faceDetections.toArray()) {
  180. Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x
  181. + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
  182. }
  183. String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\ouput.png";
  184. System.out.println(String.format("Writing %s", filename));
  185. Highgui.imwrite(filename, image);
  186. // watermark(a,d,"C:\\Users\\Administrator\\Desktop\\opencv\\zzlTm2.jpg",0.7f);
  187. //
  188. // // 读取图像,不改变图像的原始信息
  189. // Mat image1 = Highgui.imread(a);
  190. // Mat image2 = Highgui.imread(d);
  191. // Mat mat1 = new Mat();Mat mat2 = new Mat();
  192. // Size size = new Size(300, 300);
  193. // Imgproc.resize(image1, mat1, size);
  194. // Imgproc.resize(image2, mat2, size);
  195. // Mat mat3 = new Mat(size,CvType.CV_64F);
  196. // //Core.addWeighted(mat1, 0.5, mat2, 1, 0, mat3);
  197. //
  198. // //Highgui.imwrite("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg", mat3);
  199. //
  200. // mergeSimple(ImageIO.read(new File(a)),
  201. // ImageIO.read(new File(d)),0,0,
  202. // new File("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg"));
  203. }
  204. }

最终效果:人脸旁有绿色边框,可以将绿色边框图片截取,生成人脸图

发表评论

表情:
评论列表 (有 0 条评论,773人围观)

还没有评论,来说两句吧...

相关阅读

    相关 人脸识别

    计划 实现了一个基于 PCA 的人脸识别 方法 ,我 称之为 “ 特征点方法 ”, 所有的功能简单而且实用 。 下面,我使用一个简单的MATLAB脚本 说明 它的用法

    相关 人脸识别

    人脸检测 [长文干货!走近人脸检测:从 VJ 到深度学习(上)][VJ] [长文干货!走近人脸检测:从VJ到深度学习(下)][VJ 1]

    相关 人脸识别系统_人脸注册

        基于上次的人脸检测后,一直纠结人脸注册,照片存放方式,我想到了两种方式,1.数据库存照片存放的路径,2.数据库存放照片的二进制码。但是针对我的毕业设计我想要是存路径的话

    相关 人脸识别系统_人脸检测

    项目:基于人脸识别的无卡ATM机模拟系统 主要实现内容: 包括实现AMT机模拟人脸识别和密码输入、PC端模拟实现储户数据库服务器系统。 1. ATM模拟端实现采用手

    相关 人脸识别杂谈

    Gabor 及 LBP 特征描述子是迄今为止在人脸识别领域最为成功的两种人工设计局部描述子。 对各种人脸识别影响因子的针对性处理也是那一阶段的研究热点,比如人脸光照归一化、人