Kaynağa Gözat

视频处理

suntianwu 3 yıl önce
ebeveyn
işleme
9de489b6aa

+ 62 - 13
src/main/java/com/iden/bms/face/FaceIdenService.java

@@ -10,20 +10,19 @@ import com.face.monitor.model.FaceModel;
 import com.iden.bms.service.PersonService;
 import com.iden.common.cache.RedisKeyConstant;
 import com.iden.common.cache.RedisUtil;
-import com.iden.common.entity.IdenCamera;
-import com.iden.common.entity.IdenCommunity;
-import com.iden.common.entity.IdenFaceImage;
+import com.iden.common.entity.*;
 
-import com.iden.common.entity.IdenPerson;
 import com.iden.common.enums.HandleWarningStatusEnum;
 import com.iden.common.enums.PersonTypeEnum;
 import com.iden.common.service.IdenCameraService;
+import com.iden.common.service.IdenCameraVideoService;
 import com.iden.common.service.IdenCommunityService;
 import com.iden.common.service.IdenFaceImageService;
 
 import com.iden.common.util.ByteUtil;
 import com.iden.common.util.DateUtils;
 import com.iden.common.util.FileUtil;
+import com.iden.common.util.VideoUtil;
 import com.iden.common.vo.FaceRetrieveResultVO;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
