前几天用Java做了一个人脸识别项目,当时的我还不了解OpenCV是什么,然后突击学习了opencv大概的了解了它的内容,就开始项目的编写了,opencvmat了解一下
opencv的概念
定义识别规则
haarcascade_frontalface_alt.xml
摄像头类 对象
VideoCapture
read(Mat);// 拍一次
Mat //一张相片
OpenVCTools
Mat-Image的转换
BufferedImage mat2BufferedImage(Mat)
前提:
所有的UI显示的内容,都是画出来
JVM一个专门的线程定时画
paintComponent(G...)方法思路
重写组件的paintComponent()方法
在里面追加我们要画图片的逻辑代码
手段
写一个类,继承JPanel,重写paintComponent()方法
super.paintComponent();
画图片
获取图片文件对应的Image对象
加载图片文件->url
将url封装成ImageIcon
从ImageIcon获取Image对象
g.drawImage(xxx);
显示一张图片功能的功能:
1 创建摄像头对象
2 使用摄像头拍一张照片
3 将照片转换成图片
4 将图片画在JPanel上面
下面是openvctools的代码:
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
public final class OpenVCTools {
public final static String FACE_DETECTOR_XML = "e:/work/code/temp/haarcascade_frontalface_alt.xml";
public static Mat convImageFile2Mat(String imgFile, String detectorXml) {
CascadeClassifier detector = new CascadeClassifier(detectorXml);
return convImageFile2Mat(imgFile, detector);
}
public static Mat convImageFile2Mat(String imgFile, CascadeClassifier detector) {
Mat image0 = Imgcodecs.imread(imgFile);
Mat image = new Mat();
//灰度转换
Imgproc.cvtColor(image0, image, Imgproc.COLOR_BGR2GRAY);
MatOfRect faceDetections = new MatOfRect();
//探测人脸
detector.detectMultiScale(image, faceDetections);
// rect中是人脸图片的范围
for (Rect rect : faceDetections.toArray()) {
//切割rect人脸
Mat mat = new Mat(image, rect);
return mat;
}
return null;
}
public static void writeMat(String fileName, Mat capImg) {
Mat mat = new Mat();
Imgproc.cvtColor(capImg, mat, Imgproc.COLOR_RGB2GRAY);
Imgcodecs.imwrite(fileName, mat);
}
public static BufferedImage mat2BufferedImage(Mat mat) {
int dataSize = mat.cols() * mat.rows() * (int) mat.elemSize();
byte[] data = new byte[dataSize];
mat.get(0, 0, data);
int type = mat.channels() == 1 ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR;
if (type == BufferedImage.TYPE_3BYTE_BGR) {
for (int i = 0; i < dataSize; i += 3) {
byte blue = data[i + 0];
data[i + 0] = data[i + 2];
data[i + 2] = blue;
}
}
BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);
return image;
}
public static Mat fetchMat(VideoCapture capture)throws Exception{
Mat capImg = new Mat();
capture.read(capImg);
return capImg;
}
public static double compareMats(Mat mat1, Mat mat2) {
double result = 0;
Mat hist_1 = new Mat();
Mat hist_2 = new Mat();
//颜色范围
MatOfFloat ranges = new MatOfFloat(0f, 256f);
//直方图大小, 越大匹配越精确 (越慢)
MatOfInt histSize = new MatOfInt(1000);
Imgproc.calcHist(Arrays.asList(mat1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
Imgproc.calcHist(Arrays.asList(mat2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);
// CORREL 相关系数
result = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
return result;
}
public static DetectResult detectEye(Mat img, Rect faceRect, String eyeXml) throws Exception{
if(img == null || faceRect == null) {
return null;
}
DetectResult result = new DetectResult();
if (eyeXml == null || "".equals(eyeXml)) {
throw new RuntimeException("没有face识别器文件");
}
CascadeClassifier eyeDetector = new CascadeClassifier(eyeXml);
Mat faceMat = new Mat(img, faceRect);
// 在图片中检测眼睛
MatOfRect eyeDetections = new MatOfRect();
eyeDetector.detectMultiScale(faceMat, eyeDetections);
Rect[] eyeRects = eyeDetections.toArray();
if (null != eyeRects && eyeRects.length >= 2) {
for (Rect eyeRect : eyeRects) {
// 需要加上人脸框的坐标
Imgproc.rectangle(img, new Point(faceRect.x + eyeRect.x, faceRect.y + eyeRect.y),
new Point(faceRect.x + eyeRect.x + eyeRect.width, faceRect.y + eyeRect.y + eyeRect.height),
new Scalar(213, 223, 255), 2);
result.rectHeight.add(eyeRect.height);
result.rectWidth.add(eyeRect.width);
result.rectX.add(faceRect.x+eyeRect.x);
result.rectY.add(faceRect.y+eyeRect.y);
}
}
result.faceRect = faceRect;
result.mat = img;
return result;
}
public static DetectResult detectFace(Mat img, String faceXml) throws Exception {
DetectResult result = new DetectResult();
if (faceXml == null || "".equals(faceXml)) {
throw new RuntimeException("没有face识别器文件");
}
CascadeClassifier faceDetector = new CascadeClassifier(faceXml);
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(img, faceDetections);
Rect[] faceRects = faceDetections.toArray();
// 只需要捕捉一张人脸
if (faceRects != null && faceRects.length == 1) {
Rect faceRect = faceRects[0];
// 绘制矩形
Imgproc.rectangle(img, new Point(faceRect.x, faceRect.y),
new Point(faceRect.x + faceRect.width, faceRect.y + faceRect.height),
new Scalar(0, 0, 255), 2);
result.rectHeight.add(faceRect.height);
result.rectWidth.add(faceRect.width);
result.rectX.add(faceRect.x);
result.rectY.add(faceRect.y);
result.faceRect = faceRect;
}
result.mat=img;
return result;
}
public static DetectResult detectFace(Mat img, String faceXml, String eyeXml) throws Exception {
DetectResult result = new DetectResult();
if (faceXml == null && eyeXml == null) {
throw new RuntimeException("没有识别器xml");
}
CascadeClassifier faceDetector = null;
CascadeClassifier eyeDetector = null;
if (faceXml != null) {
faceDetector = new CascadeClassifier(faceXml);
}
if (eyeXml != null) {
eyeDetector = new CascadeClassifier(eyeXml);
}
return result;
}
public static class DetectResult {
public Mat mat;
public Rect faceRect;
public List rectX=new ArrayList();
public List rectY=new ArrayList();
public List rectWidth=new ArrayList();
public List rectHeight=new ArrayList();
}
}
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
public class openVCUI extends JFrame {
private JPanel contentPane;
private BufferedImage matImage;
private JPanel panel;
private VideoCapture capture;
private boolean isRunning=true;
private boolean isStop=true;
private int count=4;
private Mat mat;
private Mat myMat;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
openVCUI frame = new openVCUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public openVCUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 625, 503);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
panel = new JPanel(){
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(matImage!=null){
g.drawImage(matImage,0,0,this.getWidth(), this.getHeight(),this);
}
}
};
JButton button = new JButton("��ʼ");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
isRunning=true;
Thread t=new Thread(){
public void run(){
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
capture=new VideoCapture(0);
while(isRunning){
mat =new Mat();
capture.read(mat);
//mat1=mat.clone();
CascadeClassifier faceDetector=new CascadeClassifier(OpenCVTools.FACE_DETECTOR_XML);
MatOfRect matOfRect=new MatOfRect();
faceDetector.detectMultiScale(mat,matOfRect);
Rect[] faceRects=matOfRect.toArray();
if(faceRects !=null&&faceRects.length>0){
Rect firstRect=faceRects[0];
Imgproc.rectangle(mat, new Point(firstRect.x,firstRect.y), new Point(firstRect.x+firstRect.width,firstRect.y+firstRect.height),new Scalar(0, 0, 255), 2); }
myMat=mat;
matImage=OpenCVTools.mat2BufferedImage(myMat);
panel.repaint();
// isRunning=true;
}
capture.release();
}
};
t.start();
// System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// VideoCapture capture=new VideoCapture(0);
// Mat mat =new Mat();
// capture.read(mat);
// matImage =OpenVCTools.mat2BufferedImage(mat);
// //cvtColor(matImage,matImage, CV_RGB2GRAY);//תΪ�Ҷ�ͼ
// panel.repaint();
// capture.release();
}
});
button.setFont(new Font("����", Font.PLAIN, 20));
JButton btnStop = new JButton("����");
btnStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
isRunning=false;
}
});
btnStop.setFont(new Font("����", Font.PLAIN, 20));
JButton button_1 = new JButton("�Ա�");
button_1.setFont(new Font("����", Font.PLAIN, 20));
button_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//CascadeClassifier faceDedector=new CascadeClassfier();
// 1 ץ������ͷ���ĵ���
// ��������ʶ����
CascadeClassifier faceDetector = new CascadeClassifier(OpenCVTools.FACE_DETECTOR_XML);
MatOfRect matOfRect = new MatOfRect();
// ʶ��mat�е�������
faceDetector.detectMultiScale(myMat, matOfRect);
// ��ȡ������������
Rect[] faceRects = matOfRect.toArray();
Mat newFaceMat = null;
if (faceRects != null && faceRects.length > 0) {
// ��һ����
newFaceMat = new Mat(myMat, faceRects[0]);
}
// 2 ץ��������ͼƬ�ļ��е�������ǰ�ɼ��ģ�
// 2.0 ��ȡ���е�ͼƬ�ļ�
File dir = new File("E:\\Image");
File[] files = dir.listFiles();
if(files==null){
System.out.println("ƥ�䲻�ɹ�");
}
if (files != null && files.length > 0) {
String resultFileName = null;
double finallyResult = 0.8;
for (File f : files) {
// ��ȡ�ļ��ģ�����·��������
String fileName = f.getAbsolutePath();
// 2.1 ��ȡ�ļ�-��Mat
Mat fileMat = Imgcodecs.imread(fileName);
// 2.2 ��Mat��ץȡ��
faceDetector.detectMultiScale(fileMat, matOfRect);
faceRects = matOfRect.toArray();
Mat oldMat = null;
if (faceRects != null && faceRects.length > 0) {
oldMat = new Mat(fileMat, faceRects[0]);
}
// 3 ������������ƥ���ʵıȶ�
// ���ȶԵ�ϵ��
// ����ϵ���ȶԽ��
if (newFaceMat != null && !newFaceMat.empty() && oldMat != null && !oldMat.empty()) {
double result = OpenCVTools.compareMats(newFaceMat, oldMat);
System.out.println(result);
if (result > finallyResult) {
resultFileName = fileName;
}
}else{
resultFileName=null;
}
}
textField.setText(resultFileName);
}else{
System.out.println("ƥ�䲻�ɹ�");
}
}
});
textField = new JTextField();
textField.setColumns(10);
JButton button_2 = new JButton("\u91C7\u96C6");
button_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (myMat != null && !myMat.empty()) {
System.out.println("123456789");
Imgcodecs.imwrite("E:\\Image\\Image" + count++ + ".png", myMat);
}
}
});
button_2.setFont(new Font("����", Font.PLAIN, 20));
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING, false)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(98)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 341, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(64)
.addComponent(button)
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(button_2)
.addGap(49)
.addComponent(btnStop)
.addGap(58)))
.addComponent(button_1))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(171)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, 259, GroupLayout.PREFERRED_SIZE)))
.addContainerGap(87, Short.MAX_VALUE))
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(46)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 287, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 46, Short.MAX_VALUE)
.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
.addComponent(button)
.addComponent(button_1)
.addComponent(btnStop)
.addComponent(button_2))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(7))
);
contentPane.setLayout(gl_contentPane);
}
}
注意事项:路径问题不要出错
正确的配置opencv
合理的使用windowbuilder插件
建立文件夹来存放照片