OpenCV实现人脸识别
环境搭建:https://blog.csdn.net/colourful_sky/article/details/69487720 功能:调用系统摄像头检测人脸,检测到一张完整人脸后自动关闭摄像头窗口并将人脸保存到本地,没有检测到人脸或检测到多张人脸给提示继续直到检测到完整人脸
1 package com.jf,opencv; 2 3 import java.awt.image.BufferedImage; 4 5 import javax.swing.JFrame; 6 import javax.swing.JPanel; 7 import javax.swing.WindowConstants; 8 9 import org.opencv.core.Core; 10 import org.opencv.core.Mat; 11 import org.opencv.core.MatOfRect; 12 import org.opencv.core.Point; 13 import org.opencv.core.Rect; 14 import org.opencv.core.Scalar; 15 import org.opencv.imgcodecs.Imgcodecs; 16 import org.opencv.imgproc.Imgproc; 17 import org.opencv.objdetect.CascadeClassifier; 18 import org.opencv.videoio.VideoCapture; 19 import org.opencv.videoio.Videoio; 20 21 22 public class OpencvTest extends JPanel { 23 static class Haha { 24 private Mat mat; 25 private int num; 26 27 public Mat getMat() { 28 return mat; 29 } 30 public void setMat(Mat mat) { 31 this.mat = mat; 32 } 33 public int getNum() { 34 return num; 35 } 36 public void setNum(int num) { 37 this.num = num; 38 } 39 } 40 41 private static final long serialVersionUID = 1L; 42 @SuppressWarnings("unused") 43 private BufferedImage mImg; 44 45 private BufferedImage mat2BI(Mat mat){ 46 int dataSize = mat.cols()*mat.rows()*(int)mat.elemSize(); 47 byte[] data = new byte[dataSize]; 48 mat.get(0, 0,data); 49 int type = mat.channels() == 1 ? BufferedImage.TYPE_BYTE_GRAY:BufferedImage.TYPE_3BYTE_BGR; 50 if(type == BufferedImage.TYPE_3BYTE_BGR){ 51 for(int i = 0;i < dataSize;i += 3){ 52 byte blue = data[i + 0]; 53 data[i + 0] = data[i + 2]; 54 data[i + 2] = blue; 55 } 56 } 57 BufferedImage image = new BufferedImage(mat.cols(),mat.rows(),type); 58 image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data); 59 return image; 60 } 61 62 public static void main(String[] args) { 63 try{ 64 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 65 Mat capImg = new Mat(); 66 //启动摄像头 67 VideoCapture capture = new VideoCapture(0); 68 int height = (int)capture.get(Videoio.CAP_PROP_FRAME_HEIGHT); 69 int width = (int)capture.get(Videoio.CAP_PROP_FRAME_WIDTH); 70 if(height == 0 || width == 0){ 71 throw new Exception("camera not found!"); 72 } 73 //使Java实现窗体功能 74 JFrame frame = new JFrame("camera"); 75 //用户单击窗口的关闭按钮时执行的操作 76 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); //关闭窗体时,自动隐藏并释放窗体 77 OpencvTest panel = new OpencvTest(); 78 frame.setContentPane(panel); //给窗体加个面板 79 frame.setVisible(true); //这个组件显示为可见 80 frame.setSize(width+frame.getInsets().left+frame.getInsets().right, 81 height+frame.getInsets().top+frame.getInsets().bottom); 82 int n = 0; 83 while(frame.isShowing() && n != 1){ 84 capture.read(capImg);//获取视频帧 85 //将 capImg 按照 Imgproc.COLOR_RGB2GRAY 的色彩空间转换到 temp 86 // Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY); 87 Imgcodecs.imwrite("D:/opencv/images/back"+ (n + 1) +".png", capImg); //将色彩空间转换后的capImg保存到本地 88 Haha haha = detectFace(capImg); 89 panel.mImg = panel.mat2BI(haha.getMat()); //人像画红框 90 int num = haha.getNum(); 91 if(num == 1) 92 n = num ; 93 else if(num > 1) 94 System.out.println("1个人?"); 95 else 96 System.out.println("有人吗"); 97 panel.repaint();//重绘窗口 98 } 99 capture.release(); 100 frame.dispose(); //关闭窗口 101 frame = null; 102 }catch(Exception e){ 103 System.out.println("例外:" + e); 104 }finally{ 105 System.out.println("--done--"); 106 } 107 } 108 109 /** 110 * opencv实现人脸识别 111 * @param img 112 */ 113 public static Haha detectFace(Mat img) throws Exception{ 114 Haha haha = new Haha(); 115 System.out.println("Running DetectFace ... "); 116 // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中 117 CascadeClassifier faceDetector = new CascadeClassifier(System.getProperty("user.dir") + "\\bin\\openccv\\haarcascade_frontalface_alt.xml"); 118 119 // 在图片中检测人脸 120 MatOfRect faceDetections = new MatOfRect(); 121 faceDetector.detectMultiScale(img, faceDetections); 122 123 Rect[] rects = faceDetections.toArray(); 124 if(rects != null && rects.length >= 1){ 125 for (Rect rect : rects) { 126 //处理直方图 127 Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), 128 new Scalar(0, 0, 255), 2); 129 } 130 } 131 haha.setMat(img); 132 haha.setNum(rects.length); 133 return haha; 134 } 135 }