记一次Java获取本地摄像头(基于OpenCV)
OpenCV官网下载地址(下载安装后,在安装目录可以找到动态链接库和OpenCv.jar)
安装完成后,这是我的安装目录
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 org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component; import com.crow.safeBoxHardware.components.exception.BizErrorCode;
import com.crow.safeBoxHardware.components.exception.BizException;
import com.crow.safeBoxHardware.util.FileUtil; import lombok.extern.log4j.Log4j2; @Log4j2
@Component
public class Test2 { // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
private CascadeClassifier faceDetector; // 从配置文件lbpcascade_frontalface.xml中创建一个人眼识别器,该文件位于opencv安装目录中
private CascadeClassifier eyeDetector; 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");
//
// eyeDetector = new CascadeClassifier(
// "C:\\worksplace\\safeBoxHardware\\src\\main\\resources\\native\\face\\xml\\haarcascade_eye.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(); // 创建用来装检测出来的人眼的容器
MatOfRect eyes = new MatOfRect();
// 检测人眼,videoMat为要检测的图片,faces用来存放检测结果
eyeDetector.detectMultiScale(videoMat, eyes);
Rect[] eyesArray = eyes.toArray(); if (facesArray.length > 0 && eyesArray.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) {
// 缩放
Image scaledInstance = temp.getScaledInstance(1000, 600, Image.SCALE_SMOOTH);
// 转换
updateImage = toBufferedImage(scaledInstance);
// 裁剪
updateImage = updateImage.getSubimage(300, 0, 400, 600);
// 绘制
g.drawImage(updateImage, 0, 0, 400, 600, this); //g.drawImage(temp, 0, 0, 1280, 720, this);
}
} /**
* 将image对象 转成 BufferedImage
*
* @param image
* @return
*/
private BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
image = new ImageIcon(image).getImage();
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
int transparency = Transparency.OPAQUE;
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
} catch (HeadlessException e) { } if (bimage == null) {
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
Graphics g = bimage.createGraphics(); g.drawImage(image, 0, 0, null);
g.dispose(); return bimage; } }
摄像头像素较差(百度的度目摄像头)
效果图(本人就不上镜了)
OK,搞定
记一次Java获取本地摄像头(基于OpenCV)的更多相关文章
- java获取本地计算机MAC地址
java获取本地计算机MAC地址代码如下: public class SocketMac { //将读取的计算机MAC地址字节转化为字符串 public static String transByte ...
- Java获取本地IP地址
import java.net.InetAddress; import java.net.UnknownHostException; public class IpTest { public stat ...
- directshow 获取本地摄像头播放
最近因为项目的需要,做了一个基本的获取本地笔记本摄像头并且播放的例子,因为网上的关于这部分的完整例子基本都没有,那我就上传一个吧,希望能够帮到需要学习视频的朋友. 另外也是为了纪念雷霄骅博士为音视频方 ...
- java 获取本地 mac 地址
主要参考:Java获取本机MAC地址/IP地址/主机名 做的更改: 1.我的windows是中文版,程序中获取mac时是按照physical address 获取的,添加上"物理地址&quo ...
- Java获取本地IP地址和主机名
方式一:通过java.net.InetAddress类获取 public void test1() { try { InetAddress addr = InetAddress.getLocalHos ...
- java获取本地json格式的内容
前言 该功能模块基于springBoot,自己在开发中遇到相关功能开发,总结如写: 1.首先将所需要获取的json文件放在项目resource目录下: 2.所需要的pom依赖: <depende ...
- java 获取本地电脑的分辨率代码
1.代码: java.awt.Toolkit tk=java.awt.Toolkit.getDefaultToolkit(); java.awt.Dimension screenSize= ...
- Java 获取本地IP地址
private static String getIpAddress( ){ String ip = ""; Collection<InetAddress> colIn ...
- java获取本地IP地址集合包括虚拟机的ip
public static ArrayList<String> getLocalIpAddr() { ArrayList<String> ipList = new ArrayL ...
随机推荐
- nova 通过 python curl 创建虚拟机---keystone v2
#! /bin/python #coding=utf- import urllib2 import json import requests # token post_url = 'http://12 ...
- latex:备忘代码
1.脚注代码: \footnote{欧几里德,约公元前330--340年.} 结果为: 2.改变某个字的字体形状,表示强调 \emph{勾股定理} 结果为(勾股数这三个字与其他字不一样): 3.正文中 ...
- 必看!2020最新黑马JAVA 学习路线
https://www.fang1688.cn/2020/08/24/%e5%bf%85%e7%9c%8b%ef%bc%81java-%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba ...
- idea创建mybatis的逆向工程:generator
1在工程的目录下配置mybatis-generator插件 <build> <plugins> <!-- mybatis逆向工程 --> <plugin> ...
- 华为云服务器安装hadoop2.7.5
1. 安装环境 1.1硬件环境 1.1.1 NameNode 配置项 详细参数 主机 k8s-master CPU Intel(R) Xeon(R) Gold 6278C CPU @ 2.60GHz ...
- 2020.08.31 Unit 10(暂未完成)
[重点短语] 01.at night 在晚上 02.in a more natural environment 在一个更加自然的环境中 03.all year round 一年到头,终年 04.be ...
- React的几种组件
一.函数组件 该函数在React中是一个有效的组件,可以接收唯一带有数据的props(代表属性)对象,并返回一个React元素.函数式组件要特别注意,组件名称首字母一定要大写.这种方式也成为无状态组件 ...
- 和同事谈谈Flood Fill 算法
前言 今天忙完了公司的工作后,发现同事在做LeeCode的算法题,顿时来了兴趣,于是王子与同事一起探讨如何能做好算法题,今天在此文章中和大家分享一下. 什么是Flood Fill 算法 我们今天谈论的 ...
- 【pytest】(四) pytest的一些其他的运行用法
1. 可以设置当失败N个后停止测试 pytest -x 是当第一个失败产生后,停止 pytest --maxfail=2, 这里就是当失败2个用例后,停止测试 2.pytest 在命令行模式下支持多种 ...
- Codeforces Round #669 (Div. 2)/Codeforces1407 ABCD
A. Ahahahahahahahaha 通过作者半个小时的观察:全零和全一必定有一个是符合要求的答案,因为0的个数和1的个数至少有一个大于等于\(\frac{n}{2}\). B. Big Vova ...