图像处理学习笔记
基础知识
1: 什么是平滑处理?
平滑处理也称模糊处理, 是一种简单且使用频率很道德图像处理方法。 平滑处理的用途有很多,最常见的使用来减少图像上的噪点或者失真,在涉及到降低图像分辨率时,平滑处理是非常好用的方法。
2:什么是图像滤波?
图像滤波,指在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制, 消除图像中的噪声成分叫作图像的平滑化或滤波操作。
图像滤波的目的有两个:一个是抽出对象的特征作为图像识别的特征模式;另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声;
对滤波处理也有两条要求:一是不能损坏图像的轮廓及边缘等重要信息;二是图像清晰视觉效果好;
平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊;另一类是消除噪音(锐化)
3: 滤波器有哪些?
滤波器分为两类:
线性滤波:
方框滤波--BoxBlur函数
均值滤波--Blur函数
高斯滤波--GaussianBlur函数
非线性滤波:
中值滤波--medianBlur函数
双边滤波--bilateralFilter函数
4:线性滤波器的简介
线性滤波器: 线性滤波器经常用于剔除输入信号中不想要的频率或者从许多频率中选择一个想要的频率。
几种常见的线性滤波器如下:
低通滤波器:允许低频通过
高通滤波器:允许高频通过
带通滤波器:允许一定范围频率通过
带阻滤波器:阻止一定范围频率通过并且允许其他频率通过
全通滤波器:允许所有频率通过,仅仅改变相位关系
陷波滤波器:阻止一个狭窄频率范围通过,是一种特殊的带阻滤波器。
5:什么是滤波和模糊
说白了很简单:以高斯滤波为例,
高斯滤波是指用高斯函数作为滤波函数的滤波操作
高斯模糊就是高斯低通滤波
线性滤波操作
1: 方框滤波
作用是使用方波滤波来模糊一张图片
void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
输出图像的深度,-1代表使用原图深度,即src.depth();
内核的大小。Size(3,3)就表示3*3核大小,Size(5*5)就表示5*5核大小
表示锚点,默认值表示取核的中心为锚点
表示内核是否被其区域归一化
用于推断图像外部像素的某种边界模式,一般不用管它。
2:均值滤波
作用输出图像的每一个像素是核窗口内输入图像对应像素的平均值(所有像素加权系数相等),说白了就是归一化的方框滤波。
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
内核的大小。Size(3,3)就表示3*3核大小,Size(5*5)就表示5*5核大小
表示锚点,默认值表示取核的中心为锚点
用于推断图像外部像素的某种边界模式,一般不用管它。
3: 高斯滤波
作用使用高斯滤波器来模糊一张图片
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数,或者是零,这都是由sigma计算而来。
表示高斯核函数在X方向的标准偏差
表示高斯核函数在Y方向的标准偏差
用于推断图像外部像素的某种边界模式,一般不用管它。
为了结果正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
4:中值滤波
void medianBlur(InputArray src, OutputArray dst, int ksize);
参数:
输入图像,即源图像
输出图像,即目标图像
内核的大小,这个参数必须大于1的奇数,比如3,5,7,9 ...
5: 双边滤波
void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
表示在过滤过程中每个像素领域的直径。如果这个值被设备非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它。
颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素领域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
坐标空间中的滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了领域大小且与sigmaSpace无关。否则,d正比于sigmaSpace;
用于推断图像外部像素的某种边界模式,一般不用管它。
形态学滤波(1)
1: 什么是形态学?
简单来讲,形态学操作就是基于形状的一些列图像处理操作。
最基本的形态学运算--膨胀与腐蚀, 值得注意的是腐蚀和膨胀是对白色部分(高亮部分)而言,不是黑色部分
2: 膨胀
解析: 就是求局部最大值得操作。
void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const SCALAR &borderValue = morphologyDefaultBorderValeu());
参数:
输入图像,即源图像
输出图像,即目标图像
膨胀操作的核。当为NULL时,表示的是使用参考点位于中心3x3的核。一般使用getStructuringElement(MORPH_RECT, SIZE(x,y))函数会返回指定形状的尺寸的结构元素。
表示锚点,默认值表示取核的中心为锚点
迭代使用dilate()函数的次数,默认值为1
用于推断图像外部像素的某种边界模式,一般不用管它。
最后一个参数不需要管
3:腐蚀
解析: 就是求局部最小值的操作。
void erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const SCALAR &borderValue = morphologyDefaultBorderValeu());
参数:
输入图像,即源图像
输出图像,即目标图像
膨胀操作的核。当为NULL时,表示的是使用参考点位于中心3x3的核。一般使用getStructuringElement(MORPH_RECT, SIZE(x,y))函数会返回指定形状的尺寸的结构元素。
表示锚点,默认值表示取核的中心为锚点
迭代使用dilate()函数的次数,默认值为1
用于推断图像外部像素的某种边界模式,一般不用管它。
最后一个参数不需要管
4: 上面函数注意事项
注意:使用函数时,一般只需要填前面的三个参数,后面的四个参数都有默认值。
通常getStructuringElement()函数一起使用
参数:
1>表示内核的形状,有如下三种形态选择
矩形 MORPH_RECT
交叉形 MORPH_CROSS
椭圆形 MORPH_ELLIPSE
2> 内核的大小
3> 表示锚点,默认值表示取核的中心为锚点
形态学滤波(2)
1: 运用腐蚀和膨胀两种最基本的操作可以实现更高级的形态学变换
1.1 开运算:就是先腐蚀后膨胀的过程。可以用来消除小物体,在纤细点处分离物体,并且在平滑较大的物体的边界的同事不明显改变其面积。
其数学表达式: dst = open(src, element) = dilate(erode(src, element));
1.2 闭运算:就是先膨胀后腐蚀的过程。能够排除小型黑洞(黑色区域)。
其数学表达式: dst = close(src, element) = erode(dilate(src, element));
1.3 形态学梯度: 膨胀与腐蚀之差。可以将团块的边缘突出出来,保留物体的边缘轮廓。
1.4 顶帽(礼帽):原图与开运算之差。往往用来分离比邻近点亮一些的斑块。
1.5 黑帽运算:闭运算与原图之差。用来分离比邻近点暗一些的斑块,效果图有着非常完美的轮廓。
2:核心函数
void morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iterations = 1, borderType = BORDER_CONSTANT, const SCALAR &borderValue = morphologyDefaultBorderValeu());
参数:
输入图像,即源图像
输出图像,即目标图像
形态运算学类型:
MORPT_OPEN 开运算
MORPH_CLOSE 闭运算
MORPH_GRADIENT 形态学梯度
MORPH_TOPHAT 顶帽
MORPH_BLACKHAT 黑帽
MORPH_ERODE 腐蚀
MORPH_DILATE 膨胀
膨胀操作的核。当为NULL时,表示的是使用参考点位于中心3x3的核。一般使用getStructuringElement(MORPH_RECT, SIZE(x,y))函数会返回指定形状的尺寸的结构元素。
表示锚点,默认值表示取核的中心为锚点
迭代使用dilate()函数的次数,默认值为1
用于推断图像外部像素的某种边界模式,一般不用管它。
最后一个参数不需要管
3:漫水填充
3.1 什么是漫水填充?
是一种用特定的颜色填充连通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。漫水填充经常被用来标记或分离图像的一部分,以便
对其进行进一步处理或分析,也可以用来从输入图像获取掩码区域,掩码会进行加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域。
3.2 函数原型
第一版本:
int floodFill(InputOutputArry image, Point seedPoint, Scalar newVal, Rect *rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4);
第二版本:
int floodFill(InputOutputArry image, InputOutputArry mask, Point seedPoint, Scalar newVal, Rect *rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4);
参数:
输入/输出1通道或3通道,8位或浮点对象。
单通道8位,长和宽都比输入图像打两个像素点的图像
漫水填充算法的起始点
像素点被染色的值,即在重绘区域像素的新值。
可选参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
当前观察像素值与其部件邻域像素值或待加入该部件的种子像素之间的亮度或颜色之负差的最大值
当前观察像素值与其部件邻域像素值或待加入该部件的种子像素之间的亮度或颜色之正差的最大值
标志操作符,包含三部分:
低八位(0~7):用于控制算法的连通性,可取4(只考虑当前像素水平和垂直方向的相邻点)或者8(还会包含对角线方向的相邻点).
高八位(16-23):可为0或者如下两种选项标识组合;
FLOODFILL_FIXED_RANGE:设置就会考虑当前像素与种子像素之差,否则就考虑当前像素与其相邻像素的差。
FLOODFILL_MASK_ONLY:设置函数不会去填充改变原图像(也就是忽略第三个参数newVal),而去填充掩码图像,只对第二版本有效
中八位(8~15):关于高八位FLOODFILL_MASK_ONLY表示符找那个已经输的很明显,需要输入符合要求的掩码。中八位就是用于指定填充掩码图像的值的。如果中八位为0,则掩码会用1来填充。
图像尺寸调整
1: 放大(向上采样)
void pyrUp(InputArray src, OutputArray dst, const Size &dstsize=Size(), int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
输出图像的大小
用于推断图像外部像素的某种边界模式,一般不用管它。
2:缩小(向下采样)
void pryDown(InputArry src, OutputArray dst, const Size &dstsize=Size(), int borderType = BORDER_DEFAULT);
参数:
输入图像,即源图像
输出图像,即目标图像
输出图像的大小
用于推断图像外部像素的某种边界模式,一般不用管它。
3:尺寸调整
void resize(InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation=INTER_LINEAR);
参数:
输入图像,即源图像
输出图像,即目标图像
输出图像的大小
沿水平轴的缩放系数
沿垂直轴的缩放系数
指定插入方式:
INTER_NEAREST 最近邻插值
INTER_LINEAR 线性插值(默认)
INTER_AREA 区域插值(利用像素区域关系的重采样插值)
INTER_CUBIC 三次样条插值(超过4X4像素邻域内的双三次插值)
INTER_LANCZOS4 Labczis插值(超过8X8像素邻域的Lanczos插值)
注意:
如要缩小图像,一般情况下最好使用CV_INTER_AREA, 放大图像用CV_INTER_LINEAR。
阈值
1: 什么是阈值化?
在对各种图形进行处理操作的过程中,我们常常需要对图像中的像素做出取舍与决策,直接剔除一些低于或高于一定值的像素。
阈值可以被视作最简单的图像分割的方法。
2:固定阈值操作
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);
参数:
输入图像,即源图像
输出图像,即目标图像
具体的阈值
阈值的类型;当第五个参数为CV_THRESH_BINARY或CV_THRESH_BINARY_INV时阈值类型的最大值;
阈值类型:
THRESH_BINARY: 取值0,二值阈值化
THRESH_BINARY_INV: 取值1,反向二值阈值化并反转
THRESH_TRUNC: 取值2,截断阈值化
THRESH_TOZERO: 取值3,超过阈值被置为0
THRESH_TOZERO_INV: 取值4,低于阈值被置为0
注意:
在使用中阈值参数可以直接填写取值数字
3:自适应阈值操作
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, itn thresholdType, int blockSize, double C);
参数:
输入图像,即源图像
输出图像,即目标图像
像素满足条件的非零值
用于指定要使用的自适应阈值算法;ADAPTIVE_THRESH_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C;
阈值类型
用于计算阈值大小的一个像素的邻域尺寸,通常为3,5,7等
减去平均或加权平均值后的常数值。通常为正数,少数情况也可以为零或负数。
作用:
对矩阵采用自适应阈值操作,支持就地操作。