Java实现人脸检测

安装比较简单,一直下一步即可。但记得修改安装路径。

3、openCV重要目录


安装好opencv之后,有build以及source目录。

build目录如下。有对应支持的语言的dll库和引用包。

sources\data目录下,存放着为opencv实现的各种分类器。我们需要使用的人脸和人眼检测的分类器都在里面。如果想详细了解的话可以在opencv的官网里进行查看。

三、工程搭建


人脸识别项目已经上传github,大家可以进行下载导入,下载地址为https://github.com/379685397/FaceDetect。可以的话,帮忙加个星啊亲~。哈哈

1、工程目录


config目录存放的为opencv的分类器。此处使用了正面人脸以及人眼的分类器。

func为实现人脸相关接口

image存放的为测试用图片

tmp为测试使用输出图片。

lib里包含opencv的使用jar包和本地dll库。

工程导入完成之后,需要配置对应的jar包以及修改JDK。

IDEA的话通过file->Project Structure进行设置。选中加号,选择外部jar包引用。选择工程里lib目录下的openCV343.jar。

之后重新编译。看是否报错。没有报错的话项目导入成功

2、代码实现


1、DetectFace

package com.facedetect.func;

import org.opencv.core.*;

import org.opencv.imgcodecs.Imgcodecs;

import org.opencv.imgproc.Imgproc;

import org.opencv.objdetect.CascadeClassifier;

/**

  • @Auther: DarkKing

  • @Date: 2019/10/2 11:06

  • @Description:

*/

public class DetectFace {

//定义程序的基础路径

private String basePath =System.getProperty(“user.dir”);

//人眼识别分类器路径

private String eyeConfigPath=basePath+“\src\com\facedetect\config\haarcascade_eye_tree_eyeglasses.xml”;

//人脸识别分类器路径

private String faceConfigPath=basePath+“\src\com\facedetect\config\haarcascade_frontalface_alt2.xml”;

static{

// 载入opencv的库

String opencvpath = System.getProperty(“user.dir”) + “\libs\x64\”;

String opencvDllName = opencvpath + Core.NATIVE_LIBRARY_NAME + “.dll”;

System.load(opencvDllName);

}

/**

  • opencv实现人脸识别

  • @param imagePath

  • @param outFile

  • @throws Exception

*/

public void detectFace(String imagePath, String outFile) throws Exception

{

System.out.println("Running DetectFace …,config path is "+faceConfigPath);

String basePath =System.getProperty(“user.dir”);

String path= basePath+ “\src\com\facedetect\tmp\”;

// 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中,为了方便从安装方便放到了程序路径里

CascadeClassifier faceDetector = new CascadeClassifier(faceConfigPath);

//创建图片处理对象

Mat image = Imgcodecs.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();

// 在每一个识别出来的人脸周围画出一个方框

for (int i = 0; i < rects.length; i++) {

Rect rect = rects[i];

Imgproc.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 copy = new Mat(image,rect);

Mat temp = new Mat();

copy.copyTo(temp);

//输出图片

Imgcodecs.imwrite(path+i+“.png”, temp);

}

Imgcodecs.imwrite(outFile, image);

System.out.println(String.format(“人脸识别成功,人脸图片文件为: %s”, outFile));

}

/**

  • opencv实现人眼识别

  • @param imagePath

  • @param outFile

  • @throws Exception

*/

public void detectEye(String imagePath, String outFile) throws Exception {

System.out.println("Running DetectFace …,config path is "+eyeConfigPath);

CascadeClassifier eyeDetector = new CascadeClassifier(

eyeConfigPath);

Mat image = Imgcodecs.imread(imagePath); //读取图片

// 在图片中检测人脸

MatOfRect faceDetections = new MatOfRect();

eyeDetector.detectMultiScale(image, faceDetections, 2.0,1,1,new Size(20,20),new Size(20,20));

System.out.println(String.format(“Detected %s eyes”, faceDetections.toArray().length));

Rect[] rects = faceDetections.toArray();

if(rects != null && rects.length <2){

throw new RuntimeException(“不是一双眼睛”);

}

Rect eyea = rects[0];

Rect 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(dxdx+dydy);

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()) {

Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x

  • rect.width, rect.y + rect.height), new Scalar(0, 255, 0));

}

Imgcodecs.imwrite(outFile, image);

System.out.println(String.format(“人眼识别成功,人眼图片文件为: %s”, outFile));

}

}

