• @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{

// 获取底图

BufferedImage buffImg1 = ImageIO.read(new File(image1));

// 获取层图

BufferedImage buffImg2 = ImageIO.read(new File(image2));

//合并两个图像

int w1 = buffImg1.getWidth();

int h1 = buffImg1.getHeight();

int w2 = buffImg2.getWidth();

int h2 = buffImg2.getHeight();

BufferedImage imageSaved = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_ARGB); //创建一个新的内存图像

Graphics2D g2d = imageSaved.createGraphics();

g2d.drawImage(buffImg1, null, 0, 0); //绘制背景图像

for (int i = 0; i < w2; i++) {

for (int j = 0; j < h2; j++) {

int rgb1 = buffImg1.getRGB(i + posw, j + posh);

int rgb2 = buffImg2.getRGB(i, j);

/*if (rgb1 != rgb2) {

rgb2 = rgb1 & rgb2;

}*/

imageSaved.setRGB(i + posw, j + posh, rgb2); //修改像素值

}

}

ImageIO.write(imageSaved, “png”, new File(outFile));

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

}

}

改类为文件处理类。

3、DetectFaceTest 测试类


package com.facedetect;

import java.awt.AlphaComposite;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.ImageIcon;

import com.facedetect.func.DetectFace;

import com.facedetect.func.ImageUtils;

import com.sun.imag

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】浏览器打开:qq.cn.hn/FTf 免费领取

eio.plugins.common.ImageUtil;

import org.opencv.core.Core;

import org.opencv.core.Mat;

import org.opencv.core.MatOfRect;

import org.opencv.core.Point;

import org.opencv.core.Rect;

import org.opencv.core.Scalar;

Java实现人脸检测,java线程教程相关推荐

  1. Java实现人脸检测

    一.前言 之前上传了一个资源,就是Java实现人脸检测,发现很多人都不会用,就是这个https://download.csdn.net/download/b379685397/10023135.各种乱 ...

  2. Java版人脸检测详解下篇:开发java应用并做成docker镜像

    本篇概览 如果您看过<Java版人脸检测上篇>一文,甚至动手实际操作过,那么你应该会对背后的技术细节感兴趣,开发这样一个应用,咱们总共要做以下三件事: 1.准备好docker基础镜像 2. ...

  3. Java版人脸检测详解上篇:运行环境的Docker镜像(CentOS+JDK+OpenCV)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 如果您看过<三分钟极速体验:Java版 ...

  4. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 如果您看过<三分钟极速体验:Java版 ...

  5. 三分钟极速体验:Java版人脸检测

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 检测照片中的人脸,用Java可以实现吗? 当 ...

  6. cvpr2020 人脸检测与识别_Python人脸检测识别实例教程

    前言 随着科技的发展,人脸识别技术在许多领域得到的非常广泛的应用,手机支付.银行身份验证.手机人脸解锁等等. 识别 废话少说,这里我们使用 opencv 中自带了 haar人脸特征分类器,利用训练好的 ...

  7. python视频人脸识别教程_Python学习笔记之视频人脸检测识别实例教程

    前言 上一篇博文与大家分享了简单的图片人脸识别技术,其实在实际应用中,很多是通过视频流的方式进行识别,比如人脸识别通道门禁考勤系统.人脸动态跟踪识别系统等等. 下面话不多说了,来一起看看详细的介绍吧 ...

  8. 25 行 Python 代码实现人脸检测——OpenCV 技术教程

    安装 OpenCV 首选,你需要找到对应你的操作系统的正确设置文件. 我发现,安装 OpenCV 是最难的一个环节.如果你遇到奇怪的.无法解释的错误,有可能是库崩溃了.32 与 64 比特的兼容问题等 ...

  9. java 整数溢出检测,Java如何处理整数下溢和溢出以及如何检查它?

    How does Java handle integer underflows and overflows? Leading on from that, how would you check/tes ...

最新文章

  1. html轮播图鼠标可以暂停,为什么better scroll轮播鼠标点击就会暂停?
  2. selenium 在centos中的配置
  3. pythontuple数据类型_Python数据类型之元组的详细介绍
  4. android中关于手机屏幕的相关操作(获取屏幕的宽高等操作)
  5. sql:数据操作语言dml
  6. Mysql数据库的读写分离
  7. ubuntu16 kickstart pxe 安装系统
  8. python URLError,HTTPError 的异常处理
  9. 数组的定义、作为方法参数传递、作为方法的返回值
  10. 编程坑太多,Map 集合怎么也有这么多坑?一不小心又踩了好几个!
  11. windows10-seaslog安装笔记
  12. 软件(敏捷)开发中工作量与工时评估模型
  13. matlab显示数据类型,MATLAB查看数据类型
  14. c语言公开课教案,9、祝福优质课一等奖教案
  15. java实现爬虫,爬取网易歌单信息
  16. 基于JAVA个人交友网站计算机毕业设计源码+系统+mysql数据库+lw文档+部署mp4
  17. 企业抖音蓝V怎么认证?申请流程是怎样的?需要具备哪些条件?
  18. poe交换机归类有什么?
  19. 如何修理无线网络电视服务器,win7实现无线投屏到电视_网站服务器运行维护
  20. java/php/net/python电影影评网站设计

热门文章

  1. 什么是 ROC AUC
  2. Oracle报错:ORA-01756: quoted string not properly terminated解决
  3. 【蓝桥杯真题】幸运数字的解决方法
  4. 电脑任务栏同时显示网速与CPU和内存的占用。
  5. springcloud微服务实现增删改查
  6. 暴风php视频怎么打开,点播PHP SDK-暴风云视频
  7. 基于shell,python 简易数据采集流程图
  8. day10 负载均衡反向代理
  9. 服务器双电源自动切换,服务器到底用双电源还是单电源?
  10. 2667: [cqoi2012]模拟工厂