package com.gapf.supervise.web.controller.v1;/**
* Description: TODO
* @author OWolfe
* @date 2020/8/31 13:45
*/
import com.alibaba.fastjson.JSON;
import com.gapf.common.config.GapfConfig;
import com.gapf.management.utils.FaceUtils;
import com.gapf.management.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
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.videoio.VideoCapture;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author Crazy.X
*/
@Slf4j
@RestController
@RequestMapping("/{version}")
public class FaceController extends JPanel{
private static final long serialVersionUID = 1L;
//每一帧视频的BufferedImage对象
private static BufferedImage mImg;
//图片名字格式
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyymmddHHmmss");
//图片保存地址
public static final String FACE_PATH = "/face/";
//图片格式
private static String format = "jpg";
//人脸识别器位置
// private static String altPath = "haarcascade_frontalface_alt.xml";
static {
//在调用之前,一定要加上这句话,目的是加载OpenCV API相关的DLL支持,没有它是不会正确运行的
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
/**
* 将Mat对象转换为BufferedImage
* @param mat
* @return
*/
private static 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;
}
/**
* 将BufferedImage在窗口显示出来
* @param g
*/
public void paintComponent(Graphics g) {
if (mImg != null) {
g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
}
}
/**
* opencv实现人脸识别、画框、转换为BufferedImage对象
* @param img
*/
public static String detectFace(Mat img,CascadeClassifier faceDetector) {
System.out.println("Running DetectFace ... ");
//转为灰度图,直方图均衡化的前提
Mat greyScaleImg = new Mat();
Imgproc.cvtColor(img, greyScaleImg, Imgproc.COLOR_RGB2GRAY,0);
//缩放图片,可提高检测速率,减少检测时间
Mat smallImg=img.clone();
Imgproc.resize(greyScaleImg,smallImg,new Size(img.width()*0.2,img.height()*0.2));
//直方图均衡化,提高图像质量
Mat qualityImg = new Mat();
Imgproc.equalizeHist(smallImg,qualityImg);
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(qualityImg, faceDetections);
//人脸坐标
Rect[] rects = faceDetections.toArray();
//如果检测到人脸
if (rects != null && rects.length >= 1) {
String name = sdf.format(new Date());
//画框
for (Rect rect : rects) {
// Imgproc.rectangle(img, new Point(rect.x*10, rect.y*10),
// new Point(rect.x*10 + rect.width*10, rect.y*10 + rect.height*10),
// new Scalar(0, 255, 245), 2);
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);
// save(qualityImg, rect, "E:\\dir\\img"+name+".jpg");
}
//将这一帧保存起来
String filePath = GapfConfig.getUploadPath()+FACE_PATH+ File.separator + name + "." + format;
File f = new File(filePath);
BufferedImage bufferedImage = mat2BI(img);
try {
ImageIO.write(bufferedImage, format, f);
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
} else {
return null;
}
//测试是否正常接收摄像头视频流此方法只需这一步
//return mat2BI(img);
}
/**
* opencv将人脸进行截图并保存
* @param img
*/
private static void save(Mat img, Rect rect, String outFile){
Mat sub = img.submat(rect);
Mat mat = new Mat();
Size size = new Size(300, 300);
Imgproc.resize(sub, mat, size);
Imgcodecs.imwrite(outFile, mat);
}
/**
* 识别人脸
* @param
*/
@GetMapping("/face/search")
public void searchFace(String rtsp) {
VideoCapture capture = new VideoCapture(); //打开摄像头,参数为0:代表本地摄像头
try {
//打开rtsp地址,需要把opencv\build\bin下的opencv_ffmpeg320_64.dll,拷贝一份到idea工作空间当前项目下,若是打开本地摄像头直接在上一步填入参数0即可,不需要capture.open(rtsp);这一步
capture.open(rtsp);
if (!capture.isOpened()) {
throw new Exception("camera not found!");
}
// JFrame frame = new JFrame("camera");
// frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
FaceController panel = new FaceController();
// frame.setContentPane(panel);
// //设置窗口尺寸
// /*frame.setSize((int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH) + frame.getInsets().left + frame.getInsets().right,
// (int) (capture.get(Videoio.CAP_PROP_FRAME_HEIGHT) + frame.getInsets().top + frame.getInsets().bottom)); 全屏*/
// frame.setSize(1024,768);
// //打开窗口
// frame.setVisible(true);
Mat capImg = new Mat();
// while (frame.isShowing()) {
while (capture.isOpened()) {
//读取一帧视频画面
capture.read(capImg);
//从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
//opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml文件
String altPath = ResourceUtils.getFile("classpath:static/haarcascade_frontalface_alt.xml").getPath();
Resource resource = new ClassPathResource(altPath);
String path= resource.getFile().getPath();
CascadeClassifier faceDetector = new CascadeClassifier(path);
//识别人脸,转换为BufferedImage对象
String imageUrl = detectFace(capImg,faceDetector);
if(imageUrl!=null){
String file = FaceUtils.uploadFile(imageUrl);
String mapStr = FaceUtils.searchFace(file);
float score = 0f;
if(!StringUtil.isBlank(mapStr)){
HashMap hashMap = JSON.parseObject(mapStr, HashMap.class);
Map<String, Map> bodyMap= (Map<String, Map>) hashMap.get("body");
Map<String, Map> dataMap= (Map<String, Map>) hashMap.get("data");
List<Map<String, Map>> listMap= (List<Map<String, Map>>) dataMap.get("matchList");
List<Map<String, Object>> facelistMap= (List<Map<String, Object>>) listMap.get(0).get("faceItems");
Map<String, Object> resultMap= (Map<String, Object>) facelistMap.get(0);
score= Float.valueOf(resultMap.get("score").toString());
if(score>0.6){
System.out.println("-----------------"+resultMap.get("entityId"));
break;
}
}
}
//刷新
panel.repaint();
}
capture.release();
//关闭Frame窗口
// frame.dispose();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("--done--");
capture.release();
}
}
@GetMapping("/face/search1")
public void searchFace1(String rtsp) throws IOException {
String path = ResourceUtils.getFile("classpath:static/haarcascade_frontalface_alt.xml").getPath();
System.out.println(path);
}
public static void main(String[] args) throws IOException {
}
}
java opencv调用摄像头识别人脸并截图
最新推荐文章于 2024-06-01 10:13:18 发布