@@ -52,14 +51,16 @@ public class FaceIdenService {
     private IdenCommunityService idenCommunityService;
     @Resource
     private PersonService personService;
+    @Resource
+    private IdenCameraVideoService idenCameraVideoService;
 
     @Resource
     private RedisUtil redisUtil;
 
     @Value("${iden.root:#{null}}")
     private String idenRoot;
-    @Value("${image.url:#{null}}")
-    private String imageUrl;
+    @Value("${file.url:#{null}}")
+    private String fileUrl;
 
     private static final Logger logger = LogManager.getLogger(FaceIdenService.class);
 
@@ -72,8 +73,8 @@ public class FaceIdenService {
 
         File originImageDirFile = new File(idenRoot + "data/origin/camera/image");
 
-        //使用摄像头编码做目录名,里面图像或视频的名称上加上拍照时间,
-        // 比如  20211217123023.jpg     20211217123023~20211217123323.mp4
+        //使用摄像头编码做目录名,里面图像的名称上加上拍照时间,
+        // 比如  20211222123223_76639ced-6409-11ec-b8f9-fa163e4e1e9f.jpg
         if (originImageDirFile.isDirectory()) {
             File[] cameraCodeDirs = originImageDirFile.listFiles();
             if(cameraCodeDirs != null && cameraCodeDirs.length > 0){
@@ -81,6 +82,7 @@ public class FaceIdenService {
                 //初始化引擎,加载人员图像人脸特征库
                 String personImageDir = idenRoot + "data/final/person";
 
+                //递归获取人员图像目录下的图像文件
                 List<File> imgPersonFileList = new ArrayList<>();
                 imgPersonFileList = FileUtil.getFiles(new File(personImageDir),imgPersonFileList);
                 File[] imgPersonFiles = new File[imgPersonFileList.size()];
@@ -158,7 +160,7 @@ public class FaceIdenService {
 
                                 imgFile.renameTo(finalImgFile);//移动到最终目录
 
-                                idenFaceImage.setImage( imageUrl + cameraCode + "/" + finalImgFile.getName());
+                                idenFaceImage.setImage( fileUrl + "camera/image/" + cameraCode + "/" + finalImgFile.getName());
 
                                 //和人员图像库比对特征码,关联personId
                                 if(faceModels[i] != null){
@@ -263,17 +265,64 @@ public class FaceIdenService {
             return false;
         }
 
-
-
-
     }
     /**
      * 把摄像头上传的图像解开为一帧帧图片,放到图像目录下,等待识别引擎处理
      * @throws Exception
      */
-
     public void handleCameraVideo() throws Exception {
+        logger.info("FaceIdenService.handleCameraVideo start...");
+        File originVideoDirFile = new File(idenRoot + "data/origin/camera/video");
+        //使用摄像头编码做目录名,里面存放视频,名称里包含拍摄结束时间
+        // 比如 20211217123343_76639ced-6409-11ec-b8f9-fa883e4e1e9f.mp4
+        if (originVideoDirFile.isDirectory()) {
+            File[] cameraCodeDirs = originVideoDirFile.listFiles();
+            if (cameraCodeDirs != null && cameraCodeDirs.length > 0) {
+                for(File cameraCodedir : cameraCodeDirs) {
+                    if (cameraCodedir.isDirectory()) {
+                        File[] videoFiles = FileUtil.sortByName(cameraCodedir.listFiles());
+                        if (videoFiles != null && videoFiles.length > 0) {
+                            String cameraCode = cameraCodedir.getName();
+                            QueryWrapper<IdenCamera> queryWrapper = new QueryWrapper<>();
+                            queryWrapper.lambda().eq(IdenCamera::getCode,cameraCode);
+                            IdenCamera idenCamera = idenCameraService.getOne(queryWrapper);
+                            if(idenCamera == null){
+                                continue;
+                            }
 
+                            for(File videoFile : videoFiles){
+                                String videoFileName = videoFile.getName();
+                                String shootEndTimeStr = videoFileName.substring(0, videoFileName.indexOf("_"));
+                                Date shootEndTime = DateUtils.strToDate(shootEndTimeStr,"yyyyMMddHHmmss");
+                                VideoUtil.fetchAllPic(videoFile,idenRoot + "data/origin/camera/image/" + cameraCode, shootEndTime);
+
+                                File finalDir = new File(videoFile.getParentFile().getAbsolutePath().replace("origin","final"));
+                                if(!finalDir.exists()){
+                                    finalDir.mkdirs();
+                                }
+                                logger.info("FaceIdenService.handleCameraVideo ...finalDir == " + finalDir.getAbsolutePath());
+                                logger.info("FaceIdenService.handleCameraVideo ...videoFile.getName() == " + videoFileName);
+                                File finalvideoFile = new File(finalDir, videoFileName);
+
+                                logger.info("FaceIdenService.handleCameraVideo ...finalvideoFile == " + finalvideoFile.getAbsolutePath());
+                                videoFile.renameTo(finalvideoFile);//移动到最终目录
+
+                                IdenCameraVideo idenCameraVideo = new IdenCameraVideo();
+                                idenCameraVideo.setVideoUrl(fileUrl + "camera/video/" + cameraCode + "/" + videoFileName);
+                                idenCameraVideo.setCameraId(idenCamera.getId());
+                                idenCameraVideo.setCommunityId(idenCamera.getCommunityId());
+                                idenCameraVideo.setName(videoFileName.substring(0,videoFileName.lastIndexOf(".mp4")));
+                                idenCameraVideo.setPhotographTime(shootEndTime);
+                                idenCameraVideo.setCreateTime(new Date());
+                                idenCameraVideoService.save(idenCameraVideo);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        logger.info("FaceIdenService.handleCameraImage end");
     }
 
 }

+ 3 - 3
src/main/java/com/iden/bms/schedule/FaceIdenSchedule.java

@@ -30,7 +30,7 @@ public class FaceIdenSchedule {
      * 处理摄像头上传的图像
      */
     @Async
-    @Scheduled(cron = "0 0/1 * * * ?")
+    @Scheduled(cron = "0 0/2 * * * ?")
     public void handleCameraImage() {
         String key = RedisKeyConstant.HANDLE_CAMERA_IMAGE;
         String requestId = UUID.randomUUID().toString();
@@ -51,11 +51,11 @@ public class FaceIdenSchedule {
      * 处理摄像头上传的视频
      */
     @Async
-    @Scheduled(cron = "10 0/5 * * * ?")
+    @Scheduled(cron = "10 0/2 * * * ?")
     public void handleCameraVideo() {
         String key = RedisKeyConstant.HANDLE_CAMERA_VIDEO;
         String requestId = UUID.randomUUID().toString();
-        boolean result = redisUtil.tryLock(key,requestId,5 * 60);
+        boolean result = redisUtil.tryLock(key,requestId,10 * 60);
         try {
             if (result) {
                 faceIdenService.handleCameraVideo();

+ 1 - 1
src/main/java/com/iden/bms/service/PersonService.java

@@ -242,7 +242,7 @@ public class PersonService {
                 String picFullFileName = idenRoot + "data/final/person/" + idenCommunity.getCode() + "/" + saveFileName;
                 FileOutputStream fos = new FileOutputStream(picFullFileName);
                 fos.write(file.getBytes());
-                image = fileUrl + "person/" + saveFileName;
+                image = fileUrl + "person/image/" + idenCommunity.getCode() +"/"+ saveFileName;
             } else {
                 throw new BDException("上传失败");
             }

+ 60 - 55
src/main/java/com/iden/common/util/VideoUtil.java

@@ -1,7 +1,6 @@
 package com.iden.common.util;
 
-import org.bytedeco.javacpp.opencv_core;
-import org.bytedeco.javacpp.opencv_videoio;
+
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.Frame;
 import org.bytedeco.javacv.Java2DFrameConverter;
@@ -15,9 +14,6 @@ import java.io.File;
 import java.util.*;
 import java.util.List;
 
-import static org.bytedeco.javacpp.opencv_imgcodecs.cvSaveImage;
-import static org.bytedeco.javacpp.opencv_videoio.*;
-
 
 /**
  * 视频工具
@@ -56,7 +52,8 @@ public class VideoUtil {
                 System.out.print(i + ",");
                 if (frame != null && frame.image != null) {
                     System.out.println(i);
-                    files.add(writeToFile(frame, saveFile, i));
+                    String fileName = String.valueOf(System.currentTimeMillis()) + i;
+                    files.add(writeToFile(frame, saveFile, fileName));
                 }
                 second++;
             }
@@ -70,8 +67,8 @@ public class VideoUtil {
         if (count > length) {
             count = length;
         }
-        System.out.println(length);
-        System.out.println(count);
+//        System.out.println(length);
+//        System.out.println(count);
         int total = (int) (length / count);
         List<Integer> list = new ArrayList<>();
         for (int i = 0; i < count; i++) {
@@ -81,17 +78,20 @@ public class VideoUtil {
         return list;
     }
 
-    public static List<File> fetchPicByCount(File videoFile, String saveFile, int count) throws Exception {
+    public static List<File> fetchPicByCount(File videoFile, String saveDir, int count) throws Exception {
 
         java.util.List<File> files = new ArrayList<>();
 
         FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
         ff.start();
 
+        // 此视频时长(s/秒)
+        Long duration = ff.getLengthInTime() / (1000 * 1000);
+        System.out.println("duration==" + duration);
+        // 视频总帧数
         int frameLength = ff.getLengthInFrames();
 
-
-        System.out.println("length:" + frameLength);
+        System.out.println("length==" + frameLength);
 
         List<Integer> list = getList(count, frameLength);
 
@@ -105,7 +105,8 @@ public class VideoUtil {
             if (list.contains(i)) {
                 if (frame != null && frame.image != null) {
                     System.out.println(i);
-                    files.add(writeToFile(frame, saveFile, i));
+                    String fileName = String.valueOf(System.currentTimeMillis()) + i;
+                    files.add(writeToFile(frame, saveDir, fileName));
                 }
             }
             i++;
@@ -114,10 +115,48 @@ public class VideoUtil {
         return files;
     }
 
+    public static List<File> fetchAllPic(File videoFile, String saveDir, Date shootEndTime) throws Exception {
+
+        Long endTime = shootEndTime.getTime() ;
+
+        java.util.List<File> files = new ArrayList<>();
+
+        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
+        ff.start();
+
+        // 此视频时长(ms/毫秒秒)
+        Long duration = ff.getLengthInTime() /  1000;
+        System.out.println("duration==" + duration);
 
-    private static File writeToFile(Frame frame, String saveFile, int second) throws Exception {
-        String fileName = String.valueOf(System.currentTimeMillis()) + second;
-        File targetFile = new File(saveFile + File.separator + fileName + ".jpg");
+        Long beginTime = endTime - duration;
+
+        // 视频总帧数
+        int frameLength = ff.getLengthInFrames();
+
+        System.out.println("length==" + frameLength);
+
+        //帧率(1秒多少帧)
+        double framRate = ff.getFrameRate();
+
+        int i = 0;
+        Frame frame = null;
+
+        while (i < frameLength) {
+            frame = ff.grabImage();
+            if (frame != null && frame.image != null) {
+                Double time = beginTime + (i * (1000/framRate));
+                String fileName = DateUtils.formatToDateStr(new Date(time.longValue()),"yyyyMMddHHmmss") + "_" + UUID.randomUUID().toString();
+                files.add(writeToFile(frame, saveDir, fileName));
+            }
+            i++;
+        }
+        ff.stop();
+        return files;
+    }
+
+    private static File writeToFile(Frame frame, String saveDir, String fileName) throws Exception {
+
+        File targetFile = new File(saveDir + File.separator + fileName + ".jpg");
         String imgSuffix = "jpg";
 
         Java2DFrameConverter converter = new Java2DFrameConverter();
@@ -157,51 +196,17 @@ public class VideoUtil {
         return times;
     }
 
-    public static void getBySecond(String filePath, String directory) {
-        opencv_videoio.CvCapture capture = cvCaptureFromFile(filePath);
-        //帧率
-        double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
-        System.out.println("帧率:" + fps);
-        opencv_core.IplImage frame = null;
-        double pos1 = 0;
-
-        double rootCount = 0;
-        while (true) {
-
-            //读取关键帧
-            frame = cvQueryFrame(capture);
-
-            rootCount = fps;
-            while (rootCount > 0) {
-                //这一段的目的是跳过每一秒钟的帧数,也就是说fps是帧率(一秒钟有多少帧),在读取一帧后,跳过fps数量的帧就相当于跳过了1秒钟。
-                frame = cvQueryFrame(capture);
-                rootCount--;
-            }
-
-            //获取当前帧的位置
-            pos1 = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
-            System.out.println(pos1);
-
-            if (null == frame)
-                break;
-
-            cvSaveImage("E:/223/" + pos1 + ".jpg", frame);
-
-        }
-
-        cvReleaseCapture(capture);
-    }
-
-
 
     public static void main(String[] args) {
         try {
             //getList(10,113);
 
-            File file = new File("E:/4bcd37e90a0d087c349bbd817b5b4798.mp4");
-            List<File> files = VideoUtil.fetchPicByCount(file, "E:/223", 100);
-            System.out.println(files.get(0).getName());
-            System.out.println(VideoUtil.getVideoTime(file));
+          File file = new File("E:/4bcd37e90a0d087c349bbd817b5b4798.mp4");
+//            List<File> files = VideoUtil.fetchPicByCount(file, "E:/223", 100);
+//            System.out.println(files.get(0).getName());
+//            System.out.println(VideoUtil.getVideoTime(file));
+            fetchAllPic(file,"E:/223",new Date());
+
         } catch (Exception e) {
             e.printStackTrace();
         }

+ 2 - 2
src/main/resources/application-dev.properties

@@ -31,6 +31,6 @@ spring.redis.jedis.pool.min-idle=5
 
 #服务部署根目录
 iden.root=/data/iden/
-#图像访问http前缀
-image.url=http://124.70.58.209:17778/
+#文件访问http前缀
+file.url=http://124.70.58.209:17778/
 

+ 1 - 1
src/main/resources/application.properties

@@ -2,7 +2,7 @@
 spring.profiles.active=dev
 
 # 配置服务端口号
-    server.port=13456
+server.port=13456
 
 ### spring配置
 # 配置服务名称