一、利用子矩阵修剪图像

通过submat来截取我们想要的那部分内容,主要目标是介绍submat函数。submat的返回值是一个矩阵对象,内容是原图的子矩阵或子区域。我们使用imread来读取图片文件,然后通过submat来截取我们想要的那部分内容。

1. 读取图片,获取图像的原始信息。代码示例:

@Test
    public void test08() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // IMREAD_GRAYSCALE:加载灰度图像
        Mat mat = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\888.png");
        if (mat.empty()){
            throw new Exception("image is empty!");
        }

        out.println(mat);

        imshow("Original Image", mat);
        waitKey();
    }

Java advance imaging 抠图 java抠图算法的实现_Image

根据输出信息, println输出了矩阵对象本身的一些信息。它的大部分信息与内存有关,所以你可以直接访问内存,同时它也显示了这个矩阵对象是否是一个子矩阵。在这个例子中,由于这个矩阵对象是原始图片,所以它的isSubmat值是false。

Mat [ 675*900*CV_8UC3, isCont=true, isSubmat=false, nativeObj=0x1103ab0, dataAddr=0x1d34a080 ]

2. 现在我们使用submat函数,输入参数是每一行和每一列的起始和终止值。,代码实现:

@Test
    public void test08() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // IMREAD_GRAYSCALE:加载灰度图像
        Mat mat = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\1000.jpg");
        if (mat.empty()) {
            throw new Exception("image is empty!");
        }
        out.println("submat Image before:" + mat);
        // 一行的 起始和终止值,一列的起始和终止值;
        Mat submat = mat.submat(440, 540, 300, 450);
        out.println("submat Image after:" + submat);
        imshow("submat Image after:", submat);
        waitKey();
    }

打印的信息:

 

submat Image before:Mat [ 675*900*CV_8UC3, isCont=true, isSubmat=false, nativeObj=0xa1b280, dataAddr=0x20ce9080 ]
submat Image after:Mat [ 100*150*CV_8UC3, isCont=false, isSubmat=true, nativeObj=0xa1b7c0, dataAddr=0x20e0b4a4 ]

处理后的图片: 

Java advance imaging 抠图 java抠图算法的实现_Image_02

二、图片模糊处理

blur是org.opencv.imgproc.Imgproc类中的一个核心函数,它的输入参数是size对象,用来指明每个像素模糊区域大小,size越大,模糊的效果也越强。

1. 实现对整张图片的模糊处理。代码实现:

@Test
    public void test10() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // 读取图像到矩阵中
        Mat src = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\1000.jpg");
        if (src.empty()) {
            throw new Exception("image is empty!");
        }

        //复制矩阵进入dst
        Mat dst = src.clone();
        // 图像模糊化处理
        Imgproc.blur(src,dst,new Size(25,25));
        out.println("submat Image after:" + dst);
        imshow("submat Image after:", dst);
        waitKey();
    }

效果图:

Java advance imaging 抠图 java抠图算法的实现_opencv_03

2. 通过 submat  指定模糊区域并对局部进行模糊处理,代码实现:

@Test
    public void test10() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // 读取图像到矩阵中
        Mat mat = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\1000.jpg");
        if (mat.empty()) {
            throw new Exception("image is empty!");
        }
        // 一列的起始和终止值,一行的 起始和终止值;
        Mat submatSrc = mat.submat(240, 440, 400, 650);
        // 图像模糊化处理
        Imgproc.blur(submatSrc,submatSrc,new Size(55,55));
        out.println("submat Image after:" + submatSrc);
        imshow("submat Image after:", mat);
        waitKey();
    }

Java advance imaging 抠图 java抠图算法的实现_计算机视觉_04

三、获取子矩阵方法

除了 submat函数的定义外,还有两种方法可以获得子矩阵。

1. 一种是采用两个Range参数,第一个代表行(y或高度)的范围,第二个代表列(x或宽度)的范围,都是使用Range类来创建的。

Mat dst = src.submat(new Range(240,440),new Range(440,640));

 该方式的代码实现 和方式二实现一样,不在赘述。

2. 另一种方法是使用 Rect 对象的矩形,首先给出左上角的坐标,然后是矩形的大小。

// 第一个参数:行,第二个参数:列
        Mat dst = src.submat(new Rect(450,190,250,250));

第二种方法比较常用,代码实现:

@Test
    public void test12() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // 读取图像到矩阵中
        Mat src = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\1000.jpg");
        if (src.empty()) {
            throw new Exception("image is empty!");
        }

        //复制矩阵进入dst
        // 第一个参数:行,第二个参数:列
        Mat dst = src.submat(new Rect(450,190,250,250));
        // 图像模糊化处理
        Imgproc.blur(dst,dst,new Size(25,25));
        out.println("submat Image after:" + dst);
        imwrite("D:\\ProgramFiles\\personDocument\\picture\\1002.jpg", src);
        imshow("submat Image after:", src);
        waitKey();
    }

效果图如下:

Java advance imaging 抠图 java抠图算法的实现_Image_05

四、通过 Mat 的 setTo() 方法 处理图片


1. 通过 new Scalar() 获取不同的颜色,再通过  Mat 的 setTo()方法设置图片的颜色。代码实现:


@Test
    public void test13() throws Exception {
        URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
        System.load(url.getPath());

        // 读取图像到矩阵中
        Mat src = Imgcodecs.imread("D:\\ProgramFiles\\personDocument\\picture\\1.jpg");
        if (src.empty()) {
            throw new Exception("image is empty!");
        }

        //复制矩阵进入dst
        // 第一个参数:行,第二个参数:列
        Mat dst = src.submat(new Rect(300,900,850,450));
        // 图像模糊化处理
//        Imgproc.blur(dst,dst,new Size(75,75));
        
        dst.setTo(new Scalar(255,0,0));
        out.println("submat Image after:" + dst);
        imwrite("D:\\ProgramFiles\\personDocument\\picture\\2.jpg", src);
        imshow("submat Image after:", src);
        waitKey();
    }

效果如下: 

 

Java advance imaging 抠图 java抠图算法的实现_图像处理_06

 

如有不当之处请多多指教,如对你有所帮助,请评论或点赞予以支持,谢谢!