瀏覽代碼

图像单通道拆解

syh 5 年之前
父節點
當前提交
33621d033b

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

@@ -0,0 +1,282 @@
+package org.jeecg.modules.demo.opencv;
+
+public class Avutils {
+    /**
+     * 平面YUV 4:2:0,12bpp,(1 Cr&每2×2个样本的Cb样本)
+     **/
+    public static int AV_PIX_FMT_YUV420P = 0;
+    /**
+     * 打包YUV 4:2:2,16bpp,Y0 Cb Y1 Cr
+     */
+    public static int AV_PIX_FMT_YUYV422 = 1;
+    /**
+     * 打包RGB 8:8:8,24bpp,RGBRGB ...
+     */
+    public static int AV_PIX_FMT_RGB24 = 2;
+    /**
+     * 打包RGB 8:8:8,24bpp,BGRBGR ...
+     */
+    public static int AV_PIX_FMT_BGR24 = 3;
+    /**
+     * 平面YUV 4:2:2,16bpp,(每2×1个样本1 Cr& Cb样本)
+     */
+    public static int AV_PIX_FMT_YUV422P = 4;
+    /**
+     * 平面YUV 4:4:4,24bpp,(每1×1个样本1个Cr& Cb样本)
+     */
+    public static int AV_PIX_FMT_YUV444P = 5;
+    /**
+     * 平面YUV 4:1 :0,9bpp,(每4x4Y样品1 Cr& Cb样品)
+     */
+    public static int AV_PIX_FMT_YUV410P = 6;
+    /**
+     * 平面YUV 4:1:1,12bpp,(1 Cr& Cb每4x1 Y样本的样本)
+     **/
+    public static int AV_PIX_FMT_YUV411P = 7;
+    /**
+     * Y,8bpp
+     */
+    public static int AV_PIX_FMT_GRAY8 = 8;
+    /**
+     * Y,1bpp,0为白色,1是黑色的,每个字节的像素都是从msb到lsb的顺序
+     */
+    public static int AV_PIX_FMT_MONOWHITE = 9;
+    /**
+     * Y,1bpp,0为黑色,1为白色,每个字节中的像素从msb排序到lsb
+     */
+    public static int AV_PIX_FMT_MONOBLACK = 10;
+    /**
+     * 8使用PIX_FMT_RGB32调色板
+     */
+    public static int AV_PIX_FMT_PAL8 = 11;
+    /**
+     * 平面YUV 4:2:0,12bpp,满刻度(JPEG),弃用PIX_FMT_YUV420P并设置color_range
+     */
+    public static int AV_PIX_FMT_YUVJ420P = 12;
+    /**
+     * 平面YUV 4:2:2,16bpp,满量程(JPEG),弃用PIX_FMT_YUV422P并设置color_range
+     */
+    public static int AV_PIX_FMT_YUVJ422P = 13;
+    /**
+     * 平面YUV 4:4:4,24bpp,满量程(JPEG),不利于PIX_FMT_YUV444P并设置color_range
+     */
+    public static int AV_PIX_FMT_YUVJ444P = 14;
+    /**
+     * 通过公共数据包的XVideo运动加速通过
+     */
+    public static int AV_PIX_FMT_XVMC_MPEG2_MC = 15;
+    public static int AV_PIX_FMT_XVMC_MPEG2_IDCT = 16;
+    /**
+     * 打包YUV 4:2:2,16bpp,Cb Y0 Cr Y1
+     */
+    public static int AV_PIX_FMT_UYVY422 = 17;
+    /**
+     * 打包YUV 4:1:1,12bpp,Cb Y0 Y1 Cr Y2 Y3
+     */
+    public static int AV_PIX_FMT_UYYVYY411 = 18;
+    /**
+     * 打包RGB 3:3:2,8bpp,(msb)2B 3G 3R(lsb)
+     */
+    public static int AV_PIX_FMT_BGR8 = 19;
+    /**
+     * 打包RGB 1:2:1比特流,4bpp,(msb)1B 2G 1R(lsb),一个字节包含两个像素,字节中的第一个像素是4 msb位
+     */
+    public static int AV_PIX_FMT_BGR4 = 20;
+    /**
+     * 打包RGB 1:2:1,8bpp,(msb)1B 2G 1R(lsb)
+     */
+    public static int AV_PIX_FMT_BGR4_BYTE = 21;
+    /**
+     * 打包RGB 3:3:2,8bpp,(msb)2R 3G 3B(lsb)
+     */
+    public static int AV_PIX_FMT_RGB8 = 22;
+    /**
+     * 打包RGB 1:2:1比特流,4bpp,( msb)1R 2G 1B(lsb),
+     * 一个字节包含两个像素,字节中的第一个像素是由4 msb位组成的一个
+     */
+    public static int AV_PIX_FMT_RGB4 = 23;
+    /**
+     * 打包RGB 1 :2:1,8bpp,(msb)1R 2G 1B(lsb)
+     */
+    public static int AV_PIX_FMT_RGB4_BYTE = 24;
+    /**
+     * 平面YUV 4:2:0,12bpp,1和1个交织的平面(第一个字节U和随后的字节V)
+     */
+    public static int AV_PIX_FMT_NV12 = 25;
+    /**
+     * 如上所述,但U和V字节被交换
+     */
+    public static int AV_PIX_FMT_NV21 = 26;
+
+    /**
+     * 打包ARGB 8:8:8:8,32bpp,ARGBARGB ...
+     */
+    public static int AV_PIX_FMT_ARGB = 27;
+    /**
+     * 包装RGBA 8:8:8:8,3bpp,RGBARGBA ...
+     */
+    public static int AV_PIX_FMT_RGBA = 28;
+    /**
+     * 打包ABGR 8:8:8:8,332pp,ABGRABGR .. 。
+     */
+    public static int AV_PIX_FMT_ABGR = 29;
+    /**
+     * 包装BGRA 8:8:8:8,32bpp,BGRABGRA ...
+     */
+    public static int AV_PIX_FMT_BGRA = 30;
+
+    /**
+     * Y,16bpp,big-endian
+     */
+    public static int AV_PIX_FMT_GRAY16BE = 31;
+    /**
+     * Y,16bpp,little-endian
+     */
+    public static int AV_PIX_FMT_GRAY16LE = 32;
+    /**
+     * 平面YUV 4:4:0(1 Cr&每个1x2 Y样本的Cb样本)
+     */
+    public static int AV_PIX_FMT_YUV440P = 33;
+    /**
+     * 平面YUV 4:4:0满量程(JPEG),弃用PIX_FMT_YUV440P并设置color_range
+     */
+    public static int AV_PIX_FMT_YUVJ440P = 34;
+    /**
+     * 平面YUV 4:2:0,20bpp,(每2X& A样本1 Cr& Cb样本)
+     */
+    public static int AV_PIX_FMT_YUVA420P = 35;
+    /**
+     * 使用VDPAU的H.264硬件解码,数据[0]包含一个vdpau_render_state结构,
+     * 其中包含片段的比特流以及从头部提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_H264 = 36;
+    /**
+     * 使用VDPAU的MPEG-1硬件解码,数据[0]包含一个vdpau_render_state结构,
+     * 其中包含片段的比特流以及从标题中提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_MPEG1 = 37;
+    /**
+     * 使用VDPAU的MPEG-2硬件解码,数据[0]包含一个vdpau_render_state结构,
+     * 其中包含片段的比特流以及从头部提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_MPEG2 = 38;
+    /**
+     * 使用VDPAU的WMV3硬件解码,数据[0]包含一个包含片段的比特流的vdpau_render_state结构以及从头提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_WMV3 = 39;
+    /**
+     * 使用VDPAU的VC-1 HW解码,数据[0]包含一个vdpau_render_state结构,
+     * 其中包含片段的比特流以及从标题中提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_VC1 = 40;
+    /**
+     * 打包RGB 16:16:16,48bpp,16R,16G,16B,每个R / G / B组件的2字节值存储为big-endian
+     */
+    public static int AV_PIX_FMT_RGB48BE = 41;
+    /**
+     * 打包RGB 16:16:16,48bpp,16R,16G,16B,每个R / G / B组件的2字节值存储为小尾数
+     */
+    public static int AV_PIX_FMT_RGB48LE = 42;
+
+    /**
+     * 打包RGB 5:6:5,16bpp,(msb)5R 6G 5B(lsb),big-endian
+     */
+    public static int AV_PIX_FMT_RGB565BE = 43;
+    /**
+     * 包装RGB 5:6:5,16bpp,(msb)5R 6G 5B(lsb),little-endian
+     */
+    public static int AV_PIX_FMT_RGB565LE = 44;
+    /**
+     * 打包RGB 5:5:5,16bpp,(msb)1A 5R 5G 5B(lsb),大端,最高有效位为0
+     */
+    public static int AV_PIX_FMT_RGB555BE = 45;
+    /**
+     * 包装RGB 5:5:5,16bpp,(msb)1A 5R 5G 5B(lsb),小端,最高有效位为0
+     */
+    public static int AV_PIX_FMT_RGB555LE = 46;
+
+    /**
+     * 包装BGR 5:6:5,16bpp,(msb)5B 6G 5R(lsb),big-endian
+     */
+    public static int AV_PIX_FMT_BGR565BE = 47;
+    /**
+     * 打包BGR 5:6:5,16bpp ,(msb)5B 6G 5R(lsb),little-endian
+     */
+    public static int AV_PIX_FMT_BGR565LE = 48;
+    /**
+     * 打包BGR 5:5:5,16bpp,(msb)1A 5B 5G 5R(lsb ),big-endian,最高有效位到1
+     */
+    public static int AV_PIX_FMT_BGR555BE = 49;
+    /**
+     * 打包BGR 5:5:5,16bpp,(msb)1A 5B 5G 5R(lsb) -endian,最高有效位到1
+     */
+    public static int AV_PIX_FMT_BGR555LE = 50;
+
+    /**
+     * 通过VA API在运动补偿入口处的HW加速,Picture.
+     * data [3]包含一个vaapi_render_state struct包含宏块以及从头文件提取的各种字段
+     */
+    public static int AV_PIX_FMT_VAAPI_MOCO = 51;
+    /**
+     * 通过IDC入口点的VA API加速硬件,Picture.data [3]包含一个vaapi_render_state结构,其中包含从头部提取的字段
+     */
+    public static int AV_PIX_FMT_VAAPI_IDCT = 52;
+    /**
+     * 通过VA API进行HW解码,Picture.data [3]包含一个vaapi_render_state结构,其中包含片段的比特流以及从标题中提取的各种字段
+     */
+    public static int AV_PIX_FMT_VAAPI_VLD = 53;
+
+    /**
+     * 平面YUV 4:2:0,24bpp,(1 Cr&每个2x2 Y样本的Cb样本),little-endian
+     */
+    public static int AV_PIX_FMT_YUV420P16LE = 54;
+    /**
+     * 平面YUV 4:2:0,248pp,(每2×2个样本1 Cr& Cb样本) ,big-endian
+     */
+    public static int AV_PIX_FMT_YUV420P16BE = 55;
+    /**
+     * 平面YUV 4:2:2,32bpp,(每2×1个样本1 Cr& Cb样本),little-endian
+     */
+    public static int AV_PIX_FMT_YUV422P16LE = 56;
+    /**
+     * 平面YUV 4:2:2,32bpp,(每2×1个样本1 Cr& Cb样本),big-endian
+     */
+    public static int AV_PIX_FMT_YUV422P16BE = 57;
+    /**
+     * 平面YUV 4:4:4,48bpp,(每1×1个样本1 Cr& Cb样本),小尾数
+     */
+    public static int AV_PIX_FMT_YUV444P16LE = 58;
+    /**
+     * 平面YUV 4:4:4,48bpp,(每1×1个样品1 Cr& Cb样品),big-endian
+     */
+    public static int AV_PIX_FMT_YUV444P16BE = 59;
+    /**
+     * 使用VDPAU的MPEG4硬件解码,数据[0]包含一个vdpau_render_state结构,其中包含片段的比特流以及从头部提取的各种字段
+     */
+    public static int AV_PIX_FMT_VDPAU_MPEG4 = 60;
+    /**
+     * 硬解码thr哦DXVA2,Picture.data [3]包含一个LPDIRECT3DSURFACE9指针
+     */
+    public static int AV_PIX_FMT_DXVA2_VLD = 61;
+
+    /**
+     * 打包RGB 4:4:4,16bpp,(msb)4A 4R 4G 4B(lsb),小端,最高有效位为0
+     */
+    public static int AV_PIX_FMT_RGB444LE = 62;
+    /**
+     * 打包RGB 4:4:4,16bpp,(msb)4A 4R 4G 4B(lsb ),big-endian,最高有效位为0
+     */
+    public static int AV_PIX_FMT_RGB444BE = 63;
+    /**
+     * 打包BGR 4:4:4,16bpp,(msb)4A 4B 4G 4R(lsb) -endian,最高有效位为1
+     */
+    public static int AV_PIX_FMT_BGR444LE = 64;
+    /**
+     * 打包BGR 4:4:4,16bpp,(msb)4A 4B 4G 4R(lsb),big-endian,最高有效位为1
+     */
+    public static int AV_PIX_FMT_BGR444BE = 65;
+    /**
+     * 8位灰色,8位alpha
+     */
+    public static int AV_PIX_FMT_YA8 = 66;
+}

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

