Java使用opencv实现人脸识别、人脸比对

1. opencv概述

OpenCV是一个开源的计算机视觉库,它提供了一系列丰富的图像处理和计算机视觉算法,包括图像读取、显示、滤波、特征检测、目标跟踪等功能。

opencv官网:https://opencv.org/

2. 安装opencv
2.1 下载opencv

opencv下载:https://opencv.org/releases/
在这里插入图片描述
这里我们使用4.7.0版本,下载到本地后,双击进行安装即可。

进入到opencv的安装目录:
在这里插入图片描述

build :基于window构建sources:开源,提供源码

进入到build\java 目录
在这里插入图片描述

x64与x86目录下是对应的.dll文件:代表给不同的系统使用,下面的代码会使用到.dll文件
opencv-460.jar给java操作openvc的程序包

3. 代码实现
3.1 pom.xml添加依赖

版本的依赖与下载的opencv版本一致

<dependency><groupId>org.bytedeco</groupId><artifactId>opencv</artifactId><version>4.7.0-1.5.9</version></dependency>
3.2 编写代码

ps:代码中存在加载.dll、haarcascade_frontalface_alt.xml文件,请确保文件地址正确

package com.testpro.test.opencv;import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;import java.util.Arrays;public class FaceCompare {// 初始化人脸探测器static CascadeClassifier faceDetector;private static final String PATH_PREFIX = "C:\\Users\\dev\\Desktop\\";static int i = 0;static {// 判断系统String os = System.getProperty("os.name");// 加载动态库if (os != null && os.toLowerCase().startsWith("windows")) {// Windows操作系统// todo windows 系统部署加载 .dll 文件 - 路径跟据自己存放位置更改【这里需要使用绝对路径】System.load("D:\\opencv\\opencv\\build\\java\\x64\\opencv_java470.dll");} else if (os != null && os.toLowerCase().startsWith("linux")) {// Linux操作系统// todo Linux 服务器部署加载 .so 文件 - 路径跟据自己存放位置更改【是否需要绝对路径有待验证,目前只在windows 系统实践过】System.load("/opt/face/libopencv_java440.so");}// 引入 特征分类器配置 文件:haarcascade_frontalface_alt.xml 文件路径// 此文件在opencv的安装目录build\etc\haarcascades下可以找到String property = "D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";System.out.println(property);faceDetector = new CascadeClassifier(property);}public static void main(String[] args) {// 图片路径不能包含中文String str1 = PATH_PREFIX + "3-1.jpg";String str2 = PATH_PREFIX + "3-2.jpg";long start = System.currentTimeMillis();double compareHist = compare_image(str1, str2);System.out.println("time:" + (System.currentTimeMillis() - start));System.out.println(compareHist);if (compareHist > 0.6) {System.out.println("人脸匹配");} else {System.out.println("人脸不匹配");}}// 灰度化人脸public static Mat conv_Mat(String img) {Mat image0 = Imgcodecs.imread(img);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(String img_1, String img_2) {Mat mat_1 = conv_Mat(img_1);Mat mat_2 = conv_Mat(img_2);Mat hist_1 = new Mat();Mat hist_2 = new Mat();//颜色范围MatOfFloat ranges = new MatOfFloat(0f, 256f);//直方图大小, 越大匹配越精确 (越慢)MatOfInt histSize = new MatOfInt(10000000);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;}}

上述代码加载.dll文件也可使用以下方式:

ps:【不过以下方式需要将opencv安装目录下的build\java\x64\opencv_java470.dll文件复制到C:\Windows\System32目录下才可使用否则会报错】

// 使用此方法需将D:\opencv\opencv\build\java\x64\opencv_java470.dll文件复制到C:\Windows\System32目录下
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

如下:
在这里插入图片描述

4. 效果

在这里插入图片描述

5. 附:完整代码

包括:
从摄像头实时人脸识别,识别成功保存图片到本地
从本地视频文件中识别人脸
本地图片人脸识别,识别成功并保存人脸图片到本地

package com.testpro.test.opencv;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 org.opencv.videoio.VideoWriter;
import org.opencv.videoio.Videoio;import java.util.Arrays;/*** Opencv 图片人脸识别、实时摄像头人脸识别、视频文件人脸识别*/
public class FaceVideo {// 初始化人脸探测器static CascadeClassifier faceDetector;static int i = 0;static {// 判断系统String os = System.getProperty("os.name");// 加载动态库if (os != null && os.toLowerCase().startsWith("windows")) {// Windows操作系统// todo windows 系统部署加载 .dll 文件 - 路径跟据自己存放位置更改System.load("D:\\opencv\\opencv\\build\\java\\x64\\opencv_java470.dll");
//            ClassLoader.getSystemResource("dlls/opencv_java470.dll");} else if (os != null && os.toLowerCase().startsWith("linux")) {// Linux操作系统// todo Linux 服务器部署加载 .so 文件 - 路径跟据自己存放位置更改System.load("/opt/face/libopencv_java440.so");}// 引入 特征分类器配置 文件:haarcascade_frontalface_alt.xml 文件路径String property = "D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";System.out.println(property);faceDetector = new CascadeClassifier(property);}private static final String PATH_PREFIX = "C:\\Users\\dev\\Desktop\\";public static void main(String[] args) {// 1- 从摄像头实时人脸识别,识别成功保存图片到本地
//        getVideoFromCamera();// 2- 从本地视频文件中识别人脸
//        getVideoFromFile();// 3- 本地图片人脸识别,识别成功并保存人脸图片到本地
//        face("5-1.jpg");// 4- 比对本地2张图的人脸相似度 (越接近1越相似)double compareHist = compare_image(PATH_PREFIX + "5-1.jpg", PATH_PREFIX + "6-1.jpg");System.out.println(compareHist);if (compareHist > 0.72) {System.out.println("人脸匹配");} else {System.out.println("人脸不匹配");}}/*** OpenCV-4.7.0 从摄像头实时读取*/public static void getVideoFromCamera() {//1 如果要从摄像头获取视频 则要在 VideoCapture 的构造方法写 0VideoCapture capture = new VideoCapture(0);Mat video = new Mat();int index = 0;if (capture.isOpened()) {while (i < 3) {// 匹配成功3次退出capture.read(video);HighGui.imshow("实时人脸识别", getFace(video));index = HighGui.waitKey(100);if (index == 27) {capture.release();break;}}} else {System.out.println("摄像头未开启");}try {capture.release();Thread.sleep(1000);System.exit(0);} catch (InterruptedException e) {e.printStackTrace();}return;}/*** OpenCV-4.7.0 从视频文件中读取*/public static void getVideoFromFile() {VideoCapture capture = new VideoCapture();capture.open(PATH_PREFIX + "yimi.mp4");//1 读取视频文件的路径if (!capture.isOpened()) {System.out.println("读取视频文件失败!");return;}Mat video = new Mat();int index = 0;while (capture.isOpened()) {capture.read(video);//2 视频文件的视频写入 Mat video 中HighGui.imshow("本地视频识别人脸", getFace(video));//3 显示图像index = HighGui.waitKey(100);//4 获取键盘输入if (index == 27) {//5 如果是 Esc 则退出capture.release();return;}}}/*** OpenCV-4.7.0 人脸识别** @param image 待处理Mat图片(视频中的某一帧)* @return 处理后的图片*/public static Mat getFace(Mat image) {// 1 读取OpenCV自带的人脸识别特征XML文件(faceDetector)
//        CascadeClassifier facebook = new CascadeClassifier("D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");// 2 特征匹配类MatOfRect face = new MatOfRect();// 3 特征匹配faceDetector.detectMultiScale(image, face);Rect[] rects = face.toArray();System.out.println("匹配到 " + rects.length + " 个人脸");if (rects != null && rects.length >= 1) {// 4 为每张识别到的人脸画一个圈for (int i = 0; i < rects.length; i++) {Imgproc.rectangle(image, new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(0, 255, 0));Imgproc.putText(image, "Human", new Point(rects[i].x, rects[i].y), Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1, Imgproc.LINE_AA, false);//Mat dst=image.clone();//Imgproc.resize(image, image, new Size(300,300));}i++;if (i == 3) {// 获取匹配成功第10次的照片Imgcodecs.imwrite(PATH_PREFIX + "face.png", image);}}return image;}/*** OpenCV-4.7.0 图片人脸识别*/public static void face(String filename) {// 1 读取OpenCV自带的人脸识别特征XML文件// OpenCV 图像识别库一般位于 opencv\sources\data 下面
//        CascadeClassifier facebook=new CascadeClassifier("D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");// 2 读取测试图片String imgPath = PATH_PREFIX + filename;Mat image = Imgcodecs.imread(imgPath);if (image.empty()) {System.out.println("image 内容不存在!");return;}// 3 特征匹配MatOfRect face = new MatOfRect();faceDetector.detectMultiScale(image, face);// 4 匹配 Rect 矩阵 数组Rect[] rects = face.toArray();System.out.println("匹配到 " + rects.length + " 个人脸");// 5 为每张识别到的人脸画一个圈int i = 1;for (Rect rect : face.toArray()) {Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 255, 0), 3);imageCut(imgPath, PATH_PREFIX + i + ".jpg", rect.x, rect.y, rect.width, rect.height);// 进行图片裁剪i++;}// 6 展示图片HighGui.imshow("人脸识别", image);HighGui.waitKey(0);}/*** 裁剪人脸** @param imagePath* @param outFile* @param posX* @param posY* @param width* @param height*/public static void imageCut(String imagePath, String outFile, int posX, int posY, int width, int height) {// 原始图像Mat image = Imgcodecs.imread(imagePath);// 截取的区域:参数,坐标X,坐标Y,截图宽度,截图长度Rect rect = new Rect(posX, posY, width, height);// 两句效果一样Mat sub = image.submat(rect); // Mat sub = new Mat(image, rect);Mat mat = new Mat();Size size = new Size(width, height);Imgproc.resize(sub, mat, size);// 将人脸进行截图并保存Imgcodecs.imwrite(outFile, mat);System.out.println(String.format("图片裁切成功,裁切后图片文件为: %s", outFile));}/*** 人脸比对** @param img_1* @param img_2* @return*/public static double compare_image(String img_1, String img_2) {Mat mat_1 = conv_Mat(img_1);Mat mat_2 = conv_Mat(img_2);Mat hist_1 = new Mat();Mat hist_2 = new Mat();//颜色范围MatOfFloat ranges = new MatOfFloat(0f, 256f);//直方图大小, 越大匹配越精确 (越慢)MatOfInt histSize = new MatOfInt(1000);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;}/*** 灰度化人脸** @param img* @return*/public static Mat conv_Mat(String img) {Mat image0 = Imgcodecs.imread(img);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;}/*** OpenCV-4.7.0 将摄像头拍摄的视频写入本地*/public static void writeVideo() {//1 如果要从摄像头获取视频 则要在 VideoCapture 的构造方法写 0VideoCapture capture = new VideoCapture(0);Mat video = new Mat();int index = 0;Size size = new Size(capture.get(Videoio.CAP_PROP_FRAME_WIDTH), capture.get(Videoio.CAP_PROP_FRAME_HEIGHT));VideoWriter writer = new VideoWriter("D:/a.mp4", VideoWriter.fourcc('D', 'I', 'V', 'X'), 15.0, size, true);while (capture.isOpened()) {capture.read(video);//2 将摄像头的视频写入 Mat video 中writer.write(video);HighGui.imshow("像头获取视频", video);//3 显示图像index = HighGui.waitKey(100);//4 获取键盘输入if (index == 27) {//5 如果是 Esc 则退出capture.release();writer.release();return;}}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/155964.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp微信小程序自定义封装分段器。

uniapp微信小程序自定义封装分段器。 话不多说先上效果 这里我用的是cil框架 vue3 下面贴代码 组价代码&#xff1a; <template><view class"page"><viewv-for"(item, index) in navList":key"index"click"changeNav(ind…

C#和JS交互之Microsoft.ClearScript.V8(V8引擎)

之前测试了很多JS引擎&#xff0c;都只支持es5语法&#xff0c;不支持执行es6&#xff0c;测试了下微软的V8反正能跑通&#xff0c;应该是支持的。还得是微软呀。 如图&#xff1a;安装相关包&#xff1a; 这是参考的官方V8代码 using Microsoft.ClearScript.JavaScript; us…

UnrealEngine iOS 打包 —— 签名证书(cer、p12)生成

官方文档 docs.unrealengine.com/5.3/zh-CN/setting-up-ios-tvos-and-ipados-provisioning-profiles-and-signing-certificates-for-unreal-engine-projects 打开 ProjectSettings -> Platforms -> iOS 可以看到签名证书配置 需要拓展名为 .cer 和 .p12 的一对证书和密钥…

卫星/RedCap/高算力/解决方案/创新金奖……移远通信为IOTE 2023再添新活力

9月20日&#xff0c;IOTE 2023第二十届国际物联网展深圳场震撼来袭。 作为IOTE多年的“老朋友”&#xff0c;移远通信在参展当天&#xff0c;不仅有5G RedCap、卫星通信、高算力、车载等高性能产品及终端展出&#xff0c;还携智慧出行、智慧生活、智慧能源、工业互联网等多领域…

微信小程序底部tabBar不显示图标

现场还原 在设置微信小程序底部tabBar导航图标时&#xff0c;无论如何操作均无法显示在界面上 解决思路 问题1 图标类型 一开始以为不支持png类型&#xff0c;但查看官方API仅提示ICON尺寸大小 打开其他项目可以正常展示&#xff0c;排除图标类型问题 iconPath string 否 …

easy code 模板案例 (author作者 修改+swagger-ui+mybatis plus)

pojo ##引入宏定义 $!{define.vm} ##使用宏定义设置回调&#xff08;保存位置与文件后缀&#xff09; #save("/pojo", ".java") ##使用宏定义设置包后缀 #setPackageSuffix("pojo") ##使用全局变量实现默认包导入 $!{autoImport.vm} import ja…

基于全息感知的智慧高速IT设施监控运维方案

作为智能交通的重要细分领域&#xff0c;建设智慧高速是实施交通强国战略的重要基础。在信息化时代&#xff0c;交通行业已经依托信息化建设取得了显著的成果&#xff0c;其中以收费网络、办公网络、监控网络和通讯网络为基础的网络架构已经形成&#xff0c;并且正在逐步完善网…

【算法|滑动窗口No.1】leetcode209. 长度最小的子数组

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

Unity ToLua热更框架使用教程(1)

从本篇开始将为大家讲解ToLua在unity当中的使用教程。 Tolua的框架叫LuaFramework&#xff0c;首先附上下载链接&#xff1a; https://github.com/jarjin/LuaFramework_UGUI_V2 这个地址的是UGUI的。 下载完之后导入项目&#xff0c;首先&#xff0c;我们要先让这个项目跑起…

统一机器人描述格式——URDF

URDF&#xff08;Unified Robot Description Format&#xff0c;统一机器人描述格式&#xff09;是ROS中一个非常重要的机器人模型描述格式&#xff0c;ROS同时也提供URDF文件的C解析器&#xff0c;可以解析URDF文件中使用XML格式描述的机器人模型。 在使用URDF文件构建机器人模…

Centos8 openjdk升级

1、卸载旧版本 sudo dnf remove java-1.8.0-openjdk 2、搜索新版本 yum search java-11-openjdk3、安装新版本 dnf install java-11-openjdk.x86_644、验证新版本 java -version

光纤激光切割机如何高效的切割铜等高反材料

高反射材料的切割过程往往具有挑战性&#xff0c;对于许多光纤激光切割设备厂商而言都是难以解决的问题。但是作为铜、铝、金等常见的高反射性材料又需要在日常生产中经常进行加工处理。 很多厂家解决的办法之一就是采用相应的辅助气体。在光纤激光切割机切割铜时&#xff0c;辅…

【智慧燃气】智慧燃气解决方案总体概述--终端层、网络层

关键词&#xff1a;智慧燃气、智慧燃气系统、智慧燃气平台、智慧燃气解决方案、智慧燃气应用、智能燃气 智慧燃气解决方案是基于物联网、大数据、云计算、移动互联网等先进技术&#xff0c;结合燃气行业特征&#xff0c;通过智能设备全面感知企业生产、环境、状态等信息的全方…

【机器学习 | 回归问题】超越直线:释放多项式回归的潜力 —— 详解线性回归与非线性 (含详细案例、源码)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

【前端小技巧】如何使用 Eolink Apilkit 调用 Mock ?

在开发过程中&#xff0c;进度比较赶的情况下&#xff0c;前端人员当页面写完时&#xff0c;后台的接口还没写完&#xff0c;等要交付的时候后端才把接口给你&#xff0c;这个时候就很尴尬。 这个时候 Mock 就可以很好的解决这个问题&#xff0c;前端团队可以在 API 还没开发完…

SAP内部转移价格(利润中心转移价格)的条件

SAP内部转移价格&#xff08;利润中心转移价格&#xff09; SAP内部转移价格&#xff08;利润中心转移价格&#xff09; SAP内部转移价格&#xff08;利润中心转移价格&#xff09;这个听了很多人说过&#xff0c;但是利润中心转移定价需要具备什么条件。没有找到具体的文档。…

应用在自动跟随行李箱领域中的国产蓝牙芯片

自动行走行李箱&#xff0c;又名“蓝牙行李箱”&#xff0c;是一种全自动的机械化行李箱。将三个蓝牙信号感应装置安装在一个特制的行李箱里面&#xff0c;这些装置接收到智能手机发出的蓝牙信号后&#xff0c;可通过一个计算机微处理器控制安装在行李下方的履带移动。自动行走…

深度学习基础知识 学习率调度器的用法解析

深度学习基础知识 学习率调度器的用法解析 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR2、正儿八经的模型搭建流程以及学习率调度器的使用设置 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR 实验代码&#xff1a; i…

精益生产与MES生产管理系统相互融合

近年来&#xff0c;精益生产理念在企业管理中越来越受欢迎。它强调以最小的浪费&#xff0c;在最短的时间内&#xff0c;生产出高质量的产品。这一理念的实施手段包括准时制生产方式、适时生产方式等&#xff0c;消除浪费、看板、快换工装等都是精益提高的工具方针。 然而&…

公网环境下如何内网穿透读写本地群晖NAS文件?

File Station 是 群晖Synology NAS 的集中化文件管理工具。我们可以在局域网内登陆nas web界面通过 File Station管理群晖nas中的文件&#xff0c;如果我们在户外&#xff0c;有读写家中群晖nas中文件的需求怎么办&#xff1f; 本教程解决的问题是&#xff1a; 人在户外&#…