首页 > 技术文章 > 记一次Java调用本地/百度度目 摄像头(基于OpenCV)

crow9527 2020-09-24 10:31 原文

OpenCV官网下载地址(下载安装后,在安装目录可以找到动态链接库和OpenCv.jar)

https://opencv.org/releases/

     

 

 

 

 安装完成后,这是我的安装目录

    

 

maven 依赖(这个是安装完成后我把jar放到maven本地仓库中,然后在maven中就可以直接引用了)

     <!-- opencv依赖 -->
        <dependency>
            <groupId>org.opencv</groupId>
            <artifactId>opencv</artifactId>
            <version>440</version>
        </dependency>

 

1.配置OpenCV环境

   新建本地依赖

 

 

 自己定义依赖库的名称

 

 

 

 

 

 

 

选择动态链接库dll文件的目录

 

 

选择OpenCV的安装目录

 

 

 这个是根据你的JDK来选择,如果你的JDK是64位的就选择x64

 

 

2.摄像头获取类


package com.crow.safeBoxHardware;

import java.awt.FlowLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
import lombok.extern.log4j.Log4j2;

@Log4j2
public class Test2 {

    // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
    private CascadeClassifier faceDetector;
private JFrame cameraFrame;

    public CamarePanel panelCamera;

    // 是否打开摄像头
    private boolean open = false;

    // 相机
    public VideoCapture capture;

    // 人脸图像
    public Mat faceMat;

    // 摄像头读取的帧
    public Mat capImg;

    public Test2() {
        // 初始化人脸检测器
//        faceDetector = new CascadeClassifier(
//                "C:\\worksplace\\safeBoxHardware\\src\\main\\resources\\native\\face\\xml\\haarcascade_frontalface_alt.xml");
        capture = new VideoCapture();
    }

    /**
     * 打开摄像头
     * 
     * @param x
     * @param y
     */
    public void open(int x, int y) {

        capImg = new Mat();

        faceMat = new Mat();

        cameraFrame = new JFrame("camare");

        panelCamera = new CamarePanel();

        // 打开相机
        capture.open(0);

        boolean grab = capture.grab();

        if (!grab) {
            throw new BizException(BizErrorCode.CAMARE_OPEN_ERROE);
        }

        // 打开摄像头
        open = true;

     
        capture.set(Videoio.CAP_PROP_FRAME_WIDTH, 1280);
        capture.set(Videoio.CAP_PROP_FRAME_HEIGHT, 720);
        capture.set(Videoio.CAP_PROP_FPS, 30);

        // 添加到Frame
        cameraFrame.setContentPane(panelCamera);

        // 设置去掉边框
        cameraFrame.setUndecorated(true);

        // 是否显示窗口
        cameraFrame.setVisible(true);

        // 设置在最顶层
        cameraFrame.setAlwaysOnTop(true);

        // 设置关闭
        cameraFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        // 窗口关闭事件
        cameraFrame.addWindowListener(new WindowListener() {

            @Override
            public void windowOpened(WindowEvent e) {

            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowDeactivated(WindowEvent e) {

            }

            @Override
            public void windowClosing(WindowEvent e) {
                close();
            }

            @Override
            public void windowClosed(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {

            }
        });

        // 设置位置
        if (x > 0 && y > 0) {
            cameraFrame.setBounds(x, y, 400, 600);
        } else {
            // 设置大小
            cameraFrame.setSize(400, 600);
            // 居中显示
            cameraFrame.setLocationRelativeTo(null);
        }

        while (open) {
            capture.read(capImg);
            if (!capImg.empty()) {
                // 转换成BufferImage并绘制到Panel
                panelCamera.setImageWithMat(capImg);
                // 重新绘制
                cameraFrame.repaint();
                
                //检测人脸并保存
                //detectFace(capImg, "C:\\Users\\Crow\\Desktop\\"+System.currentTimeMillis()+".png");
            }
        }
        log.info("相机已关闭......");
    }

    /**
     * 关闭窗口和摄像头释放资源
     */
    public void close() {
        // 关闭循环
        open = false;

        if (cameraFrame != null) {
            // 关闭窗口
            cameraFrame.dispose();
            cameraFrame = null;
        }

        if (panelCamera != null) {
            // 清空
            panelCamera = null;
        }

        if (capture != null && capture.isOpened()) {
            // 关闭视频文件或捕获设备,并释放资源
            capture.release();
        }

        log.warn("关闭相机...........................");
    }

    /**
     * 检测人脸,并保存
     * 
     * @param videoMat
     * @param savePath
     * @return
     */
    public Mat detectFace(Mat videoMat, String savePath) {

        File file = new File(savePath);

        // 验证父目录是否存在,不存在则新建
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        // 创建用来装检测出来的人脸的容器
        MatOfRect faces = new MatOfRect();
        // 检测人脸,videoMat为要检测的图片,faces用来存放检测结果
        faceDetector.detectMultiScale(videoMat, faces);
        Rect[] facesArray = faces.toArray();
if (facesArray.length > 0) {
            for (int i = 0; i < facesArray.length; i++) {
                Rect rect = facesArray[i];
                // 只获取人脸行和人脸列
                Mat faceImage = videoMat.rowRange(rect.y, rect.y + rect.height).colRange(rect.x, rect.x + rect.width);

                // 设置大小
                Size size = new Size(400, 600);
                // 调整图像
                Imgproc.resize(faceImage, faceMat, size);
                // 保存
                Imgcodecs.imwrite(savePath, faceMat);
            }
        }
        return faceMat;
    }

    public boolean isOpen() {
        return open;
    }

    public void setOpen(boolean open) {
        this.open = open;
    }

    public CamarePanel getPanelCamera() {
        return panelCamera;
    }

    public Mat getFaceMat() {
        return faceMat;
    }

    public static void main(String[] args) {
        //加载opencv动态链接库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //打开摄像头,并设置位置
        new Test2().open(298, 81);
    }

}

3.图像显示Panel容器

package com.crow.safeBoxHardware.components.hardware.camare;

import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import org.opencv.core.Mat;
import org.opencv.highgui.HighGui;
/** * <p> * 用于在面板上显示和拍摄 * </p> * * @author Crow * @version 0.0.1 * @since 2020-9-158:54:36 */ public class CamarePanel extends JPanel { private static final long serialVersionUID = 1L; //摄像头获取的原始图像 private BufferedImage image; //裁剪修正后的图像 private BufferedImage updateImage; public CamarePanel() { super(); } private BufferedImage getimage() { return image; } /** * 裁剪修正后的图像 * @return */ public BufferedImage getUpdateImage() { return updateImage; } public void setUpdateImage(BufferedImage updateImage) { this.updateImage = updateImage; } public void setImage(BufferedImage newimage) { image = newimage; return; } public void setImageWithMat(Mat newimage) {
      // 将Mat转换成BufferedImage
      image = (BufferedImage) HighGui.toBufferedImage(newimage);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
if (image!= null) {

        // 裁剪
        updateImage = image.getSubimage(450, 0, 400, 600);
        // 绘制
        g.drawImage(updateImage, 0, 0, 400, 600, this);

        }
    }
}

 

摄像头像素较差(百度的度目摄像头)
效果图(本人就不上镜了)

 

  OK,搞定

 

推荐阅读