函数原理
在原理上,和均值滤波一样,用一个内核和图像进行卷积:
其中:
可见,归一化了就是均值滤波;不归一化则可以计算每个像素邻域上的各种积分特性,方差、协方差,平方和等等。
函数说明
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
其他说明
若想自己实现有多种方法如积分图等方式。在此不做讨论。