Bladeren bron

识别淘汰人数

x1ongzhu 6 jaren geleden
bovenliggende
commit
ebfec4c088

+ 217 - 9
src/main/java/com/izouma/awesomeadmin/util/VideoProcessToolNew.java

@@ -6,6 +6,7 @@ import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.bytedeco.javacpp.indexer.UByteRawIndexer;
 import org.bytedeco.javacpp.indexer.UByteRawIndexer;
+import org.bytedeco.javacpp.opencv_imgproc;
 import org.bytedeco.javacpp.tesseract;
 import org.bytedeco.javacpp.tesseract;
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.Frame;
 import org.bytedeco.javacv.Frame;
@@ -23,6 +24,7 @@ import java.nio.ByteBuffer;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.*;
 import java.util.function.BiConsumer;
 import java.util.function.BiConsumer;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
 import static org.bytedeco.javacpp.lept.pixRead;
 import static org.bytedeco.javacpp.lept.pixRead;
@@ -84,9 +86,9 @@ public class VideoProcessToolNew {
                     }
                     }
                     filtered.release();
                     filtered.release();
                     if (map.get("rank") != null
                     if (map.get("rank") != null
-                            && map.get("total") != null
-                            && map.get("参赛时间") != null
-                            && map.get("评分") != null) {
+                        && map.get("total") != null
+                        && map.get("参赛时间") != null
+                        && map.get("评分") != null) {
                         double score = 0;
                         double score = 0;
                         double total = 0;
                         double total = 0;
                         double rank = 0;
                         double rank = 0;
@@ -163,9 +165,9 @@ public class VideoProcessToolNew {
                         }
                         }
                         filtered.release();
                         filtered.release();
                         if (result.getRank() != null
                         if (result.getRank() != null
-                                && result.getTotal() != null
-                                && result.getLiveTime() != null
-                                && result.getScore() != null) {
+                            && result.getTotal() != null
+                            && result.getLiveTime() != null
+                            && result.getScore() != null) {
                             try {
                             try {
                                 double score = result.getScore();
                                 double score = result.getScore();
                                 double total = result.getTotal();
                                 double total = result.getTotal();
@@ -266,8 +268,8 @@ public class VideoProcessToolNew {
                     dv = 238 - v;
                     dv = 238 - v;
                 }
                 }
                 int gray = (int) (255 - Math.min(255, dh * 50)
                 int gray = (int) (255 - Math.min(255, dh * 50)
-                        - Math.min(255, ds * 3)
-                        - Math.min(255, dv * 10));
+                                  - Math.min(255, ds * 3)
+                                  - Math.min(255, dv * 10));
                 gray = gray < 0 ? 0 : gray;
                 gray = gray < 0 ? 0 : gray;
                 // int gray = (h == 26 && Math.abs(s - S) < 50) ? 255 : 0;
                 // int gray = (h == 26 && Math.abs(s - S) < 50) ? 255 : 0;
                 filteredIndexer.put(i, j, gray);
                 filteredIndexer.put(i, j, gray);
@@ -495,7 +497,7 @@ public class VideoProcessToolNew {
         filtered.release();
         filtered.release();
         roi.release();
         roi.release();
         if (Pattern.matches("((^([0-9]+[.][0-9]*))|(^\\d{1,2}))分钟", map.get("参赛时间")) &&
         if (Pattern.matches("((^([0-9]+[.][0-9]*))|(^\\d{1,2}))分钟", map.get("参赛时间")) &&
-                Pattern.matches("((^([0-9]+[.][0-9]+)$)|(^\\d{1,2})$)", map.get("评分"))) {
+            Pattern.matches("((^([0-9]+[.][0-9]+)$)|(^\\d{1,2})$)", map.get("评分"))) {
             try {
             try {
                 double score = Double.parseDouble(map.get("评分"));
                 double score = Double.parseDouble(map.get("评分"));
                 double time = Double.parseDouble(map.get("参赛时间").replace("分钟", ""));
                 double time = Double.parseDouble(map.get("参赛时间").replace("分钟", ""));
@@ -511,6 +513,196 @@ public class VideoProcessToolNew {
         return null;
         return null;
     }
     }
 
 
+    public void getKill(Mat src) {
+        int m = src.rows();
+        int n = src.cols();
+        src = removeBlackBarAndRotate(src);
+        Mat roi = new Mat(src, new Range(0, (int) (m * 0.05)), new Range(0, (int) (n * 0.2)));
+        Mat out = new Mat();
+        bilateralFilter(roi, out, 25, 25 * 2, 25 / 2f);
+        imwrite("kill.jpg", out);
+
+        Mat filtered = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
+
+        UByteRawIndexer srcIndexer = roi.createIndexer();
+        UByteRawIndexer filteredIndexer = filtered.createIndexer();
+        for (int i = 0; i < out.rows(); i++) {
+            for (int j = 0; j < out.cols(); j++) {
+                int b = srcIndexer.get(i, j, 0);
+                int g = srcIndexer.get(i, j, 1);
+                int r = srcIndexer.get(i, j, 2);
+                // if (b > 150 & g > 150 & r > 150) {
+                //     filteredIndexer.put(i, j, (b + g + r) / 3);
+                // } else {
+                //     filteredIndexer.put(i, j, 0);
+                // }
+                int gg = (b + g + r) / 3 - 80;
+                gg -= Math.sqrt((Math.pow(b - g, 2) + Math.pow(b - r, 2) + Math.pow(r - g, 2)) / 3);
+                gg = Math.max(gg, 0);
+                gg *= 1.5;
+                gg = Math.min(gg, 255);
+                gg = 255 - gg;
+                filteredIndexer.put(i, j, gg);
+            }
+        }
+        imwrite("kill_f.png", filtered);
+
+        Mat gray = new Mat();
+        threshold(filtered, gray, 253, 255, THRESH_BINARY);
+
+        erode(gray, gray, 1);
+
+        imwrite("kill_g.png", gray);
+
+
+        MatVector contours = new MatVector();
+        findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
+        List<Rect> rects = new ArrayList<>();
+        for (int i = 0; i < contours.size(); i++) {
+            Mat contour = contours.get(i);
+            Rect rect = boundingRect(contour);
+            rects.add(rect);
+            contour.release();
+        }
+        rects.sort(Comparator.comparingInt(Rect::area));
+        for (int i = 0; i < rects.size(); i++) {
+            Rect rect = rects.get(i);
+            if (rect.area() < 1000) {
+                continue;
+            }
+            System.out.println(rect.area());
+
+            Mat txtImg = new Mat(filtered, new Range(rect.y(), rect.y() + rect.height()), new Range(rect.x(), rect.x() + rect.width()));
+            resize(txtImg, txtImg, new Size(txtImg.cols() * 2, txtImg.rows() * 2));
+
+            String str = doOCR(txtImg, "chi_sim");
+            System.out.println(str);
+
+            rectangle(out, rect, new Scalar(255, 0, 0, 0));
+
+            imwrite("text" + i + "_.png", txtImg);
+
+            erode(txtImg, txtImg, 2);
+
+            threshold(txtImg, txtImg, 200, 255, THRESH_BINARY);
+            imwrite("text" + i + ".png", txtImg);
+        }
+        imwrite("kill_src.png", out);
+
+        srcIndexer.release();
+        filteredIndexer.release();
+    }
+
+    public Integer getKillNum(Mat src) {
+        int m = src.rows();
+        int n = src.cols();
+        Mat roi = new Mat(src, new Range(0, (int) (m * 0.05)), new Range(0, (int) (n * 0.2)));
+
+        Mat filtered1 = new Mat(roi.rows(), roi.cols(), CV_8UC3, new Scalar(0));
+        Mat filtered2 = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
+        UByteRawIndexer srcIndexer = roi.createIndexer();
+        UByteRawIndexer idx1 = filtered1.createIndexer();
+        UByteRawIndexer idx2 = filtered2.createIndexer();
+        for (int i = 0; i < roi.rows(); i++) {
+            for (int j = 0; j < roi.cols(); j++) {
+                int b = srcIndexer.get(i, j, 0);
+                int g = srcIndexer.get(i, j, 1);
+                int r = srcIndexer.get(i, j, 2);
+                // if (b > 150 & g > 150 & r > 150) {
+                //     idx1.put(i, j, (b + g + r) / 3);
+                // } else {
+                //     idx1.put(i, j, 0);
+                // }
+
+                if (b > 190 && g > 190 & r > 190) {
+                    idx1.put(i, j, 0, b);
+                    idx1.put(i, j, 1, g);
+                    idx1.put(i, j, 2, r);
+                } else {
+                    idx1.put(i, j, 0, 0);
+                    idx1.put(i, j, 1, 0);
+                    idx1.put(i, j, 2, 0);
+                }
+
+                int gg = (b + g + r) / 3 - 80;
+                gg -= Math.sqrt((Math.pow(b - g, 2) + Math.pow(b - r, 2) + Math.pow(r - g, 2)) / 3);
+                gg = Math.max(gg, 0);
+                gg *= 1.5;
+                gg = Math.min(gg, 255);
+                gg = 255 - gg;
+                idx2.put(i, j, gg);
+            }
+        }
+        srcIndexer.release();
+        idx1.release();
+        idx2.release();
+
+        cvtColor(filtered1, filtered1, COLOR_BGR2GRAY);
+        imwrite("kill_f1.png", filtered1);
+        imwrite("kill_f2.png", filtered2);
+
+        imwrite("kill.jpg", roi);
+        Mat gray = new Mat();
+        threshold(filtered1, gray, 200, 255, THRESH_BINARY);
+        filtered1.release();
+        imwrite("kill_g.jpg", gray);
+
+        dilate(gray, gray, 3);
+        imwrite("kill_g_dilate.jpg", gray);
+
+        erode(gray, gray, 1);
+        imwrite("kill_g_erode.jpg", gray);
+
+
+        MatVector contours = new MatVector();
+        findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
+        gray.release();
+
+        List<Rect> rects = new ArrayList<>();
+        int width = 0;
+        int height = 0;
+        for (int i = 0; i < contours.size(); i++) {
+            Mat contour = contours.get(i);
+            Rect rect = boundingRect(contour);
+            rects.add(rect);
+            contour.release();
+            width += rect.width();
+            if (rect.height() > height) {
+                height = rect.height();
+            }
+            rectangle(roi, rect, new Scalar(0, 255, 0, 0));
+        }
+        imwrite("kill.jpg", roi);
+
+        Mat img = new Mat(height, width, CV_8UC1, new Scalar(255, 255, 255, 0));
+        int colStart = 0;
+        rects.sort(Comparator.comparingInt(Rect::x));
+        for (Rect rect : rects) {
+            int rowStart = (img.rows() - rect.height()) / 2;
+            filtered2.rowRange(new Range(rect.y(), rect.y() + rect.height()))
+                     .colRange(new Range(rect.x(), rect.x() + rect.width()))
+                     .copyTo(img.rowRange(rowStart, rowStart + rect.height())
+                                .colRange(colStart, colStart + rect.width()));
+            colStart += rect.width();
+        }
+        filtered2.release();
+        resize(img, img, new Size(width * 3, height * 3));
+        imwrite("img.jpg", img);
+        String str = doOCR(img);
+        img.release();
+        System.out.println(str);
+        if (StringUtils.isNotEmpty(str)) {
+            str = str.replace(" ", "");
+            Pattern pattern = Pattern.compile("淘汰(\\d{1,2})");
+            Matcher matcher = pattern.matcher(str);
+            if (matcher.find()) {
+                System.out.println(matcher.group(0));
+                return Integer.parseInt(matcher.group(1));
+            }
+        }
+        return 0;
+    }
+
     public Mat timeFilter(Mat src) {
     public Mat timeFilter(Mat src) {
         int b = 27;
         int b = 27;
         int g = 145;
         int g = 145;
@@ -574,6 +766,22 @@ public class VideoProcessToolNew {
         return recognizedText == null ? "" : recognizedText;
         return recognizedText == null ? "" : recognizedText;
     }
     }
 
 
+    private void dilate(Mat src, Mat dst, float dilation_size) {
+        Mat dilationElement = getStructuringElement(MORPH_ELLIPSE,
+                                                    new Size((int) (2 * dilation_size + 1), (int) (2 * dilation_size + 1)),
+                                                    new Point((int) dilation_size, (int) dilation_size));
+        opencv_imgproc.dilate(src, dst, dilationElement);
+        dilationElement.release();
+    }
+
+    private void erode(Mat src, Mat dst, float erosion_size) {
+        Mat erodeElement = getStructuringElement(MORPH_RECT,
+                                                 new Size((int) (2 * erosion_size + 1), (int) (2 * erosion_size + 1)),
+                                                 new Point((int) erosion_size, (int) erosion_size));
+        opencv_imgproc.erode(src, dst, erodeElement);
+        erodeElement.release();
+    }
+
     public Mat removeBlackBarAndRotate(Mat src) {
     public Mat removeBlackBarAndRotate(Mat src) {
         if (src.cols() < src.rows()) {
         if (src.cols() < src.rows()) {
             rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);
             rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);

BIN
src/main/resources/trainneddata/pubg.traineddata


+ 11 - 0
src/test/java/VideoProcessTest.java

@@ -92,4 +92,15 @@ public class VideoProcessTest {
         System.out.println(df.format(Math.random() * 40));
         System.out.println(df.format(Math.random() * 40));
         RandomStringUtils.random(100, "01234567890./,第分钟");
         RandomStringUtils.random(100, "01234567890./,第分钟");
     }
     }
+
+    @Test
+    public void testKill() {
+        Mat img = imread("/Users/drew/Pictures/Screenshots/2019-08-12-05-26-16-6j9l2tpm-0004.jpg");
+        // Mat img = imread("/Users/drew/Pictures/Screenshots/2019-08-12-05-26-16-6j9l2tpm-0001.jpg");
+        // Mat img = imread("/Users/drew/Pictures/Screenshots/2019-08-12-05-26-16-6j9l2tpm-0003.jpg");
+        Mat filtered = new Mat();
+        bilateralFilter(img, filtered, 25, 25 * 2, 25 / 2f);
+        Mat noBlackBar = videoProcessToolNew.removeBlackBarAndRotate(filtered);
+        videoProcessToolNew.getKillNum(noBlackBar);
+    }
 }
 }