我是靠谱客的博主 洁净鸭子,最近开发中收集的这篇文章主要介绍毕业设计开发_01:人脸识别截取人像基于javaCV的人脸识别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

毕业设计开发_01:人脸识别截取人像

  • 基于javaCV的人脸识别
    • OpenCVFrameGrabber中的Frame与Mat的关联
    • haarcascade_frontalface_alt.xml配置文件
    • 使用OpenCVFrameGrabber获取摄像头并进行拍照
    • 从获取的图片中提取人脸信息并截取

基于javaCV的人脸识别

JavaCV是一款基于JavaCPP调用方式(JNI的一层封装),由多种开源计算机视觉库组成的包装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。

OpenCVFrameGrabber中的Frame与Mat的关联

在图像获取的实现中,我们采用OpenCVFrameGrabber读取设备、媒体文件及流,OpenCVFrameGrabber其实内部封装了opencv的VideoCapture操作,支持设备、视频文件、图片文件和流媒体地址(rsprtmp等)。可以通过ImageMode设置色彩模式,支持lmageMode.COLOR(色彩图)和lmageMode.GRAY(灰度图)

ps: opencv并不支持音频读取和录制等操作,只支持视频文件、视频流媒体、图像采集设备的画面抓取。另外需要注意的是,读取非动态图片,只能读取一帧。

通过OpenCVFrameRecorder的grab()抓取到的图像是Frame,其实javaCV内部通过OpenCVFrameConverter把opencv的Mat转换为了Frame,也即是说,Frame中可以直接获取Mat或者也可以通过OpenCVFrameConverter实现Mat和Frame的互转。

haarcascade_frontalface_alt.xml配置文件

haarcascade_frontalface_alt.xml为人脸识别配置包,最好应放在项目包中,在项目中可以使用相对地址,防止项目迁移时路径出错。

使用OpenCVFrameGrabber获取摄像头并进行拍照

创建CameraUtil类封装拍照动作,并保存为指定文件具体代码设计如下:

package FaceDetect;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.javacv.OpenCVFrameGrabber;
import org.bytedeco.opencv.opencv_core.IplImage;