该函数主要实现了两个方法,一个是人脸检测,一个是人眼检测。方法都差不多。主要是加载的分类器不同。以及结果集的过滤。其中重要的一个方法时是MatOfRect的detectMultiScale方法。该方法共有7个参数。含义如下。

  • **参数1:**image–待检测图片,一般为灰度图像加快检测速度;

  • **参数2:**objects–被检测物体的矩形框向量组;

  • **参数3:**scaleFactor–表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;

  • **参数4:**minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。        如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。       如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,        这种设定值一般用在用户自定义对检测结果的组合程序上;

  • **参数5:**flags–要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为          CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,       因此这些区    域通常不会是人脸所在区域;

  • **参数6、7:**minSize和maxSize用来限制得到的目标区域的范围。

2、ImageUtils

package com.facedetect.func;

import org.opencv.core.Mat;

import org.opencv.core.Rect;

import org.opencv.core.Size;

import org.opencv.imgcodecs.Imgcodecs;

import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;

import javax.swing.*;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

/**

  • @Auther: DarkKing

  • @Date: 2019/10/2 11:12

  • @Description:

*/

public class ImageUtils {

/**

  • 裁剪图片并重新装换大小

  • @param imagePath

  • @param posX

  • @param posY

  • @param width

  • @param height

  • @param outFile

*/

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(300, 300);

Imgproc.resize(sub, mat, size);//将人脸进行截图并保存

Imgcodecs.imwrite(outFile, mat);

System.out.println(String.format(“图片裁切成功,裁切后图片文件为: %s”, outFile));

}

/**

  • @param imagePath

  • @param outFile

*/

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));

System.out.println(String.format(“绘制图片半透明成功,图片文件为: %s”, outFile));

}

catch (Exception e) {

e.printStackTrace();

}

}

/**

  • 为图像添加水印

  • @param buffImgFile 底图

  • @param waterImgFile 水印

  • @param outFile 输出图片

  • @param alpha 透明度

  • @throws IOException

*/

private static void watermark(String buffImgFile,String waterImgFile,String outFile, float alpha) throws IOException {

// 获取底图

BufferedImage buffImg = ImageIO.read(new File(buffImgFile));

// 获取层图

BufferedImage waterImg = ImageIO.read(new File(waterImgFile));

// 创建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));

System.out.println(String.format(“图片添加水印成功,图片文件为: %s”, outFile));

}

/**

  • 图片合成

  • @param image1

  • @param image2

  • @param posw

  • @param posh

  • @param outFile

  • @return

*/

public static void simpleMerge(String image1, String image2, int posw, int posh, String outFile) throws IOException{

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
int posw, int posh, String outFile) throws IOException{

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-CADx0IWO-1715732876837)]

[外链图片转存中…(img-8dWNBioH-1715732876838)]

[外链图片转存中…(img-plvdngmm-1715732876838)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java实现人脸识别,可以使用Face++提供的API来实现。首先,你需要注册一个Face++的账号并创建API Key和API Secret。然后,你可以使用Postman等工具来调用Face++的API接口。 在人脸识别中,你可以使用人脸检测API来检测图片中的人脸。通过调用人脸检测API,你可以获取到人脸的位置和特征标识(face_token)。人脸特征标识是系统为每个人脸分配的唯一标识。 接下来,你可以使用人脸对比API来比较两个人脸的相似度。你需要提供两个人脸的特征标识(face_token)作为参数进行对比。 如果你想进行人脸搜索,即在已知身份用户的人脸集合中搜索新的人脸属于哪个已知身份用户,你可以调用人脸搜索API。你需要提供一个人脸库(FaceSet)来存储已知身份用户的人脸信息,并在调用人脸搜索API时指定该人脸库。 在Java代码中,你可以使用HTTP请求库来发送HTTP请求,并将API的URL、请求方法、请求体等信息设置好。然后,你可以解析API的响应结果来获取人脸识别的结果。 总结起来,要在Java实现人脸识别,你需要注册Face++账号,创建API Key和API Secret,使用API调用人脸检测人脸对比和人脸搜索等功能,并在Java代码中发送HTTP请求并解析响应结果。 #### 引用[.reference_title] - *1* *3* [人脸识别-Java实现刷脸登录](https://blog.csdn.net/qq_54227907/article/details/124785956)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [通过调用face++接口实现人脸识别(Java)](https://blog.csdn.net/weixin_43890515/article/details/110789552)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值