OPENCV+JAVA实现人脸识别
作者:OkidoGreen 发布时间:2022-03-15 18:31:39
标签:OPENCV,JAVA,人脸识别
本文实例为大家分享了JAVA实现人脸识别的具体代码,供大家参考,具体内容如下
官方下载 安装文件 ,以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(目录中有各类识别文件)
项目结构:
具体代码:由于需要用到 opencv 的dll文件,故要么放在java library path 中,或放在jre lib 中,windows下可放在System32目录下,也可以在代码中动态加载,如下:
package opencv;
import com.sun.scenario.effect.ImageData;
import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Vector;
/**
* Created by Administrator on 2017/8/17.
*/
public class Test {
static{
// 导入opencv的库
String opencvpath = System.getProperty("user.dir") + "\\opencv\\x64\\";
String libPath = System.getProperty("java.library.path");
String a = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
System.load(opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll");
}
public static String getCutPath(String filePath){
String[] splitPath = filePath.split("\\.");
return splitPath[0]+"Cut"+"."+splitPath[1];
}
public static void process(String original,String target) throws Exception {
String originalCut = getCutPath(original);
String targetCut = getCutPath(target);
if(detectFace(original,originalCut) && detectFace(target,targetCut)){
}
}
public static boolean detectFace(String imagePath,String outFile) throws Exception
{
System.out.println("\nRunning DetectFaceDemo");
// 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
CascadeClassifier faceDetector = new CascadeClassifier(
"C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml");
Mat image = Highgui.imread(imagePath);
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
System.out.println(String.format("Detected %s faces",
faceDetections.toArray().length));
Rect[] rects = faceDetections.toArray();
if(rects != null && rects.length > 1){
throw new RuntimeException("超过一个脸");
}
// 在每一个识别出来的人脸周围画出一个方框
Rect rect = rects[0];
Core.rectangle(image, new Point(rect.x-2, rect.y-2), new Point(rect.x
+ rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
Mat sub = image.submat(rect);
Mat mat = new Mat();
Size size = new Size(300, 300);
Imgproc.resize(sub, mat, size);//将人脸进行截图并保存
return Highgui.imwrite(outFile, mat);
// 将结果保存到文件
// String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\faceDetection.png";
// System.out.println(String.format("Writing %s", filename));
// Highgui.imwrite(filename, image);
}
public static void setAlpha(String imagePath,String outFile) {
/**
* 增加测试项
* 读取图片,绘制成半透明
*/
try {
ImageIcon imageIcon = new ImageIcon(imagePath);
BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(),imageIcon.getIconHeight()
, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
g2D.drawImage(imageIcon.getImage(), 0, 0,
imageIcon.getImageObserver());
//循环每一个像素点,改变像素点的Alpha值
int alpha = 100;
for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
int rgb = bufferedImage.getRGB(j2, j1);
rgb = ( (alpha + 1) << 24) | (rgb & 0x00ffffff);
bufferedImage.setRGB(j2, j1, rgb);
}
}
g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
//生成图片为PNG
ImageIO.write(bufferedImage, "png", new File(outFile));
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void watermark(String a,String b,String outFile, float alpha) throws IOException {
// 获取底图
BufferedImage buffImg = ImageIO.read(new File(a));
// 获取层图
BufferedImage waterImg = ImageIO.read(new File(b));
// 创建Graphics2D对象,用在底图对象上绘图
Graphics2D g2d = buffImg.createGraphics();
int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
int waterImgHeight = waterImg.getHeight();// 获取层图的高度
// 在图形和图像中实现混合和透明效果
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 绘制
g2d.drawImage(waterImg, 0, 0, waterImgWidth, waterImgHeight, null);
g2d.dispose();// 释放图形上下文使用的系统资源
//生成图片为PNG
ImageIO.write(buffImg, "png", new File(outFile));
}
public static boolean mergeSimple(BufferedImage image1, BufferedImage image2, int posw, int posh, File fileOutput) {
//合并两个图像
int w1 = image1.getWidth();
int h1 = image1.getHeight();
int w2 = image2.getWidth();
int h2 = image2.getHeight();
BufferedImage imageSaved = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = imageSaved.createGraphics();
// 增加下面代码使得背景透明
g2d.drawImage(image1, null, 0, 0);
image1 = g2d.getDeviceConfiguration().createCompatibleImage(w1, w2, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image1.createGraphics();
// 背景透明代码结束
// for (int i = 0; i < w2; i++) {
// for (int j = 0; j < h2; j++) {
// int rgb1 = image1.getRGB(i + posw, j + posh);
// int rgb2 = image2.getRGB(i, j);
//
// if (rgb1 != rgb2) {
// //rgb2 = rgb1 & rgb2;
// }
// imageSaved.setRGB(i + posw, j + posh, rgb2);
// }
// }
boolean b = false;
try {
b = ImageIO.write(imageSaved, "png", fileOutput);
} catch (IOException ie) {
ie.printStackTrace();
}
return b;
}
public static void main(String[] args) throws Exception {
String a,b,c,d;
a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzl.jpg";
d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgx.jpg";
//process(a,d);
a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzlCut.jpg";
d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgxCut.jpg";
CascadeClassifier faceDetector = new CascadeClassifier(
"C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml");
CascadeClassifier eyeDetector1 = new CascadeClassifier(
"C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye.xml");
CascadeClassifier eyeDetector2 = new CascadeClassifier(
"C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye_tree_eyeglasses.xml");
Mat image = Highgui.imread("C:\\Users\\Administrator\\Desktop\\opencv\\gakki.jpg");
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
//eyeDetector2.detectMultiScale(image, faceDetections);
Vector<Rect> objects;
eyeDetector1.detectMultiScale(image, faceDetections, 2.0,1,1,new Size(20,20),new Size(20,20));
Rect[] rects = faceDetections.toArray();
Rect eyea,eyeb;
eyea = rects[0];eyeb = rects[1];
System.out.println("a-中心坐标 " + eyea.x + " and " + eyea.y);
System.out.println("b-中心坐标 " + eyeb.x + " and " + eyeb.y);
//获取两个人眼的角度
double dy=(eyeb.y-eyea.y);
double dx=(eyeb.x-eyea.x);
double len=Math.sqrt(dx*dx+dy*dy);
System.out.println("dx is "+dx);
System.out.println("dy is "+dy);
System.out.println("len is "+len);
double angle=Math.atan2(Math.abs(dy),Math.abs(dx))*180.0/Math.PI;
System.out.println("angle is "+angle);
for(Rect rect:faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x
+ rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}
String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\ouput.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
// watermark(a,d,"C:\\Users\\Administrator\\Desktop\\opencv\\zzlTm2.jpg",0.7f);
//
// // 读取图像,不改变图像的原始信息
// Mat image1 = Highgui.imread(a);
// Mat image2 = Highgui.imread(d);
// Mat mat1 = new Mat();Mat mat2 = new Mat();
// Size size = new Size(300, 300);
// Imgproc.resize(image1, mat1, size);
// Imgproc.resize(image2, mat2, size);
// Mat mat3 = new Mat(size,CvType.CV_64F);
// //Core.addWeighted(mat1, 0.5, mat2, 1, 0, mat3);
//
// //Highgui.imwrite("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg", mat3);
//
// mergeSimple(ImageIO.read(new File(a)),
// ImageIO.read(new File(d)),0,0,
// new File("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg"));
}
}
最终效果:人脸旁有绿色边框,可以将绿色边框图片截取,生成人脸图
来源:http://blog.csdn.net/z69183787/article/details/77334829


猜你喜欢
- 一.BASIC认证概述在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,
- 一般我们在java中运行其它类中的方法时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个java虚拟机实例在运行
- 这篇文章主要介绍了SpringBoot跨域Access-Control-Allow-Origin实现解析,文中通过示例代码介绍的非常详细,对
- 前言在上篇文章讲到了如何配置单数据源,但是在实际场景中,会有需要配置多个数据源的场景,比如说,我们在支付系统中,单笔操作(包含查询、插入、新
- 您好,我是贾斯汀,欢迎又进来学习啦!【学习背景】学习Java的小伙伴,都知道想要提升个人技术水平,阅读JDK源码少不了,但是说实话还是有些难
- java使用HttpClient调用接口HttpClient 提供的主要的功能(1)实现了所有 HTTP 的方法(GET,POST,PUT,
- 复制文件并命名的超简洁写法没错又是我,这次为大家带来Java中 复制文件并命名的超简洁写法(请确保你的jre在1.8+),这次用到了File
- 前言介绍了几篇 Hero 动画,我们来一个 Hero 动画应用案例。在一些应用中,列表的元素和详情的
- 如下所示:import java.util.*;public class Main{public static void main(Stri
- 1、JavaBean介绍 * JavaBean的定义:JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)
- 栈的变化规则:1、方法调用会导致栈的生长,具体包括两个步骤:一、插入方法返回地址(下图中的Fn:);二、将实际参数按值(可以使用ref或ou
- 本文实例讲述了java取两个字符串的最大交集的实现方法,分享给大家供大家参考。具体实现方法如下:package com.itheima.ne
- 本文实例讲述了C#中异步回调函数用法。分享给大家供大家参考。具体如下:static void Main(string[] args){ Fu
- 今天跟大家分享一个实现PDF另存为的效果,是调用Acrobat SDK的JavaScript实现的。/// <summary>&
- switch语句的格式如下:(它的功能是选出一段代码执行) switch(整数选择因子) { case 整数值1 : 语句; break;
- 我就废话不多说了,大家还是直接看代码吧~/* *es配置类 * */@Configurationpublic class ElasticSe
- 简要介绍Retrofit是当前应用非常广泛的网络请求框架,通常结合RxJava来进行网络请求,本文将展示一个采用RxJava+Retrofi
- 一、系统启动后注入配置package com.example.config;import org.springframework.beans
- 混合开发简介使用Flutter从零开始开发App是一件轻松惬意的事情,但对于一些成熟的产品来说,完全摒弃原有App的历史沉淀,全面转向Flu
- Java中 * 主要有JDK和CGLIB两种方式。区别主要是jdk是代理接口,而cglib是代理类。优点:这种方式已经解决我们前面所有日记