@@ -1,12 +1,13 @@
 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.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 /**
  * 角点检测
@@ -16,153 +17,12 @@ public class CornerCheck {
         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
     }
 
-    private static int EXPAND_SIZE = 3;
+    private static int EXPAND_SIZE = 0;
     public static void main(String[] args) {
-//        harris();
-        detectConers();
+        detectConerList("D:\\data\\images\\233.jpg");
 //        channelSplit();
     }
 
-    public static void channelSplit() {
-        Mat srcImage = Imgcodecs.imread("D:\\data\\235.jpg", Imgcodecs.IMREAD_COLOR);
-        List<Mat> channels = new ArrayList<>();
-        Core.split(srcImage, channels);
-
-        //创建类型为Mat,数组长度为3的变量mbgr
-        List<Mat> mbgr = new ArrayList<>();
-        Mat hideChannel = new Mat(srcImage.size(), CvType.CV_8UC1, new Scalar(0));
-
-        Mat imageB = new Mat(srcImage.size(), CvType.CV_8UC3);
-        mbgr.add(channels.get(0));
-        mbgr.add(hideChannel);
-        mbgr.add(hideChannel);
-        Core.merge(mbgr, imageB);
-        Imgcodecs.imwrite("D:\\data\\imageB.jpg", imageB);
-
-    }
-
-    public static Map<String, Object> detectConers() {
-        Map<String, Object> result = new HashMap<>();
-        try {
-            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
-            Mat src = Imgcodecs.imread("D:\\data\\images\\163.jpg");
-            if (src.empty()) {
-                throw new Exception("no file");
-            }
-            for (int i = 0; i < src.cols(); i++) {
-                for (int j = 0; j < src.rows(); j++) {
-                    if (i > 160 && i < 470 && j > 250 && j < 750) {
-                        Imgproc.circle(src, new Point(i, j), 1, new Scalar(0, 236, 2), Imgproc.FILLED);
-                    }
-                }
-            }
-            final int maxCorners = 100, blockSize = 5;
-            final double qualityLevel = 0.04, minDistance = 20.0, k = 0.04;
-            final boolean useHarrisDetector = false;
-            MatOfPoint corners = new MatOfPoint();
-            //卷积
-            Mat kernel = new Mat(3, 3, CvType.CV_16SC1);
-            kernel.put(0, 0, 0, -1, 0, -1, 5, -1, 0, -1, 0);
-            Imgproc.filter2D(src, src, src.depth(), kernel);
-            //降噪
-            Imgproc.GaussianBlur(src, src, new Size(3, 3), 0, 0, 1);
-            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);
-            //归一处理
-//            Core.normalize(gray,gray);
-            //Sobel算子
-            Mat grad_x = new Mat(), grad_y = new Mat();
-            Mat abs_grad_x = new Mat(), abs_grad_y = new Mat();
-            int scale = 1;
-            int delta = 0;
-            //Gradient X
-            Imgproc.Sobel(gray, grad_x, CvType.CV_16S, 1, 0, 3, scale, delta, 1);
-            //Gradient y
-            Imgproc.Sobel(gray, grad_y, CvType.CV_16S, 0, 1, 3, scale, delta, 1);
-
-            Core.convertScaleAbs(grad_x, abs_grad_x);
-            Core.convertScaleAbs(grad_y, abs_grad_y);
-
-            /// Total Gradient (approximate)
-            Mat grad = new Mat();
-            Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
-            Imgcodecs.imwrite("D:\\data\\shark.jpg", grad);
-            Imgproc.goodFeaturesToTrack(grad, 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(255, 0, 255), 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) {
-                System.out.println(p.toString());
-            }
-            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);
-            System.out.println(result.toString());
-            return result;
-        } catch (Exception e) {
-            e.printStackTrace();
-            ResultMapUtils.setResultMap(result, StatusCode.COMMON_SERVER_ERROR);
-            return result;
-        }
-    }
-
     public static List<Point> matCornerList(List<Point> points) {
         List<Point> matCornerList = new ArrayList<>();
         matCornerList.add(points.get(0));
@@ -176,13 +36,15 @@ public class CornerCheck {
         List<Point> result = new ArrayList<>();
         try {
             System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
-
-            final int maxCorners = 50, blockSize = 5;
-            final double qualityLevel = 0.04, minDistance = 10.0, k = 0.04;
+            Mat src = Imgcodecs.imread(filePath);
+            if (src.empty()) {
+                throw new Exception("no file");
+            }
+            final int maxCorners = 1000, blockSize = 5;
+            final double qualityLevel = 0.05, minDistance = 10.0, k = 0.04;
             final boolean useHarrisDetector = false;
             MatOfPoint corners = new MatOfPoint();
 
-            Mat src = Imgcodecs.imread(filePath);
             for (int i = 0; i < src.cols(); i++) {
                 for (int j = 0; j < src.rows(); j++) {
                     if (i > 160 && i < 470 && j > 250 && j < 750) {
@@ -190,39 +52,36 @@ public class CornerCheck {
                     }
                 }
             }
-            //卷积
-            Mat kernel = new Mat(3, 3, CvType.CV_16SC1);
-            kernel.put(0, 0, 0, -1, 0, -1, 5, -1, 0, -1, 0);
-            Imgproc.filter2D(src, src, src.depth(), kernel);
-            //降噪
-            Imgproc.GaussianBlur(src, src, new Size(3, 3), 0, 0, 1);
-            if (src.empty()) {
-                throw new Exception("no file");
-            }
+//            //卷积
+//            Mat kernel = new Mat(3, 3, CvType.CV_16SC1);
+//            kernel.put(0, 0, 0, -1, 0, -1, 5, -1, 0, -1, 0);
+//            Imgproc.filter2D(src, src, src.depth(), kernel);
+//            //降噪
+//            Imgproc.GaussianBlur(src, src, new Size(3, 3), 0, 0, 1);
             Mat dst = src.clone();
             Mat gray = new Mat();
             //灰度
             Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGB2GRAY);
-            //归一处理
+//            //归一处理
 //            Core.normalize(gray,gray);
             //Sobel算子
-            Mat grad_x = new Mat(), grad_y = new Mat();
-            Mat abs_grad_x = new Mat(), abs_grad_y = new Mat();
-            int scale = 1;
-            int delta = 0;
-            //Gradient X
-            Imgproc.Sobel(gray, grad_x, CvType.CV_16S, 1, 0, 3, scale, delta, 1);
-            //Gradient y
-            Imgproc.Sobel(gray, grad_y, CvType.CV_16S, 0, 1, 3, scale, delta, 1);
-
-            Core.convertScaleAbs(grad_x, abs_grad_x);
-            Core.convertScaleAbs(grad_y, abs_grad_y);
+//            Mat grad_x = new Mat(), grad_y = new Mat();
+//            Mat abs_grad_x = new Mat(), abs_grad_y = new Mat();
+//            int scale = 1;
+//            int delta = 0;
+//            //Gradient X
+//            Imgproc.Sobel(gray, grad_x, CvType.CV_16S, 1, 0, 3, scale, delta, 1);
+//            //Gradient y
+//            Imgproc.Sobel(gray, grad_y, CvType.CV_16S, 0, 1, 3, scale, delta, 1);
+//
+//            Core.convertScaleAbs(grad_x, abs_grad_x);
+//            Core.convertScaleAbs(grad_y, abs_grad_y);
+//
+//            /// Total Gradient (approximate)
+//            Mat grad = new Mat();
+//            Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
 
-            /// Total Gradient (approximate)
-            Mat grad = new Mat();
-            Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
-            Imgproc.goodFeaturesToTrack(grad, corners, maxCorners, qualityLevel, minDistance, new Mat(), blockSize, useHarrisDetector, k);
-//            Imgproc.goodFeaturesToTrack(gray, corners, maxCorners,qualityLevel,minDistance,new Mat(), blockSize, useHarrisDetector, k);
+            Imgproc.goodFeaturesToTrack(gray, corners, maxCorners, qualityLevel, minDistance, new Mat(), blockSize, useHarrisDetector, k);
             Point[] pCorners = corners.toArray();
             List<Point> pointList = new ArrayList<>();
             double maxX = 0d;
@@ -230,7 +89,8 @@ public class CornerCheck {
             double minX = 10000d;
             double minY = 100000d;
             for (int i = 0; i < pCorners.length; i++) {
-                if (pCorners[i].x > 130 && pCorners[i].x < 570 && pCorners[i].y > 200 && pCorners[i].y < 850) {
+//                Imgproc.circle(dst, pCorners[i], 4, new Scalar(255, 0, 255), Imgproc.FILLED);
+                if (pCorners[i].x > 120 && pCorners[i].x < 555 && pCorners[i].y > 200 && pCorners[i].y < 860) {
                     if (pCorners[i].x >= maxX) {
                         maxX = pCorners[i].x;
                     }
@@ -248,17 +108,62 @@ public class CornerCheck {
                     pointList.add(pCorners[i]);
                 }
             }
+            Imgproc.line(dst, new Point(minX, minY), new Point(minX, maxY), new Scalar(255, 255, 255));
+            Imgproc.line(dst, new Point(minX, maxY), new Point(maxX, maxY), new Scalar(255, 255, 255));
+            Imgproc.line(dst, new Point(maxX, maxY), new Point(maxX, minY), new Scalar(255, 255, 255));
+            Imgproc.line(dst, new Point(maxX, minY), new Point(minX, minY), new Scalar(255, 255, 255));
             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, 10, new Scalar(0, 255, 255), Imgproc.FILLED);
+                if ((getY >= (minY + 50) && getY <= (maxY - 50)) || (getX >= (minX + 25) && getX <= (maxX - 70))) {
+                    Imgproc.circle(dst, point, 4, new Scalar(0, 255, 0), Imgproc.FILLED);
                 } else {
+                    Imgproc.circle(dst, point, 4, new Scalar(255, 0, 255), Imgproc.FILLED);
                     cornerPoints.add(point);
-//                    Imgproc.circle(dst, point, 10, new Scalar(0, 255, 255), Imgproc.FILLED);
                 }
             }
+            Point[] cornerArray = new Point[cornerPoints.size()];
+
+            for (int i = 0; i < cornerPoints.size(); i++) {
+                cornerArray[i] = cornerPoints.get(i);
+            }
+            /*MatOfPoint2f srcPoint = new MatOfPoint2f(cornerArray);
+            MatOfPoint2f destPoint = new MatOfPoint2f();
+            Imgproc.approxPolyDP(srcPoint,destPoint,100,true);
+            Point []des = destPoint.toArray();
+            for (int i=0;i<des.length-2;i++) {
+                Imgproc.line(dst,des[i],des[i+1],new Scalar(255,255,255));
+            }*/
+            Collections.sort(cornerPoints, new Comparator<Point>() {
+                @Override
+                public int compare(Point p1, Point p2) {
+                    return (int) (p1.x + p1.y - p2.x - p2.y);
+                }
+            });
+            List<Mat> channels = new ArrayList<>();
+            Core.split(src, channels);
+            List<Mat> mbgr = new ArrayList<>();
+            Mat hideChannel = new Mat(src.size(), CvType.CV_8UC1, new Scalar(0));
+            Mat imageGR = new Mat(src.size(), CvType.CV_8UC3);
+            mbgr = new ArrayList<>();
+            mbgr.add(hideChannel);
+            mbgr.add(channels.get(1));
+            mbgr.add(channels.get(2));
+            Core.merge(mbgr, imageGR);
+            List<Point> checkPoints = new ArrayList<>();
+            Point rightDown = cornerPoints.get(cornerPoints.size() - 1);
+            for (Point point : cornerPoints) {
+                System.out.println("cornerPoint:" + point.toString());
+                System.out.println(imageGR.get((int) point.y, (int) point.x)[1]);
+                if (imageGR.get((int) point.y, (int) point.x)[1] >= 120) {
+                    if (point.x <= rightDown.x) {
+                        System.out.println("greenPoint:" + point.toString());
+                        checkPoints.add(point);
+                    }
+                }
+            }
+            cornerPoints = checkPoints;
             Collections.sort(cornerPoints, new Comparator<Point>() {
                 @Override
                 public int compare(Point p1, Point p2) {
@@ -279,12 +184,97 @@ public class CornerCheck {
                 result.add(new Point(cornerPoints.get(1).x - EXPAND_SIZE, cornerPoints.get(1).y + EXPAND_SIZE));
             }
             //右下
-            result.add(new Point(cornerPoints.get(3).x + EXPAND_SIZE, cornerPoints.get(3).y + EXPAND_SIZE));
-//            Imgcodecs.imwrite("d://data/111.jpg",dst);
+            result.add(new Point(cornerPoints.get(cornerPoints.size() - 1).x + EXPAND_SIZE, cornerPoints.get(cornerPoints.size() - 1).y + EXPAND_SIZE));
+
+            for (Point point : result) {
+                Imgproc.circle(dst, point, 10, new Scalar(255, 0, 255), Imgproc.FILLED);
+            }
+            Imgcodecs.imwrite("D:\\data\\allConers.jpg", dst);
             return result;
         } catch (Exception e) {
             e.printStackTrace();
             return result;
         }
     }
+
+    public static void channelSplit() {
+        Mat srcImage = Imgcodecs.imread("D:\\data\\163.jpg", Imgcodecs.IMREAD_COLOR);
+        List<Mat> channels = new ArrayList<>();
+        Core.split(srcImage, channels);
+
+        //创建类型为Mat,数组长度为3的变量mbgr
+        List<Mat> mbgr = new ArrayList<>();
+        Mat hideChannel = new Mat(srcImage.size(), CvType.CV_8UC1, new Scalar(0));
+
+        Mat imageB = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr.add(channels.get(0));
+        mbgr.add(hideChannel);
+        mbgr.add(hideChannel);
+        Core.merge(mbgr, imageB);
+        List<Point> points = detectConerList("D:\\data\\imageB.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageB, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageB.jpg", imageB);
+
+        mbgr = new ArrayList<>();
+        Mat imageG = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr.add(hideChannel);
+        mbgr.add(channels.get(1));
+        mbgr.add(hideChannel);
+        Core.merge(mbgr, imageG);
+        points = detectConerList("D:\\data\\imageG.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageG, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageG.jpg", imageG);
+
+        mbgr = new ArrayList<>();
+        Mat imageR = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr.add(hideChannel);
+        mbgr.add(hideChannel);
+        mbgr.add(channels.get(2));
+        Core.merge(mbgr, imageR);
+        points = detectConerList("D:\\data\\imageR.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageR, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageR.jpg", imageR);
+
+        mbgr = new ArrayList<>();
+        Mat imageBG = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr.add(channels.get(0));
+        mbgr.add(channels.get(1));
+        mbgr.add(hideChannel);
+        Core.merge(mbgr, imageBG);
+        points = detectConerList("D:\\data\\imageBG.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageBG, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageBG.jpg", imageBG);
+
+        Mat imageGR = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr = new ArrayList<>();
+        mbgr.add(hideChannel);
+        mbgr.add(channels.get(1));
+        mbgr.add(channels.get(2));
+        Core.merge(mbgr, imageGR);
+        points = detectConerList("D:\\data\\imageGR.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageGR, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageGR.jpg", imageGR);
+
+        mbgr = new ArrayList<>();
+        Mat imageBR = new Mat(srcImage.size(), CvType.CV_8UC3);
+        mbgr.add(channels.get(0));
+        mbgr.add(hideChannel);
+        mbgr.add(channels.get(2));
+        Core.merge(mbgr, imageBR);
+        points = detectConerList("D:\\data\\imageBR.jpg");
+        for (Point point : points) {
+            Imgproc.circle(imageBR, point, 5, new Scalar(0, 0, 0));
+        }
+        Imgcodecs.imwrite("D:\\data\\imageBR.jpg", imageBR);
+    }
 }

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