public class CameraUtil{
    private static CamerThread camerThread = null ;
    public static void main(String[] args) throws Exception, InterruptedException{
        String name = "czl";
        Camera("D:\ideaProject\img\"+name+".jpg", 700, 700);
    }

    // 身份证照片上传api
    public static void upIdentityCard(String name){
        Camera("D:\ideaProject\img\"+name+".jpg", 700, 700);
    }
    /*
     *  outFile 存储地址  列如 E:\test\2.jpg
     *  width   height 窗口大小  自己设置一下
     */
    public static void Camera(String outFile,int width ,int height) {
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
        grabber.setImageWidth(width);
        grabber.setImageHeight(height);
        CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口
        canvas.setAlwaysOnTop(true);
        canvas.setLayout(null);
        Font font= new Font("微软雅黑", Font.BOLD, 30);
        JButton jButton = new JButton("确认上传");
        JButton jButton1 = new JButton("继续拍照");
        jButton1.setEnabled(false);
        JButton jButton2 = new JButton("关闭");
        jButton.setFont(font);
        jButton1.setFont(font);
        jButton2.setFont(font);
        jButton.setBounds(30, 550, 200, 100);
        jButton1.setBounds(260, 550, 200, 100);
        jButton2.setBounds(480, 550,200, 100);
        canvas.add(jButton);
        canvas.add(jButton1);
        canvas.add(jButton2);
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(camerThread!=null) {
                    camerThread.terminate();
                }
                jButton1.setEnabled(true);
            }
        });
        jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jButton1.setEnabled(false);
                camerThread = new CamerThread(height, height, canvas, grabber, outFile);
                camerThread.start();
            }
        });
        jButton2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                camerThread.terminate();
                //System.exit(0);//退出
                canvas.dispose();
            }
        });
        camerThread = new CamerThread(height, height, canvas, grabber, outFile);
        camerThread.start();
    }

    public static void doExecuteFrame(Frame f, String targetFileName) {
        if (null ==f ||null ==f.image) {
            return;
        }
        Java2DFrameConverter converter =new Java2DFrameConverter();
        targetFileName=targetFileName.replace("mp4", "jpg");
        System.out.println("targetFileName"+targetFileName);
        String imageMat ="jpg";
        String FileName =targetFileName;
        BufferedImage bi =converter.getBufferedImage(f);
        File output =new File(FileName);
        try {
            ImageIO.write(bi,imageMat,output);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class CamerThread extends Thread{
// 此变量必须加上volatile
    private volatile boolean stop = true;
    private int width;
    private int height;
    private CanvasFrame canvas;
    private OpenCVFrameGrabber grabber;
    private String  outFile;

    public CamerThread(int width, int height, CanvasFrame canvas, OpenCVFrameGrabber grabber, String outFile) {
        super();
        this.width = width;
        this.height = height;
        this.canvas = canvas;
        this.grabber = grabber;
        this.outFile = outFile;
    }


    @Override
    public void run() {
        int i=0;
        try {
            grabber.start();   //开始获取摄像头数据
            while(stop){
                if(i<2) {
                    canvas.setSize(width, height);
                    i++;
                }
                canvas.showImage(grabber.grab());
                Thread.sleep(50);//50毫秒刷新一次图像
//获取摄像头图像并放到窗口上显示, 这里的Frame frame=grabber.grab(); frame是一帧视频图像
            }
            OpenCVFrameConverter.ToIplImage converter =new OpenCVFrameConverter.ToIplImage();
            IplImage src = null;
            Frame capturedFrame = null;
            capturedFrame= grabber.grab();
            src =converter.convert(capturedFrame);
            capturedFrame =converter.convert(src);
            CameraUtil.doExecuteFrame(grabber.grab(),outFile);
            grabber.stop();//停止抓取
        } catch (org.bytedeco.javacv.FrameGrabber.Exception | InterruptedException e) {
            e.printStackTrace();
        }
    }

// 线程终止
    public void terminate() {
        stop = false;
    }
}

从获取的图片中提取人脸信息并截取

设计了FaceFromGraph类实现该操作,首先由CascadeClassifier获取haarcascade_frontalface_alt.xml来读取opencv人脸检测器,再经过类型转换、存放灰度图、均衡化直方图、人脸检测等操作获取到人脸信息。
再设计imageCut类来实现从图片中截取人脸信息,需传递图片路径、人脸方位和人脸长宽等信息,完成裁剪后通过ImageIO.write操作进行写入。具体代码设计如下

package FaceDetect;

import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;

import static org.bytedeco.opencv.global.opencv_imgproc.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;

import static org.bytedeco.opencv.global.opencv_imgproc.*;

/**
 * @Classname FaceDetect.FaceFromGraph
 * @Description TODO
 * @Author Shawn Yue
 * @Date 16:39
 * @Version 1.0
 **/
public class FaceFromGraph {
    public static void main(String[] args) throws IOException {
        faceDetection("D:\ideaProject\img\czl.jpg");
    }

    /**
     * 人脸检测
     *
     * @param filePath 图片路径
     */
    public static void faceDetection(String filePath) throws IOException {
        // 读取opencv人脸检测器
        CascadeClassifier cascade = new CascadeClassifier("D:\ideaProject\OpenCVTest\haarcascade_frontalface_alt.xml");
        File file=new File(filePath);
        BufferedImage image = ImageIO.read(file);
        Java2DFrameConverter imageConverter = new Java2DFrameConverter();
        Frame frame = imageConverter.convert(image);
        //类型转换
        OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
        Mat original = converter.convertToMat(frame);
        //存放灰度图
        Mat grayImg = new Mat();
        //模式设置成ImageMode.Gray下不需要再做灰度 摄像头获取的是彩色图像,所以先灰度化下
        cvtColor(original, grayImg, COLOR_BGRA2GRAY);
        // 均衡化直方图
        equalizeHist(grayImg, grayImg);
        // 检测到的人脸
        RectVector faces = new RectVector();
        //多人脸检测
        cascade.detectMultiScale(grayImg, faces);

        System.out.println(faces.size());
        if(faces.size() > 2){
            System.out.println("超过一个脸");
            return ;
        }
        // 在每一个识别出来的人脸周围画出一个方框
        Rect rect = faces.get(0);
        //上y和下y为总高度的百分之15
        imageCut(filePath,
                rect.x()-2,
                (int)(rect.y()-rect.height()*0.15),
                rect.width(),
                (int)(rect.height()+rect.height()*0.15));
        System.out.println("人脸截取成功");
        return ;

    }

    /**
     * 裁剪图片并重新装换大小
     * @param imagePath
     * @param posX
     * @param posY
     * @param width
     * @param height
     */
    public static void imageCut(String imagePath,int posX, int posY, int width, int height) throws IOException {
        File file = new File(imagePath);
        BufferedImage image = ImageIO.read(file);
        BufferedImage dst = new BufferedImage(width, height, 1);
        Graphics2D g = dst.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
        g.drawImage(image, 0, 0, width, height, posX, posY, posX+width, posY+height, null);
        g.dispose();

        //获取原图片的名称
        String n1 = imagePath.substring(0, imagePath.lastIndexOf("."));
        //获取原图片的扩展名
        String n2 = imagePath.substring(imagePath.lastIndexOf("."));
        //获取裁剪后的图片名称
        String nn = n1 + "_re" + n2;
        //保存
        ImageIO.write(dst, imagePath.substring(imagePath.lastIndexOf(".") + 1), new File(nn));
    }
}

最后

以上就是洁净鸭子为你收集整理的毕业设计开发_01:人脸识别截取人像基于javaCV的人脸识别的全部内容,希望文章能够帮你解决毕业设计开发_01:人脸识别截取人像基于javaCV的人脸识别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部