java opencv调用摄像头识别人脸并截图

tech2022-12-08  94

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 { } }
最新回复(0)