@@ -1,13 +1,15 @@
 package org.jeecg.modules.demo.opencv;
 
-import org.bytedeco.javacv.FFmpegFrameGrabber;
-import org.bytedeco.javacv.Frame;
-import org.bytedeco.javacv.Java2DFrameConverter;
+import org.bytedeco.javacpp.avcodec;
+import org.bytedeco.javacpp.opencv_core;
+import org.bytedeco.javacv.*;
 
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.File;
 
+import static org.bytedeco.javacpp.opencv_imgcodecs.cvLoadImage;
+
 /**
  * 视频截帧处理
  */
@@ -64,6 +66,31 @@ public class VideoProcessing {
         return videPicture;
     }
 
+    public static void videoMerge(String videoFileName, String imagePackage) throws FrameRecorder.Exception {
+        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFileName, 720, 1280);
+//
+        recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4); // 28
+//		recorder.setFormat("mp4");
+        //	recorder.setFormat("mov,mp4,m4a,3gp,3g2,mj2,h264,ogg,MPEG4");
+        recorder.setFrameRate(20);
+        recorder.setPixelFormat(Avutils.AV_PIX_FMT_YUV420P); // yuv420p
+        recorder.start();
+        //
+        OpenCVFrameConverter.ToIplImage conveter = new OpenCVFrameConverter.ToIplImage();
+        // 列出目录中所有的图片,都是jpg的,以1.jpg,2.jpg的方式,方便操作
+        File file = new File(imagePackage);
+        File[] flist = file.listFiles();
+        // 循环所有图片
+        for (int i = 1; i <= flist.length; i++) {
+            String fname = imagePackage + i + ".jpg";
+            opencv_core.IplImage image = cvLoadImage(fname); // 非常吃内存!!
+            recorder.record(conveter.convert(image));
+            // 释放内存? cvLoadImage(fname); // 非常吃内存!!
+            opencv_core.cvReleaseImage(image);
+        }
+        recorder.stop();
+        recorder.release();
+    }
 
     public static BufferedImage FrameToBufferedImage(Frame frame) {
         //创建BufferedImage对象
@@ -73,7 +100,10 @@ public class VideoProcessing {
     }
 
     public static void main(String[] args) {
-        String videoFileName = "test.mp4";
-//        grabberVideoFramer(videoFileName,fillPackageName);
+        try {
+            videoMerge("D:\\data\\merge.mp4", "D:\\data\\video\\");
+        } catch (FrameRecorder.Exception e) {
+            e.printStackTrace();
+        }
     }
 }