Browse Source

2019/07/10

x1ongzhu 6 years ago
parent
commit
d602daa8f2

+ 69 - 0
src/main/java/com/izouma/awesomeadmin/dto/VideoProcessResult.java

@@ -0,0 +1,69 @@
+package com.izouma.awesomeadmin.dto;
+
+import net.sf.json.JSONObject;
+
+public class VideoProcessResult {
+    private Integer rank;
+    private Integer total;
+    private Double  score;
+    private Double  liveTime;
+    private Integer killNum;
+    private String  image;
+
+    public Integer getRank() {
+        return rank;
+    }
+
+    public void setRank(Integer rank) {
+        this.rank = rank;
+    }
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Double getLiveTime() {
+        return liveTime;
+    }
+
+    public void setLiveTime(Double liveTime) {
+        this.liveTime = liveTime;
+    }
+
+    public Integer getKillNum() {
+        return killNum;
+    }
+
+    public void setKillNum(Integer killNum) {
+        this.killNum = killNum;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    public boolean isValid() {
+        return rank != null && total != null && score != null && liveTime != null && image != null;
+    }
+
+    @Override
+    public String toString() {
+        return JSONObject.fromObject(this).toString(4);
+    }
+}

+ 8 - 10
src/main/java/com/izouma/awesomeadmin/service/impl/VideoRecognitionServiceImpl.java

@@ -1,6 +1,7 @@
 package com.izouma.awesomeadmin.service.impl;
 
 import com.izouma.awesomeadmin.constant.AppConstant;
+import com.izouma.awesomeadmin.dto.VideoProcessResult;
 import com.izouma.awesomeadmin.model.PlayerInfo;
 import com.izouma.awesomeadmin.service.PlayerInfoService;
 import com.izouma.awesomeadmin.service.VideoRecognitionService;
@@ -59,16 +60,13 @@ public class VideoRecognitionServiceImpl implements VideoRecognitionService {
         executor.execute(() -> {
             try {
                 playerInfoService.updatePlayerInfo(playerInfo);
-                Map<String, String> map = videoProcessTool.processVideo(playerInfo.getVideo(), 0);
-                if (map != null) {
-                    playerInfo.setImage(map.get("image"));
-                    playerInfo.setScore(Float.parseFloat(map.get("评分")));
-                    playerInfo.setLiveTime(map.get("参赛时间").replace("分钟", ""));
-                    playerInfo.setRanking(Integer.valueOf(map.get("rank").replace("第", "")));
-                    try {
-                        playerInfo.setKillNumber(Integer.parseInt(map.get("淘汰")));
-                    } catch (Exception ignore) {
-                    }
+                VideoProcessResult result = videoProcessTool.processVideo1(playerInfo.getVideo(), 0);
+                if (result != null && result.isValid()) {
+                    playerInfo.setImage(result.getImage());
+                    playerInfo.setScore(Float.parseFloat(result.getScore().toString()));
+                    playerInfo.setLiveTime(result.getLiveTime().toString());
+                    playerInfo.setRanking(result.getRank());
+                    // playerInfo.setKillNumber(result.getKillNum());
                     playerInfo.setStatusFlag(AppConstant.PlayerStatus.PROCESSED);
                 } else {
                     playerInfo.setStatusFlag(AppConstant.PlayerStatus.PROCESSED_FAIL);

+ 134 - 19
src/main/java/com/izouma/awesomeadmin/util/VideoProcessToolNew.java

@@ -1,5 +1,6 @@
 package com.izouma.awesomeadmin.util;
 
+import com.izouma.awesomeadmin.dto.VideoProcessResult;
 import com.izouma.awesomeadmin.service.OSSFileService;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -21,6 +22,7 @@ import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.function.BiConsumer;
 import java.util.regex.Pattern;
 
 import static org.bytedeco.javacpp.lept.pixRead;
@@ -42,11 +44,18 @@ public class VideoProcessToolNew {
         long frameCount = 0;
         FrameGrabber videoGrabber = new FFmpegFrameGrabber(path);
         videoGrabber.start();
+        System.out.println(videoGrabber.getLengthInFrames());
+        System.out.println(videoGrabber.getLengthInTime());
+        videoGrabber.setTimestamp(62500000L);
         Frame vFrame;
         do {
             vFrame = videoGrabber.grabFrame();
             if (vFrame != null) {
                 frameCount++;
+                if (!vFrame.keyFrame) {
+                    continue;
+                }
+                System.out.println(vFrame.timestamp);
                 if (frameCount % 200 == 0) {
                     System.gc();
                 }
@@ -58,19 +67,20 @@ public class VideoProcessToolNew {
                     Mat filtered = new Mat();
                     bilateralFilter(frame, filtered, 25, 25 * 2, 25 / 2f);
                     if (map.get("rank") == null) {
-                        String rank = extractRank(filtered);
-                        if (StringUtils.isNotEmpty(rank))
-                            map.put("rank", rank);
+                        Integer rank = extractRank(filtered);
+                        if (rank != null)
+                            map.put("rank", rank.toString());
                     }
                     if (map.get("total") == null) {
-                        String total = extractTotalNum(filtered);
-                        if (StringUtils.isNotEmpty(total))
-                            map.put("total", total);
+                        Integer total = extractTotalNum(filtered);
+                        if (total != null)
+                            map.put("total", total.toString());
                     }
                     if (map.get("参赛时间") == null) {
-                        Map<String, String> statistics = getStatistics(filtered);
-                        if (statistics != null)
-                            map.putAll(statistics);
+                        Map<String, Double> statistics = getStatistics(filtered);
+                        if (statistics != null) {
+                            statistics.forEach((s, aDouble) -> map.put(s, aDouble.toString()));
+                        }
                     }
                     filtered.release();
                     if (map.get("rank") != null
@@ -108,6 +118,102 @@ public class VideoProcessToolNew {
         return map;
     }
 
+    public VideoProcessResult processVideo1(String path, int frameSkip) throws FrameGrabber.Exception {
+        SVM svm = SVM.load(GetResource.class.getClassLoader().getResource("trainneddata/pubg.xml").getPath());
+        VideoProcessResult result = new VideoProcessResult();
+        OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
+        long frameCount = 0;
+        FrameGrabber videoGrabber = new FFmpegFrameGrabber(path);
+        videoGrabber.start();
+        Frame vFrame;
+        List<long[]> slices = toSlices(videoGrabber.getLengthInTime());
+        for (long[] slice : slices) {
+            long start = slice[0];
+            long end = slice[1];
+            long ts = start;
+            videoGrabber.setTimestamp(start);
+            while (ts <= end) {
+                vFrame = videoGrabber.grabFrame();
+                if (vFrame != null) {
+                    ts = vFrame.timestamp;
+                    frameCount++;
+                    if (frameCount % 200 == 0) {
+                        System.gc();
+                    }
+                    if (frameSkip > 0 && frameCount % frameSkip != 0) {
+                        continue;
+                    }
+                    Mat frame = removeBlackBarAndRotate(converterToMat.convert(vFrame));
+                    if (matchGameOver(svm, frame)) {
+                        Mat filtered = new Mat();
+                        bilateralFilter(frame, filtered, 25, 25 * 2, 25 / 2f);
+                        if (result.getRank() == null) {
+                            result.setRank(extractRank(filtered));
+                        }
+                        if (result.getTotal() == null) {
+                            result.setTotal(extractTotalNum(filtered));
+                        }
+                        if (result.getLiveTime() == null) {
+                            Map<String, Double> statistics = getStatistics(filtered);
+                            if (statistics != null) {
+                                result.setScore(statistics.get("评分"));
+                                result.setLiveTime(statistics.get("参赛时间"));
+                                // result.setKillNum(Integer.parseInt(statistics.get("淘汰").toString()));
+                            }
+                        }
+                        filtered.release();
+                        if (result.getRank() != null
+                                && result.getTotal() != null
+                                && result.getLiveTime() != null
+                                && result.getScore() != null) {
+                            try {
+                                double score = result.getScore();
+                                double total = result.getTotal();
+                                double rank = result.getRank();
+                                if (score > (total - rank) / total * 100 / 2) {
+                                    String filename = "/var/samples/" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(8) + ".jpg";
+                                    org.bytedeco.javacpp.opencv_imgcodecs.imwrite(filename, frame);
+                                    result.setImage(uploadImage(frame));
+                                    break;
+                                }
+                            } catch (Exception ignore) {
+                            }
+                        }
+                    }
+                    frame.release();
+                    System.out.println(frameCount + " frame processed");
+                } else {
+                    break;
+                }
+            }
+            if (result.isValid()) {
+                break;
+            }
+        }
+        videoGrabber.stop();
+        videoGrabber.release();
+        svm.deallocate();
+        System.gc();
+        return result.isValid() ? result : null;
+    }
+
+    private List<long[]> toSlices(Long total) {
+        List<long[]> list = new ArrayList<>();
+        long end = total;
+        while (true) {
+            long start = end - 30000000L;
+            if (start < 0) {
+                start = 0;
+            }
+            list.add(new long[]{start, end});
+            if (start == 0) {
+                break;
+            }
+            end = start - 1;
+        }
+        return list;
+    }
+
     public boolean matchGameOver(SVM svm, Mat inputImage) {
         Mat resized = new Mat();
         resize(inputImage, resized, new Size(854, 480));
@@ -123,8 +229,8 @@ public class VideoProcessToolNew {
     }
 
 
-    public String extractRank(Mat src) {
-        String result = null;
+    public Integer extractRank(Mat src) {
+        Integer result = null;
         int m = src.rows();
         int n = src.cols();
         Mat roi = new Mat(src, new Range(0, (int) (m * 0.093)), new Range((int) (n * 0.44), (int) (n * 0.56)));
@@ -193,9 +299,12 @@ public class VideoProcessToolNew {
                 txtImg.release();
                 System.out.println(str);
                 if (str != null) {
-                    str = str.replaceAll("[ \n]", "");
+                    str = str.replaceAll("[ \n.]", "");
                     if (Pattern.matches("^第\\d{1,3}$", str)) {
-                        result = str;
+                        try {
+                            result = Integer.parseInt(str.replace("第", ""));
+                        } catch (Exception ignored) {
+                        }
                         break;
                     }
                 }
@@ -207,8 +316,8 @@ public class VideoProcessToolNew {
         return result;
     }
 
-    public String extractTotalNum(Mat src) {
-        String result = null;
+    public Integer extractTotalNum(Mat src) {
+        Integer result = null;
         int m = src.rows();
         int n = src.cols();
         Mat roi = new Mat(src, new Range(0, (int) (m * 0.08)), new Range((int) (n * 0.42), (int) (n * 0.58)));
@@ -257,7 +366,10 @@ public class VideoProcessToolNew {
                 if (str != null) {
                     str = str.replaceAll("[ \n]", "");
                     if (Pattern.matches("^/\\d{1,3}$", str)) {
-                        result = str.replace("/", "");
+                        try {
+                            result = Integer.parseInt(str.replace("/", ""));
+                        } catch (Exception ignored) {
+                        }
                         break;
                     }
                 }
@@ -327,7 +439,7 @@ public class VideoProcessToolNew {
         return result;
     }
 
-    public Map<String, String> getStatistics(Mat src) {
+    public Map<String, Double> getStatistics(Mat src) {
         imwrite("time.jpg", src);
         int m = src.rows();
         int n = src.cols();
@@ -343,7 +455,7 @@ public class VideoProcessToolNew {
                 // new Rect((int) (filtered.cols() * 0.428), 0, (int) (filtered.cols() * 0.114), filtered.rows()),
                 // new Rect((int) (filtered.cols() * 0.542), 0, (int) (filtered.cols() * 0.1), filtered.rows()),
                 // new Rect((int) (filtered.cols() * 0.642), 0, (int) (filtered.cols() * 0.1), filtered.rows()),
-                new Rect((int) (filtered.cols() * 0.742), 0, (int) (filtered.cols() * 0.1), filtered.rows())
+                new Rect((int) (filtered.cols() * 0.742), 0, (int) (filtered.cols() * 0.15), filtered.rows())
         };
         String[] names = {
                 "淘汰",
@@ -388,7 +500,10 @@ public class VideoProcessToolNew {
                 double score = Double.parseDouble(map.get("评分"));
                 double time = Double.parseDouble(map.get("参赛时间").replace("分钟", ""));
                 if (score >= 0 && score <= 100 && time >= 0 && time <= 45) {
-                    return map;
+                    Map<String, Double> result = new HashMap<>();
+                    result.put("评分", score);
+                    result.put("参赛时间", time);
+                    return result;
                 }
             } catch (Exception ignored) {
             }

+ 7 - 7
src/test/java/VideoProcessTest.java

@@ -1,3 +1,4 @@
+import com.izouma.awesomeadmin.dto.VideoProcessResult;
 import com.izouma.awesomeadmin.util.VideoProcessToolNew;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.bytedeco.javacpp.opencv_core;
@@ -27,9 +28,8 @@ public class VideoProcessTest {
     public void testVideoNew() {
         try {
             long ts = System.currentTimeMillis();
-            Map<String, String> result = videoProcessToolNew.processVideo("/Users/drew/Downloads/464.flv", 0);
+            VideoProcessResult result = videoProcessToolNew.processVideo1("/Users/drew/Downloads/2019-07-09-04-29-14-hacic6mw.mp4", 0);
             System.out.println(result);
-            System.out.println((System.currentTimeMillis() - ts) / 1000f / 60);
         } catch (FrameGrabber.Exception e) {
             e.printStackTrace();
         }
@@ -38,7 +38,7 @@ public class VideoProcessTest {
     @Test
     public void testMatch() {
         opencv_ml.SVM svm = opencv_ml.SVM.load(GetResource.class.getClassLoader().getResource("trainneddata/pubg.xml").getPath());
-        Mat img = imread("/Users/drew/Desktop/samples/has/1.jpg");
+        Mat img = imread("/Users/drew/Pictures/Screenshots/2019-07-09-04-29-14-hacic6mw-0001.jpg");
         boolean b = videoProcessToolNew.matchGameOver(svm, img);
         System.out.println(b);
     }
@@ -54,8 +54,8 @@ public class VideoProcessTest {
 
     @Test
     public void testRank() {
-        Mat img = getTestImg("/Users/drew/Desktop/time.jpg");
-        String rank = videoProcessToolNew.extractRank(img);
+        Mat img = getTestImg("/Users/drew/Pictures/Screenshots/2019-07-09-04-29-14-hacic6mw-0001.jpg");
+        Integer rank = videoProcessToolNew.extractRank(img);
     }
 
     @Test
@@ -79,8 +79,8 @@ public class VideoProcessTest {
 
     @Test
     public void testStatistics() {
-        Mat img = getTestImg("/Users/drew/Desktop/time.jpg");
-        Map<String, String> map = videoProcessToolNew.getStatistics(img);
+        Mat img = getTestImg("/Users/drew/Pictures/Screenshots/2019-07-09-04-29-14-hacic6mw-0001.jpg");
+        Map<String, Double> map = videoProcessToolNew.getStatistics(img);
         System.out.println(map);
     }