OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)

一: 图像模糊处理(滤波)

作用: 在进行图像处理之前的预处理,降低图像的噪点,提高图像的平滑度。

公式:数学卷积
图像的各个像素点是一个离散的数据,然而数学卷积是一种线性连续的操作(求和动作),所以有叫做线性滤波。
g ( i , j ) = ∑ k , j f ( i + k , j + l ) h ( k , j ) g(i,j) = \sum_{k,j}{f(i+k,j+l)h(k,j)} g(i,j)=k,jf(i+k,j+l)h(k,j)
说明: i , j i,j i,j 表示图像的行和列 , f ( i , j ) f(i,j) f(i,j)就表示一幅图像。 k , j k,j k,j表示卷积核, h ( k , j ) h(k,j) h(k,j)表示卷积算子函数(或者叫掩膜);卷积核在图像上进行卷积操作其中卷积核中心位置坐标就是 ( i , j ) (i,j) (i,j),然后求卷积和与图像对应坐标点像素的乘积再进行相加求和(范围在 k , j k,j k,j)之间,产生一个新的像素值。 k , j k,j k,j 有称作卷积窗口大小,然后再将值再赋给 g g g 对应的坐标点( i , j i,j i,j) 得到一副新的图像。
卷积操作是在图像上从上到下,从左到右,依次进行线性卷积计算。

图例:
OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)_第1张图片
假设灰色区域是 6 X 6 的像素矩阵,黄色是 3 X 3 的卷积核。
卷积核在图像上从上到下,从左到右,进行卷积操作:
(卷积和覆盖下的每个像素值乘以它对应的卷积核系数,本例中卷积核有9个系数,则有9个乘积,把这9个乘积相加后得到的值除于9得到平均值赋给中心点(红色区域)),
每一次得到新的值赋给中心点的红色坐标点,然后移动一个像素位置进行下一卷积运算,再把值赋给中心红色的位置。整幅图像依次类推。
有一个问题是 3 X 3 的卷积核 边缘有一个像素处理不到,5 X 5 的卷积核就会有两个,7 X 7 就会有3个 … … 但是 OpenCv中有另外的边缘处理方法。

原理:1归一化盒子滤波(均值滤波):

K = 1 K w ⋅ K h [ 1 1 ⋯ 1 1 1 ⋯ 1 1 1 ⋯ 1 ⋮ ⋮ ⋱ ⋮ 1 1 ⋯ 1 ] K= \dfrac{1 }{K_w\cdot K_h}\begin{bmatrix} {1_{}}&{1_{}}&{\cdots}&{1_{}}\\ {1_{}}&{1_{}}&{\cdots}&{1_{}}\\ {1_{}}&{1_{}}&{\cdots}&{1_{}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {1_{}}&{1_{}}&{\cdots}&{1_{}}\\ \end{bmatrix} K=KwKh1111111111111

原理:2高斯滤波:

G 0 ( x , y ) = e − ( x − μ x ) 2 2 σ x 2 + − ( y − μ y ) 2 2 σ y 2 G_0(x,y)=e \dfrac{-(x-\mu_x)^2}{2\sigma_x^2} +\dfrac{-(y-\mu_y)^2}{2\sigma_y^2} G0(x,y)=e2σx2(xμx)2+2σy2(yμy)2
σ x , σ y : \sigma_x ,\sigma_y : σx,σy:用来调节高斯正太分布情况

二:相关API:

均值模糊:

 //
        // 摘要:
        //     Smoothes image using normalized box filter
        //
        // 参数:
        //   src:
        //     The source image 源图像
        //
        //   dst:
        //     The destination image; will have the same size and the same type as src 输出图像
        //
        //   ksize:
        //     The smoothing kernel size  卷积核 
        //
        //   anchor:
        //     The anchor point. The default value Point(-1,-1) means that the anchor is at
        //     the kernel center  卷积核中心点位置  (-1,-1)是默认值也是中心点
        //
        //   borderType:
        //     The border mode used to extrapolate pixels outside of the image  边缘处理类型
        public static void Blur(InputArray src, OutputArray dst, Size ksize, Point? anchor = null, BorderTypes borderType = BorderTypes.Reflect101);

高斯模糊:

 //
        // 摘要:
        //     Blurs an image using a Gaussian filter.
        //     使用高斯滤波器模糊图像
        // 参数:
        //   src:
        //     input image; the image can have any number of channels, which are processed independently,
        //     but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
        //    源图像 通带任意 深度应该是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F。
        //   dst:
        //     output image of the same size and type as src.
        //    输出图像
        //   ksize:
        //     Gaussian kernel size. ksize.width and ksize.height can differ but they both must
        //     be positive and odd. Or, they can be zero’s and then they are computed from sigma*
        //     卷积核  size(x,y):x,y必须是奇数且是正数
        //
        //   sigmaX:
        //     Gaussian kernel standard deviation in X direction.
        //     X方向上的高斯核标准差。
        //   sigmaY:
        //     Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set
        //     to be equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width
        //     and ksize.height, respectively (see getGaussianKernel() for details); to fully
        //     control the result regardless of possible future modifications of all this semantics,
        //     it is recommended to specify all of ksize, sigmaX, and sigmaY.
        //     Y方向高斯核标准差;如果sigmaY为零,则设置它
        //      要等于sigmaX,如果两个sigmas都是零,它们是从ksize.width计算出来的
         //     和ksize。高度,分别(详见getGaussianKernel();完全
         //     控制结果,而不考虑所有这些语义将来可能的修改,
         //    建议指定所有的ksize、sigmaX和sigmaY。
        //   borderType:
        //     pixel extrapolation method  边缘类型处理方法
        public static void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, BorderTypes borderType = BorderTypes.Reflect101);

