Java OpenCV 方框滤波 BoxFilter

函数原理

在原理上,和均值滤波一样,用一个内核和图像进行卷积:
在这里插入图片描述
其中:
在这里插入图片描述
可见,归一化了就是均值滤波;不归一化则可以计算每个像素邻域上的各种积分特性,方差、协方差,平方和等等。

函数说明

Imgproc.boxFilter(Mat src, Mat dst, int ddepth, Size ksize, Point anchor, boolean normalize, int borderType);
src : 图片
dst : 目标图
ddepth : 输出图像的深度。默认-1。针对不同的输入图像,输出目标图像有不同的深度,具体组合如下:

  • 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F
  • 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F
  • 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F
  • 若src.depth() = CV_64F, 取ddepth = -1/CV_64F

ksize : 内核大小 Size(Weight, Height)
anchor : 内核锚点。默认为Point(-1, -1)。Point(-1, -1)说明
normalize: 是否进行归一化。默认true
borderType : 边界填充方式。默认值填充方式BORDER_DEFAULT 边界填充说明

函数效果演示

	public static void main(String[] args) {

        //读入图片
        Mat src = Imgcodecs.imread("F:\\opencvPhoto\\testPhoto\\1.jpg");
        //灰度化
        Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2GRAY);
        //滤波
        Mat dst = new Mat();
        Imgproc.boxFilter(src, dst, CvType.CV_32F, new Size(4, 3), new Point(-1, -1), false, Core.BORDER_DEFAULT);

        Imgcodecs.imwrite("F:\\opencvPhoto\\result\\dst.jpg", dst);
    }

原图
在这里插入图片描述
效果图
在这里插入图片描述

函数具体实现

该函数原理较为简单,通过结果输出来验证上方的原理说明

	public static void main(String[] args) {

        //图片
        Mat src = new Mat(new Size(3, 3), CvType.CV_8UC1);
        src.put(0, 0, 1); src.put(0, 1, 2); src.put(0, 2, 3);
        src.put(1, 0, 1); src.put(1, 1, 2); src.put(1, 2, 3);
        src.put(2, 0, 1); src.put(2, 1, 2); src.put(2, 2, 3);
        
        System.out.println("-----------图片------------------");
        for (int row = 0; row < src.rows(); row++) {
            for (int col = 0; col < src.cols(); col++) {
                System.out.print(src.get(row, col)[0] + "   ");
            }
            System.out.println();
        }

        System.out.println("-----------normalize=false------------------");
        Mat dst1 = new Mat();
        Imgproc.boxFilter(src, dst1, CvType.CV_32F, new Size(3, 3), new Point(-1, -1), false, Core.BORDER_DEFAULT);
        for (int row = 0; row < dst1.rows(); row++) {
            for (int col = 0; col < dst1.cols(); col++) {
                System.out.print(dst1.get(row, col)[0] + "   ");
            }
            System.out.println();
        }

        System.out.println("-----------normalize=true------------------");
        Mat dst2 = new Mat();
        Imgproc.boxFilter(src, dst2, CvType.CV_32F, new Size(3, 3), new Point(-1, -1), true, Core.BORDER_DEFAULT);
        for (int row = 0; row < dst2.rows(); row++) {
            for (int col = 0; col < dst2.cols(); col++) {
                System.out.print(dst2.get(row, col)[0] + "   ");
            }
            System.out.println();
        }
    }

结果输出

-----------图片------------------
1.0   2.0   3.0   
1.0   2.0   3.0   
1.0   2.0   3.0   
-----------normalize=false------------------
15.0   18.0   21.0   
15.0   18.0   21.0   
15.0   18.0   21.0   
-----------normalize=true------------------
1.6666666269302368   2.0   2.3333332538604736   
1.6666666269302368   2.0   2.3333332538604736   
1.6666666269302368   2.0   2.3333332538604736   

其他说明

若想自己实现有多种方法如积分图等方式。在此不做讨论。

参考链接

https://blog.csdn.net/qq_41553038/article/details/79984462

发布了90 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/wangwenjie1997/article/details/101274086