一、实现思路

调用电脑的摄像头,把摄像的信息逐帧分解成图片,基于图片检测标识出人脸的位置。
把处理的图片逐帧绘制给用户,用户看到的效果就是视频的人脸检测。

二、实现步骤

1、使用OpenCV调用摄像头

  1. VideoCapture camera = new VideoCapture();
  2. // 参数0表示,获取第一个摄像头。
  3. camera.open(0);

参数为0 ,表示 获取第一个摄像头。

2、显示摄像头

逐帧显示,代码如下:

  1. // 图像帧
  2. Mat frame = new Mat();
  3. for(;;) {
  4. camera.read(frame);
  5. draw(frame);
  6. // 等待用户按esc停止检测
  7. if(HighGui.waitKey(100) == 27) {
  8. break;
  9. }
  10. }
  11. // 释放摄像头
  12. camera.release();
  13. // 释放窗口资源
  14. HighGui.destroyAllWindows();

HighGui.waitKey(100) == 27 表示是获取用户输入ESC,则跳出循环。

3、视频的人脸识别

  1. /**
  2. * 逐帧处理
  3. * @param frame
  4. */
  5. private static void draw(Mat frame) {
  6. Mat grayFrame = new Mat();
  7. Imgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY);
  8. // OpenCv人脸识别分类器
  9. CascadeClassifier classifier = new CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml");
  10. // 用来存放人脸矩形
  11. MatOfRect faceRect = new MatOfRect();
  12. // 特征检测点的最小尺寸
  13. Size minSize = new Size(32, 32);
  14. // 图像缩放比例,可以理解为相机的X倍镜
  15. double scaleFactor = 1.2;
  16. // 对特征检测点周边多少有效检测点同时检测,这样可以避免选取的特征检测点大小而导致遗漏
  17. int minNeighbors = 3;
  18. // 执行人脸检测
  19. classifier.detectMultiScale(grayFrame, faceRect, scaleFactor, minNeighbors, CV_HAAR_DO_CANNY_PRUNING, minSize);
  20. Scalar color = new Scalar(0, 0, 255);
  21. for(Rect rect: faceRect.toArray()) {
  22. int x = rect.x;
  23. int y = rect.y;
  24. int w = rect.width;
  25. int h = rect.height;
  26. // 框出人脸
  27. Imgproc.rectangle(frame, new Point(x, y), new Point(x + h, y + w), color, 2);
  28. }
  29. HighGui.imshow("预览", frame);
  30. }

三、完成代码
image.png

  1. package com.opencv.api;
  2. import org.opencv.core.*;
  3. import org.opencv.highgui.HighGui;
  4. import org.opencv.imgproc.Imgproc;
  5. import org.opencv.objdetect.CascadeClassifier;
  6. import org.opencv.videoio.VideoCapture;
  7. import static org.bytedeco.javacpp.opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING;
  8. /**
  9. * 视频人脸检测
  10. * @Author xxk
  11. * @Date 2021/11/22 17:10
  12. * @Param
  13. * @return
  14. */
  15. public class VideoFace {
  16. static {
  17. // 加载 动态链接库
  18. // System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  19. System.load("E:\\OpenCv\\opencv\\build\\java\\x64\\opencv_java453.dll");
  20. }
  21. public static void main(String[] args) {
  22. VideoCapture camera = new VideoCapture();
  23. // 参数0表示,获取第一个摄像头。
  24. camera.open(0);
  25. // 图像帧
  26. Mat frame = new Mat();
  27. for(;;) {
  28. camera.read(frame);
  29. draw(frame);
  30. // 等待用户按esc停止检测
  31. if(HighGui.waitKey(100) == 100) {
  32. break;
  33. }
  34. }
  35. // 释放摄像头
  36. camera.release();
  37. // 释放窗口资源
  38. HighGui.destroyAllWindows();
  39. }
  40. /**
  41. * 逐帧处理
  42. * @param frame
  43. */
  44. private static void draw(Mat frame) {
  45. Mat grayFrame = new Mat();
  46. Imgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY);
  47. // OpenCv人脸识别分类器
  48. CascadeClassifier classifier = new CascadeClassifier("E:\\OpenCv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml");
  49. // 用来存放人脸矩形
  50. MatOfRect faceRect = new MatOfRect();
  51. // 特征检测点的最小尺寸
  52. Size minSize = new Size(32, 32);
  53. // 图像缩放比例,可以理解为相机的X倍镜
  54. double scaleFactor = 1.2;
  55. // 对特征检测点周边多少有效检测点同时检测,这样可以避免选取的特征检测点大小而导致遗漏
  56. int minNeighbors = 3;
  57. // 执行人脸检测
  58. classifier.detectMultiScale(grayFrame, faceRect, scaleFactor, minNeighbors, CV_HAAR_DO_CANNY_PRUNING, minSize);
  59. Scalar color = new Scalar(0, 0, 255);
  60. for(Rect rect: faceRect.toArray()) {
  61. int x = rect.x;
  62. int y = rect.y;
  63. int w = rect.width;
  64. int h = rect.height;
  65. // 框出人脸
  66. Imgproc.rectangle(frame, new Point(x, y), new Point(x + h, y + w), color, 2);
  67. }
  68. HighGui.imshow("预览", frame);
  69. }
  70. }