二话不说,直接上代码
/*
* @Author 张泰清
* @Description //人脸识别
* @Date 2019/12/19 13:14
* @Param
* @return
**/
import org.opencv.core.Point;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.objdetect.HOGDescriptor;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;
public class CaptureBasic extends JPanel {
private BufferedImage mImg;
static int imgName=1;
static boolean isFace=false;
private BufferedImage mat2BI(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 void paintComponent(Graphics g){
if(mImg!=null){
g.drawImage(mImg, 0, 0, mImg.getWidth(),mImg.getHeight(),this);
}
}
public static void main(String[] args) {
try{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat capImg=new Mat();
//VideoCapture capture=new VideoCapture(0);
VideoCapture capture=new VideoCapture("http://192.168.1.204:81/videostream.cgi");
int height = (int)capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
int width = (int)capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
if(height==0||width==0){
throw new Exception("camera not found!");
}
JFrame frame=new JFrame("毕业实习--人脸识别");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
CaptureBasic1 panel=new CaptureBasic1();
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(width+frame.getInsets().left+frame.getInsets().right,
height+frame.getInsets().top+frame.getInsets().bottom);
Mat temp=new Mat();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Timer timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
capture.read(capImg);
Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY);
try {
panel.mImg=panel.mat2BI(detectFace(capImg));
} catch (Exception e) {
e.printStackTrace();
}
panel.repaint();
if (isFace){
Imgcodecs.imwrite("opencv"+imgName+".png", capImg);
imgName++;
}
isFace=false;
}
}, 10,10);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* opencv实现人脸识别
* @param img
*/
public static Mat detectFace(Mat img) throws Exception {
// 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
CascadeClassifier faceDetector = new CascadeClassifier("D:\\Program Files\\OPENCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(img, faceDetections);
//System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
Rect[] rects = faceDetections.toArray();
if(rects != null && rects.length >= 1){
System.out.println("发现人脸"+imgName);
isFace=true;
for (Rect rect : rects) {
Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 0, 255), 2);
}
}
return img;
}
}
使用该程序前需要做以下准备工作:
- 下载安装opencv
- 把opencv安装目录里的/build/java/下的jar包导入项目
- 把opencv安装目录里的/build/java/x64下的.dll文件复制到jdk安装目录的bin目录下
//调用本机默认摄像头
VideoCapture capture=new VideoCapture(0);
//调用ip摄像头
VideoCapture capture=new VideoCapture("http://192.168.1.204:81/videostream.cgi");
//必须把haarcascade_frontalface_alt.xml换成你自己的opencv安装目录里的文件
CascadeClassifier faceDetector = new CascadeClassifier("D:\\Program Files\\OPENCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
至此,程序已经能够正常运行了,在摄像头画面中出现人脸,则会自动拍照存储到类路径下!
下图是本人在学校图书馆的实验结果: