Browse Source

修改视频处理代码逻辑

syh 5 years ago
parent
commit
1fd3264de5

+ 6 - 1
jeecg-boot-module-system/pom.xml

@@ -169,11 +169,16 @@
             <artifactId>poi-ooxml</artifactId>
             <version>3.17</version>
         </dependency>-->
-        <dependency>
+        <!--<dependency>
             <groupId>com.test</groupId>
             <artifactId>opencv</artifactId>
             <scope>system</scope>
             <systemPath>${basedir}/docs/opencv-420.jar</systemPath>
+        </dependency>-->
+        <dependency>
+            <groupId>cn.com.ctop</groupId>
+            <artifactId>opencv</artifactId>
+            <version>4.2.0</version>
         </dependency>
     </dependencies>
 

+ 100 - 7
jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/opencv/CornerCheck.java

@@ -1,26 +1,119 @@
 package org.jeecg.modules.demo.opencv;
 
+import cn.com.ctop.common.module.utils.ResultMapUtils;
+import cn.com.ctop.common.module.utils.StatusCode;
 import org.opencv.core.*;
 import org.opencv.imgcodecs.Imgcodecs;
 import org.opencv.imgproc.Imgproc;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
 
 /**
  * 角点检测
  */
+
 public class CornerCheck {
     static {
         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
     }
 
-    private static int EXPAND_SIZE = 0;
+    private static int EXPAND_SIZE = 3;
     public static void main(String[] args) {
-        detectConerList("D:\\data\\images\\233.jpg");
-//        channelSplit();
+//        harris();
+//        detectConers();
+        channelSplit();
+    }
+
+    public static Map<String, Object> detectConers() {
+        Map<String, Object> result = new HashMap<>();
+        try {
+            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+            final int maxCorners = 50, blockSize = 3;
+            final double qualityLevel = 0.01, minDistance = 20.0, k = 0.04;
+            final boolean useHarrisDetector = false;
+            MatOfPoint corners = new MatOfPoint();
+
+            Mat src = Imgcodecs.imread("D:\\data\\235.jpg");
+            if (src.empty()) {
+                throw new Exception("no file");
+            }
+            Mat dst = src.clone();
+            Mat gray = new Mat();
+            //灰度
+            Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGB2GRAY);
+            Imgcodecs.imwrite("D:\\data\\gray.jpg", gray);
+            Mat binary = new Mat();
+            //二值化
+            Imgproc.threshold(gray, binary, 1, 255, Imgproc.THRESH_TOZERO);
+            Imgcodecs.imwrite("D:\\data\\binary.jpg", binary);
+            Imgproc.goodFeaturesToTrack(binary, corners, maxCorners, qualityLevel, minDistance,
+                    new Mat(), blockSize, useHarrisDetector, k);
+            Point[] pCorners = corners.toArray();
+            List<Point> pointList = new ArrayList<>();
+            double maxX = 0d;
+            double maxY = 0d;
+            double minX = 10000d;
+            double minY = 100000d;
+            for (int i = 0; i < pCorners.length; i++) {
+                Imgproc.circle(dst, pCorners[i], 4, new Scalar(0, 0, 0), Imgproc.FILLED);
+                if (pCorners[i].x > 130 && pCorners[i].x < 570 && pCorners[i].y > 200 && pCorners[i].y < 850) {
+                    if (pCorners[i].x >= maxX) {
+                        maxX = pCorners[i].x;
+                    }
+                    if (pCorners[i].y >= maxY) {
+                        maxY = pCorners[i].y;
+                    }
+
+                    if (pCorners[i].x <= minX) {
+                        minX = pCorners[i].x;
+                    }
+
+                    if (pCorners[i].y <= minY) {
+                        minY = pCorners[i].y;
+                    }
+                    pointList.add(pCorners[i]);
+                }
+            }
+            Imgcodecs.imwrite("D:\\data\\allConers.jpg", dst);
+            List<Point> cornerPoints = new ArrayList<>();
+            for (Point point : pointList) {
+                double getX = point.x;
+                double getY = point.y;
+                if ((getY >= (minY + 20) && getY <= (maxY - 20))) {
+                    Imgproc.circle(dst, point, 4, new Scalar(255, 255, 255), Imgproc.FILLED);
+                } else {
+                    cornerPoints.add(point);
+                    Imgproc.circle(dst, point, 4, new Scalar(0, 0, 0), Imgproc.FILLED);
+                }
+            }
+//            {139.0, 240.0} 左上 {144.0, 837.0} 左下
+//            {482.0, 238.0} 右上 {532.0, 825.0} 右下
+            Collections.sort(cornerPoints, new Comparator<Point>() {
+                @Override
+                public int compare(Point p1, Point p2) {
+                    return (int) (p1.x + p1.y - p2.x - p2.y);
+                }
+            });
+            Imgcodecs.imwrite("D:\\data\\coners.jpg", dst);
+            for (Point p : cornerPoints) {
+            }
+            result.put("leftTop", cornerPoints.get(0));
+            result.put("rightBottom", cornerPoints.get(3));
+            if (cornerPoints.get(2).y > cornerPoints.get(1).y) {
+                result.put("rightTop", cornerPoints.get(1));
+                result.put("leftBottom", cornerPoints.get(2));
+            } else {
+                result.put("rightTop", cornerPoints.get(2));
+                result.put("leftBottom", cornerPoints.get(1));
+            }
+            ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
+            return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+            ResultMapUtils.setResultMap(result, StatusCode.COMMON_SERVER_ERROR);
+            return result;
+        }
     }
 
     public static List<Point> matCornerList(List<Point> points) {

+ 142 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/opencv/FFmpegUtils.java

@@ -0,0 +1,142 @@
+package org.jeecg.modules.demo.opencv;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+public class FFmpegUtils {
+    public static void videoToPcm(String vedioUrl, String m4aUrl, String ffmpegUrl) throws InterruptedException, IOException {
+        List<String> commend = new ArrayList<String>();
+        commend.add(ffmpegUrl);
+        commend.add("-i");
+        commend.add(vedioUrl);
+        commend.add("-vn");
+        commend.add("y");
+        commend.add("-acodec");
+        commend.add("copy");
+        commend.add(m4aUrl);
+        ProcessBuilder builder = new ProcessBuilder();
+        builder.command(commend);
+        builder.redirectErrorStream(true);
+        Process process = builder.start();
+        process.waitFor();// 等待进程执行结束
+    }
+
+    public static void mergeVideodioAndPcm(String videoInputPath, String audioInputPath, String videoOutPath, String ffmpegUrl) throws InterruptedException, IOException {
+        /**
+         *  String command = FFMPEG_PATH + " -i " + videoInputPath + " -i " + audioInputPath
+         *   + " -c:v copy -c:a aac -strict experimental " +
+         *   " -map 0:v:0 -map 1:a:0 "
+         *   + " -y " + videoOutPath;
+         */
+        List<String> commend = new ArrayList<String>();
+        commend.add(ffmpegUrl);
+        commend.add("-i");
+        commend.add(videoInputPath);
+        commend.add("-i");
+        commend.add(audioInputPath);
+        commend.add(" -c:v");
+        commend.add("copy");
+        commend.add("-c:a");
+        commend.add("acc");
+        commend.add("-strict");
+        commend.add("experimental");
+        commend.add(videoOutPath);
+        ProcessBuilder builder = new ProcessBuilder();
+        builder.command(commend);
+        builder.redirectErrorStream(true);
+        Process process = builder.start();
+        process.waitFor();// 等待进程执行结束
+    }
+
+    public static void main(String[] args) throws InterruptedException, IOException {
+//        videoToPcm("D:\\data\\fill.mp4","D:\\data\\fill.m4a","D:\\java\\ffmpeg\\bin\\ffmpeg.exe");
+//        mergeVideodioAndPcm("D:\\data\\merge.mp4","D:\\data\\fill.m4a","D:\\data\\fill2.mp4","D:\\java\\ffmpeg\\bin\\ffmpeg.exe");
+        try {
+            videoToAudio("D:\\data\\test\\fill.mp4", "D:\\data\\test\\123.mp3");
+            String videoInputPath = "D:\\data\\test\\merge.mp4";
+            String audioInputPath = "D:\\data\\test\\123.mp3";
+            String videoOutPath = "D:\\data\\test\\fill.mp4";
+            convetor(videoInputPath, audioInputPath, videoOutPath);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        System.out.println("---------获取音频文件成功!-----------");
+    }
+
+    /**
+     * @param videoInputPath 原视频的全路径
+     * @param audioInputPath 音频的全路径
+     * @param videoOutPath   视频与音频结合之后的视频的路径
+     * @throws Exception
+     */
+    public static void convetor(String videoInputPath, String audioInputPath, String videoOutPath)
+            throws Exception {
+        Process process = null;
+        try {
+            String command = FFMPEG_PATH + " -i " + videoInputPath + " -i " + audioInputPath + " -c:v copy -c:a aac -strict experimental " +
+                    " -map 0:v:0 -map 1:a:0 "
+                    + " -y " + videoOutPath;
+            System.out.println(command);
+            process = Runtime.getRuntime().exec(command);
+            process.waitFor();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源,所以这里我们需要对流进行处理
+        InputStream errorStream = process.getErrorStream();
+        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
+        BufferedReader br = new BufferedReader(inputStreamReader);
+
+        String line = "";
+        while ((line = br.readLine()) != null) {
+        }
+        if (br != null) {
+            br.close();
+        }
+        if (inputStreamReader != null) {
+            inputStreamReader.close();
+        }
+        if (errorStream != null) {
+            errorStream.close();
+        }
+
+    }
+
+    /**
+     * 从视频中提取音频信息
+     *
+     * @param videoUrl
+     * @return
+     */
+    public static String videoToAudio(String videoUrl, String accFile) {
+        String aacFile = "";
+        try {
+            aacFile = TMP_PATH + "/" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
+                    + UUID.randomUUID().toString().replaceAll("-", "") + ".mp3";
+            String command = FFMPEG_PATH + " -i " + videoUrl + " -vn -acodec copy " + aacFile;
+            System.out.println("video to audio command : " + command);
+            Process process = Runtime.getRuntime().exec(command);
+            process.waitFor();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    /**
+     * FFmpeg全路径
+     */
+    private static final String FFMPEG_PATH = "D:\\java\\ffmpeg\\bin\\ffmpeg.exe";
+    /**
+     * 音频保存路径
+     */
+    private static final String TMP_PATH = "D:\\data\\test";
+}

+ 2 - 2
jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/opencv/Perspective.java

@@ -11,11 +11,11 @@ import java.util.List;
 /**
  * 透视变换
  */
+
 public class Perspective {
     public static void main(String[] args) {
-        perpectiveImg("D:\\data\\images\\163.jpg", "D:\\data\\fill\\1.jpg", "D:\\data\\video\\163.jpg");
-    }
 
+    }
 
     public static void perpectiveImg(String backgroundImgPath, String phoneImgPath, String targetFileName) {
         try {

+ 10 - 5
jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/opencv/Test.java

@@ -7,7 +7,7 @@ import org.opencv.imgcodecs.Imgcodecs;
 import org.opencv.imgproc.Imgproc;
 
 public class Test {
-    public static void main(String[] args) {
+    public static void initVideo() {
         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
         String srcPath = "D:\\data\\images\\";
         String fillPath = "D:\\data\\fill\\";
@@ -19,10 +19,10 @@ public class Test {
         int srcPhoneFrameNumFrom = 163;
         int changeSenceFrameNumFrom = 234;
         //2.1 复制原始视频无变化图片
-//        for(int i=1;i<srcPhoneFrameNumFrom;i++){
-//            Mat srcNoChangeImage = Imgcodecs.imread(srcPath+i+".jpg");
-//            Imgcodecs.imwrite(targetPath+i+".jpg",srcNoChangeImage);
-//        }
+        for (int i = 1; i < srcPhoneFrameNumFrom; i++) {
+            Mat srcNoChangeImage = Imgcodecs.imread(srcPath + i + ".jpg");
+            Imgcodecs.imwrite(targetPath + i + ".jpg", srcNoChangeImage);
+        }
         String getImageName = "";
         //2.2 填充手机内部图片画面
         for (int i = 163; i < changeSenceFrameNumFrom; i++) {
@@ -69,4 +69,9 @@ public class Test {
 //        }
     }
 
+
+    public static void main(String[] args) {
+        initVideo();
+    }
+
 }

+ 4 - 8
jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/opencv/VideoProcessing.java

@@ -33,10 +33,8 @@ public class VideoProcessing {
         //标识
         int flag = 0;
         try {
-			 /*
-            获取视频文件
-            */
-            FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(videoFileName);
+            /*获取视频文件*/
+            FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(videoPath + "/" + videoFileName);
             fFmpegFrameGrabber.start();
 
             //获取视频总帧数
@@ -45,12 +43,10 @@ public class VideoProcessing {
 
             while (flag <= ftp) {
                 frame = fFmpegFrameGrabber.grabImage();
-				/*
-				对视频的第五帧进行处理
-				 */
+                /*对视频的第五帧进行处理*/
                 if (frame != null) {
                     //文件绝对路径+名字
-                    String fileName = filePackageName + String.valueOf(flag) + ".jpg";
+                    String fileName = videoFramesPath + String.valueOf(flag) + ".jpg";
 
                     //文件储存对象
                     File outPut = new File(fileName);