java使用opencv2.4.9调用摄像头拍照+保存到本地
- 前言
- 需要的依赖jar包一览
- 贴代码
- 注意点
- 参考的目录
前言
本博客仅供参考使用,现把观前提示写出:
1.语言java,jar包为opencv2.4.9
2.软件 eclipse,程序为rcp(富平台)程序
3.功能为直接调用电脑自带的摄像头,直接拍照并保存到本地,比如G:\image\,然后把图片路径+图片名存入变量,返回,方便其他类调用和取得图片的URL(指的是本地路径+图片名,比如G:\image\45849898_fsf.jpg)
需要的依赖jar包一览
贴代码
package com.ifs.btt.application.splash;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
/**
* 这个类用来 调用摄像头,拍照保存图片,返回图片路径+图片名
* 使用了opencv2,原因是fes系统(本系统)的jdk是1.6,从opencv3开始,jdk要求是1.8及以上
*
*/
public class Camera {
//private DaemonThread myThread = null;
public Shell shell;
public VideoCapture capture;
public CascadeClassifier faceDetector;
public JPanel panel;
public String photo1;
public String path = "G:\\image\\";// 照片存储位置
//public Button button1;
public String photoName = path + System.nanoTime() + ".jpg";
public Camera() {
System.load("G:\\opencv_java249.dll");//加载动态库,可以理解为调用摄像头必须的软件
capture = new VideoCapture(0);//打开摄像头,0代表本电脑自带的摄像头,1代表外设的摄像头
String path = "G:\\haarcascade_frontalface_alt2.xml";//跟Camera类在统一路径
path = new File(path).getAbsolutePath();//返回此抽象路径名的绝对路径名字符串
faceDetector = new CascadeClassifier(path);//从文件 加载 分类器
}
// 摄像头显示模块
public String initComponents() {
Display display = Display.getDefault();
shell = new Shell(display, SWT.EMBEDDED);//设置窗口为EMBEDDED型
shell.setBounds(0,0, 600, 400);//设置界面大小,分别是x轴坐标,y轴坐标,宽高
Frame frame = SWT_AWT.new_Frame(shell);//界面的框架
frame.setLayout(null);
panel = new JPanel();//界面区域
panel.setBounds((frame.getWidth() - 250) / 2, 10, 250, 300);//设置摄像头显示区域大小
frame.add(panel);
//提示语
JLabel label = new JLabel("请把脸部对准摄像头,等待1-5秒");
label.setBounds((frame.getWidth() - 210) / 2, 320, 210, 30);
frame.add(label);
// JButton button = new JButton("拍照");
// button.setBounds((frame.getWidth() - 180) / 2, 320, 30, 30);
// frame.add(button);
// shell.open();
run();//运行本类的run方法
shell.open();
frame.dispose();//frame关闭
shell.dispose();//shell窗口释放
return photo1;
}
public void run() {
capture.set(3, 250);//摄像头分辨率,3-表示width
capture.set(4, 300);//摄像头分辨率,4-表示height
Graphics g = panel.getGraphics();
int width;
int height;
Mat capImg = new Mat();//创建Mat容器
Mat target = new Mat();
MatOfByte mem = new MatOfByte();
MatOfRect faceDetections = new MatOfRect();
width = panel.getWidth();
height = panel.getHeight();
final Container parent = panel.getParent();
final JLabel label = (JLabel) parent.getComponent(1);
final JButton button = (JButton) parent.getComponent(2);
try {
try {
Thread.sleep(2500);//线程请暂停2.5秒再运行
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
capture.grab();//获取一帧图像
capture.retrieve(capImg);//解码视频帧
//设置人脸识别参数,如果使用默认的可以直接写成 faceDetector.detectMultiScale(capImg, faceDetections);
faceDetector.detectMultiScale(capImg, faceDetections, 1.2, 4, 0, new Size(80, 100), new Size(250, 300));
Highgui.imencode(".png", capImg, mem);
Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray()));
BufferedImage buff = (BufferedImage) im;
//把图像刷新到界面上
g.drawImage(buff, 0, 0, width, height, 50, 50, buff.getWidth() - 50, buff.getHeight() - 50, null);
Imgproc.resize(capImg, target, new Size(250, 300));// 修改图片大小
System.out.println(photoName);
Highgui.imwrite(photoName, target);
photo1 = photoName;
label.setText("正在检测中,请稍后");
//isCollect = true;//只截取一张图
Display.getDefault().asyncExec(new Runnable() {
public void run() {
System.out.println("不知道干了什么");
}
});
try {
Thread.sleep(2500);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
capture.release();//关闭摄像头
} catch (Exception ex) {
System.out.println("Error:" + ex.getLocalizedMessage());
}
}
}
2.如何调用呢?
在其他类直接
Camera camera = new Camera();
String path = "";//取到返回值
path = camera.initComponents();//调用camera主要的方法,把图片路径+图片名的值传入这个字符串中,方便以后的操作。
注意点
1.调用摄像头并没有做很好的设置,所以一般定义一个按钮,在按钮的点击事件里调用这个方法,来调用摄像头。
2.按钮点击后,请马上把人脸对准摄像头,否则会马上关闭,因为本类是以截取摄像头拍到的一帧视频帧的方式来获取图片的,会马上运行完。
参考的目录
本demo参考了许多内容,以 一下两个为主,现贴出:
1.Java通过摄像头捕捉人脸识别和已有的照片进行相似度比对(OpenCV + face++) 2.JDK1.6+OpenCV2.4.9+SWT 人脸识别