学习 opencv - 记录学习
package cn.js.ccit.opencv.reco;
import org.opencv.core.Mat; import org.opencv.highgui.HighGui; import org.opencv.videoio.VideoCapture; import java.net.URL; /** * @Description 读取摄像头 * @Author CodeHaywire * @Created at 2022-02-06 10:16 */ public class ReadVideoData { static void showCamera() { // 加载动态库 URL url = ClassLoader.getSystemResource("lib/opencv_java411.dll"); System.load(url.getPath()); //打开相机 VideoCapture videoCapture = new VideoCapture(); //判断相机是否打开 0:表示打开默认摄像头 if (!videoCapture.open(0)) { System.out.println("相机打开失败"); return; } //循环获取画面 while (true) { //新建关键帧(图片数据每一张都存在里面) Mat img = new Mat(); //读取并判断 是否读取到 if (!videoCapture.read(img)) { return; } //展示图片 HighGui:opencv自带的窗口 HighGui.imshow("my camera video", img); //延迟10ms展示图片 HighGui.waitKey(10); } } }
package cn.js.ccit.opencv.reco;
import org.junit.jupiter.api.Test;
/**
* @Description 测试
* @Author CodeHaywire
* @Created at 2022-02-06 10:17
*/
public class ReadVideoDataTest {
@Test
public void testReadVideoData() {
ReadVideoData.showCamera();
}
}
每秒钟播放24帧,人眼能看到连续的画面,所以获取的关键帧连续展示在窗口就会看起来像视频
文件结构 opencv:下载 咔咔咔 下一步 从安装目录拿出这两文件 opencv-xxx.jar opencv_javaxxx.dll 最后将架(jar)包 add library 即可
接着写 人脸检测和获取人脸训练数据存放到本地
MatOfRect 矩形区域的像素点的集合 (个人理解)
for (Rect rect : matOfRect.toArray()) { System.out.println(rect); } // 输出: 起始点 矩形大小 rect.with rect.height 可以取出矩形的长宽 {258, 198, 149x149} {264, 195, 149x149}
CascadeClassifier 加载检测文件的对象
Imgproc 处理图片的类
Imgcodecs 保存图片的类
package cn.js.ccit.opencv.reco; import org.opencv.core.*; import org.opencv.highgui.HighGui; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; import org.opencv.videoio.VideoCapture; import java.net.URL; /** * @Description 读取摄像头 * @Author CodeHaywire * @Created at 2022-02-06 10:16 */ public class ReadVideoData { static void showCamera() { // 加载动态库 URL url = ClassLoader.getSystemResource("lib/opencv_java411.dll"); System.load(url.getPath()); //添加人脸检测 CascadeClassifier detector = new CascadeClassifier("src/main/resources/DetectData/haarcascade_frontalface_default.xml"); //打开相机 VideoCapture videoCapture = new VideoCapture(); int count = 1; //判断相机是否打开 if (!videoCapture.open(0)) { System.out.println("相机打开失败"); return; } //循环获取画面 while (true) { //存放关键帧对象 Mat img = new Mat(); if (!videoCapture.read(img)) { return; } Mat gray = new Mat(); //将彩色画面转成灰度 检测:通常都是用灰度,检测更精确 Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGB2GRAY); MatOfRect matOfRect = new MatOfRect(); //将符合的数据区域框选 detector.detectMultiScale(gray, matOfRect); for (Rect rect : matOfRect.toArray()) { //System.out.println(rect); Imgproc.putText(gray, "YouName", new Point(rect.x + 5, rect.y - 8), 1, 1.0, new Scalar(255, 255, 255)); Imgproc.rectangle( gray, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 255, 255), 1, 4); //保存人脸区域图片到本地 Imgcodecs.imwrite("src/main/resources/img/" + count + ".jpg", gray.submat(new Rect(rect.x, rect.y, rect.width, rect.height))); count++; } HighGui.imshow("my camera video", img); HighGui.waitKey(10); } } }
接着干 训练数据,提高验证正确率,但100%还是不可能的
Python 的face相关模块可以用,但是java版的该模块因不稳定在主项目中移除了,需要自己重新编译运行生成完整jar
可以参照官或者这个博主的文章 https://www.icode9.com/content-1-298318.html
由于没有face相关识别就先不实现训练数据人脸对比了,等我编译出来了完整jar包再说
转成图片相似度对比
package cn.js.ccit.opencv.comp; import org.opencv.core.*; import org.opencv.highgui.HighGui; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; import org.opencv.videoio.VideoCapture; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * @Description 比较两张图片人脸的匹配度 * 原理 : * 1. 灰度化(减小图片大小) * 2. 人脸识别 * 3. 人脸切割 * 4. 直方图相似度匹配 CV_COMP_CORREL 相关性比较算法 * @Author CodeHaywire * @Created at 2022-02-07 11:51 */ public class FaceCompare { static { // 加载动态库 URL url = ClassLoader.getSystemResource("lib/opencv_java455.dll"); System.load(url.getPath()); } /** * 彩色图片转灰度 */ static Mat cvtImgToGray(Mat face) { Mat grayFace = new Mat(); Imgproc.cvtColor(face, grayFace, Imgproc.COLOR_RGB2GRAY); return grayFace; } /** * 图片对比 */ static double compareImg(Mat grayFace, String sqlFace) { List gfList = new ArrayList<>(); List sfList = new ArrayList<>(); Mat sFace = Imgcodecs.imread(sqlFace); Mat cFace = cvtImgToGray(sFace); gfList.add(grayFace); sfList.add(cFace); //存放直方值 Mat hist_1 = new Mat(); Mat hist_2 = new Mat(); //颜色范围 MatOfFloat ranges = new MatOfFloat(0f, 256f); //直方图大小,越大匹配越慢 结果越精确 MatOfInt histSize = new MatOfInt(1000); //计算直方值 Imgproc.calcHist(gfList, new MatOfInt(0), new Mat(), hist_1, histSize, ranges); Imgproc.calcHist(sfList, new MatOfInt(0), new Mat(), hist_2, histSize, ranges); // res 相关系数 对比直方值 double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL); return res; } static void showCamera() { //添加人脸检测 CascadeClassifier detector = new CascadeClassifier("src/main/resources/DetectData/haarcascade_frontalface_default.xml"); //打开相机 VideoCapture videoCapture = new VideoCapture(); //判断相机是否打开 if (!videoCapture.open(0)) { System.out.println("相机打开失败"); return; } //循环获取画面 while (true) { //存放关键帧对象 Mat img = new Mat(); if (!videoCapture.read(img)) { return; } //将彩色画面转成灰度 Mat gray = cvtImgToGray(img); MatOfRect matOfRect = new MatOfRect(); //检测灰度图,将符合区域存在MatOfRect detector.detectMultiScale(gray, matOfRect); for (Rect rect : matOfRect.toArray()) { //在彩图中框选框选人脸 Imgproc.rectangle( img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 255, 255), 1, 4); //获取的人脸部分存放在Mat里 Mat face = new Mat(gray, rect); //与数据库的人脸进行对比 double v = compareImg(face, "src/main/resources/img/1.jpg"); System.out.println(v); } HighGui.imshow("my camera video", img); HighGui.waitKey(10); } } }
package cn.js.ccit.opencv.comp; import org.junit.jupiter.api.Test; /** * @Description TODO * @Author CodeHaywire * @Created at 2022-02-07 11:51 */ public class FaceCompareTest { @Test public void faceCompare() { FaceCompare.showCamera(); } }
结果: 是使用的匹配的人脸(我) 0.9125234821221283 0.8965588269011584 0.8786549462021448 0.8786549462021448 0.8387727275205578 0.8315250148777042 使用: 麦麦(赵今麦) 0.07287158869172858 0.0797435690147237 0.024495920668897244 0.024495920668897244 0.010139715957173966 -0.01785953384059259 0.03628837760179462
日常学习 文章被收录于专栏
记录日常学习