记一次Java调用 本地/百度度目 摄像头(基于OpenCV)

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;

/**
 * <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) {
        image = this.ConvertImage(newimage);
        return;
    }

    /*
     * 将对象转换为BufferedImage,以在帧内显示它
     */
    public BufferedImage ConvertImage(Mat matrix) {
        // 列和缓冲区图像对象的对象大小
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int) matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        // 在颜色空间中显示对象的通道数。
        switch (matrix.channels()) {
        // 单通道使用灰色矩阵
        case 1:
            type = BufferedImage.TYPE_BYTE_GRAY;
            break;
        // 如果有3个通道
        case 3:
            type = BufferedImage.TYPE_3BYTE_BGR;
            /*
             * 由于 opencv 将 rgb 颜色空间保留为 bgr, 因此我们将它转换为 rgb 空间, 在成像中实现整洁的图像
             */
            byte b;
            for (int i = 0; i < data.length; i = i + 3) {
                b = data[i];
                data[i] = data[i + 2];
                data[i + 2] = b;
            }
            break;
        default:
            return null;
        }
        BufferedImage bufferedImage = new BufferedImage(cols, rows, type);
        bufferedImage.getRaster().setDataElements(0, 0, cols, rows, data);
        return bufferedImage;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        BufferedImage temp = getimage();

        if (temp != null) {
           	// 裁剪
			updateImage = temp.getSubimage(450, 0, 400, 600);
			// 绘制
			g.drawImage(updateImage, 0, 0, 400, 600, this);
        }
    }
}

复制代码

 

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

 

  OK,搞定

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crow_9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值