三 代码实现:

static void Main(string[] args)
        {
            string imagePath = @"C:\Users\whx\Desktop\opcvImage\mmm.jpg";
            TheMeanOfFuzzyAndGaussian(imagePath);
        }
 /// 
        /// 均值模糊和高斯模糊
        /// 
        private static void TheMeanOfFuzzyAndGaussian(string path)
        {
            using (src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (Mat dst = new Mat())
            {
                Mat gauss = new Mat();
                //注意:size 参数一定要是奇数 (均值模糊)
                Cv2.Blur(src, dst, new Size(5,5), new Point(-1, -1));

                //using(new Window("Gaussian Image",WindowMode.Normal,gauss))
                using(new Window("DST Image",WindowMode.AutoSize,dst))
                using (new Window("SRC Image", WindowMode.AutoSize, src))
                {
                    Cv2.WaitKey(0);
                }
            }
        }

OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)_第2张图片
上面使用均值模糊,卷积核大小:Size(5,5), 卷积核越大模糊程度越强。
还可以对 X 轴 或 Y轴方向指定模糊:

private static void TheMeanOfFuzzyAndGaussian(string path)
        {
            using (src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (Mat dst = new Mat())
            {
                Mat gauss = new Mat();
                //注意:size 参数一定要是奇数 (均值模糊)  Y 轴模糊
                Cv2.Blur(src, dst, new Size(1,15), new Point(-1, -1));

                //using(new Window("Gaussian Image",WindowMode.Normal,gauss))
                using(new Window("DST Image",WindowMode.AutoSize,dst))
                using (new Window("SRC Image", WindowMode.AutoSize, src))
                {
                    Cv2.WaitKey(0);
                }
            }
        }

OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)_第3张图片
图像有上下跳动的感觉!
下面是高斯模糊和均值模糊对比

private static void TheMeanOfFuzzyAndGaussian(string path)
        {
            using (src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (Mat dst = new Mat())
            {
                Mat gauss = new Mat();
                //注意:size 参数一定要是奇数 (均值模糊)
                Cv2.Blur(src, dst, new Size(11,11), new Point(-1, -1));
                //高斯模糊
                Cv2.GaussianBlur(src, gauss, new Size(11, 11), 11, 11);
                using (new Window("Gaussian Image", WindowMode.Normal, gauss))
                using (new Window("Blur Image", WindowMode.Normal, dst))
                using (new Window("SRC Image", WindowMode.Normal, src))
                {
                    Cv2.WaitKey(0);
                }
            }
        }

OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)_第4张图片
高斯滤波应该比均值滤波处理更精细一点,但是我感觉在视觉上差不多!

自定义卷积核:

 private static void TheMeanOfFuzzyAndGaussian(string path)
        {
            using (src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (Mat dst = new Mat())
            {
                //Mat gauss = new Mat();
                ////注意:size 参数一定要是奇数 (均值模糊)
                //Cv2.Blur(src, dst, new Size(11,11), new Point(-1, -1));
                ////高斯模糊
                //Cv2.GaussianBlur(src, gauss, new Size(11, 11), 11, 11);
                //using (new Window("Gaussian Image", WindowMode.Normal, gauss))
                InputArray arr = InputArray.Create(new float[3, 3] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } });
                Cv2.Filter2D(src, dst, -1, arr, new Point(-1, -1), 0);

                using (new Window("DST Image", WindowMode.Normal, dst))
                using (new Window("SRC Image", WindowMode.Normal, src))
                {
                    Cv2.WaitKey(0);
                }
            }
        }

OpenCvSharp 学习笔记8 --图像的模糊处理1(滤波)_第5张图片
图片亮度有所提升,对比更强烈了。

你可能感兴趣的:(学习笔记)