常用传统图像处理方法梳理

文章目录

    • 0. 颜色空间
    • 1. 图像滤波
      • (1) 图像滤波
      • (2) 图像增强——常见边缘检测算子
    • 2. HoG特征与SIFT特征
      • (1) HoG
      • (2) SIFT 特征
    • 3. 霍夫变换
      • (1) 直线检测
      • (2) 霍夫变换圆检测
    • 4. 开闭运算 腐蚀膨胀
    • 5. 插值

0. 颜色空间

常见颜色空间:

  • RGB
  • HSI(色调、饱和度、明度)
  • YUV
  • CMYK

OpenCV为什么是BGR?

  • 早期的bmp等图像格式中BGR更广泛一点,所以opencv也遵循这个格式

  • BGR与RGB格式转换

    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # 或
    img_rgb = img[:,:,::-1] # 因为img[:,:,0]为b分量, img[:,:,1]为g,img[:,:,2]为r分量
    

    注:python的list中,listA[i:j:s],表示从i到j的左闭右开区间,s表示步长。

  • opencv中通道数是在最后面,也就是上面的不管rgb还是bgr都是[h,w,c]的格式,有时候需要将通道数放到前面,使用transpose方法

    img_channel_first = img.transpose((2,0,1))
    

1. 图像滤波

(1) 图像滤波

  • 图像噪声

    • 高斯噪声,噪声的概率密度函数服从高斯分布,一般来自于器件的热噪声、电路噪声;高斯白噪声,功率谱密度均匀分布(高斯滤波)
    • 椒盐噪声,亮暗点噪声(中值滤波)
    • 泊松噪声,概率密度函数服从泊松分布(泊松分布适合于描述单位时间内随机事件发生的次数的概率分布),一般也是由于器件的光电转换过程导致
    • 量化噪声
  • 滤波器

    (一般在计算模板的时候就对系数和进行归一化处理了,因此使用模板的时候只需要求加权和)

    • 高斯滤波器:根据高斯函数的形状来选择权值的线性平滑滤波器

    • 均值滤波:窗口下取均值

    • 中值滤波:窗口下取中位数

    • 双边滤波:非线性滤波,具有保持边缘、平滑降噪的功能。

      ​ 对一幅图像而言,边缘区域像素值变化快,而非边缘区域像素变化比较平坦。高斯滤波并没有对这两种区域加以区分,因此会导致边缘模糊。若要比较好的保留图像边缘,就必须引入一个变量去衡量当前像素变化的剧烈程度,所以双边滤波其实就是引入了这样一个图像像素域的核。原来的高斯滤波中就是一个空间域的核,它是一个二维的高斯函数;像素域核就是衡量像素变化剧烈程度的函数。它们俩共同作用的结果:在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息

      dst = cv2.bilateralFilter(src=image,d=0,sigmaColor=100,sigmaSpace=15)
      

      ​ 其模板权重的计算方法:先根据sigmaSpace核sigmaColor计算各自的高斯函数下的权重,然后在对应像素位置将二者的乘积作为模板权重。之后就是像一般的卷积那样像素值加权求和。

      ​ Ref:双边滤波原理

(2) 图像增强——常见边缘检测算子

  • sobel

    边缘检测,边缘是像素值变化比较剧烈的位置,在连续函数上就是求梯度,在离散的数字图像上就是求差分。sobel算子就是求的水平或者竖直方向的一阶差分,同时带有一定的平滑效果。

    下图给出了两种sobel算子的功能。从本质上来看,上面这个sobel算子是水平差分+垂直平滑的结果,下面这个是水平平滑+垂直差分的结果。

    【优点】计算简单,速度快

    【缺点】计算方向单一,只有水平和垂直方向,难以应对复杂纹理;根据差分结果直接用单一阈值进行判断是否边缘像素,对有的噪声情况无法进行很好的处理

    常用传统图像处理方法梳理_第1张图片

  • canny

    虽然比较古老,但却是传统图像处理中,边缘检测的首选,性能很好。它主要包括以下四个步骤:

    • 高斯滤波,对图像进行平滑

    • 计算梯度大小和方向

      • 计算梯度大小,也使用类似sobel的梯度检测算子。它的模板系数计算方法是对高斯函数求梯度并标准化得到的,然后计算得到的也是水平和垂直两个方向的梯度大小

      • 计算梯度方向(角度)

        img

    • 利用非极大值抑制剔除上一步得到的梯度图像中大部分的非边缘点。这里的非极大值抑制思路主要为:如果一个像素点属于边缘,那么这个像素点在梯度方向上的梯度值是最大的。否则不是边缘,将灰度值设为0。如下图,梯度方向均为垂直向上,则取梯度方向上最大值为边缘点,这样理论上能够形成细且准确的单像素边缘

      常用传统图像处理方法梳理_第2张图片

    • 使用双阈值进行边缘连接。经过以上三步之后得到的边缘质量已经很高了,但还是存在很多伪边缘,因此Canny算法中所采用的算法为双阈值法,具体思路为选取两个阈值,将小于低阈值的点认为是假边缘置0,将大于高阈值的点认为是强边缘置1,介于中间的像素点需进行进一步的检查。具体实现的时候,根据高阈值图像中把边缘链接成轮廓,当到达轮廓的端点时,该算法会在断点的8邻域点中寻找满足低阈值的点,再根据此点收集新的边缘,直到整个图像闭合

    canny算子在opencv中的使用:

    dst = cv2.Canny(img, thresh1, thresh2) #两个threshold前者为低阈值,后者为高阈值
    

    Ref:https://zhuanlan.zhihu.com/p/59640437

2. HoG特征与SIFT特征

(1) HoG

参考:HoG特征
① 对图像进行预处理,主要是伽马矫正和灰度化,尽量去除光照的影响
② 对原图中的每一点,计算其梯度值,得到其梯度的大小和方向
例如,水平方向梯度gx:做水平差分;竖直方向梯度gy:做竖直差分。
总的梯度大小g = sqrt(gx2+gy2)
总的梯度方向θ = arctan(gx/gy)
③ 计算梯度直方图
将8x8大小的区域划分为一个cell,其元素共有8x8x2=128个关于梯度的值,将其按角度分到9个bin中,这9个bin是将180度划分为9份得到。这样,就得到一个长度为9的数组(梯度的直方图)。一般来说,观察梯度方向的主要分布范围,就可以大致认为该8x8区域的具有某个方向的边缘。HoG是对边界敏感,对灰度变化平坦的区域不敏感。

常用传统图像处理方法梳理_第3张图片

常用传统图像处理方法梳理_第4张图片

④ 以4个cell为一个block进行归一化,进一步降低光照影响
一个block事实上对应16x16的区域。4个cell,每个cell经过梯度直方图计算已经转化为一个长度为9的vector,现在一个block相当于包含一个长度为4x9=36的vector。这里的归一化,就是对这个长度为36的向量进行归一化

常用传统图像处理方法梳理_第5张图片

⑤ 得到HoG特征向量
注意block是在整张图上滑动的,因此对于64x128的图像,共7x15个block。
因此一张图像的HoG向量为7x15x36 = 3780
得到HoG特征向量之后,一般用svm进行分类。

(2) SIFT 特征

SIFT全称为scale invariant feature transform,即尺度不变特征变换。SFIT特征对于旋转、缩放、亮度等具有较好的不变性。

  • 特点

    • 描述图像的局部特征,能够对旋转(生成特征描述子时进行主方向校正)、尺度(通过差分高斯金字塔保证)、亮度(通过特征归一化保证)等保持不变,同时对视角变化、仿射变换、噪声等也具有一定的鲁棒性。
    • 独特性好,信息量丰富,适用于海量特征库进行快速、准确的匹配。
    • 多量性,即使是很少几个物体也可以产生大量sift特征
    • 高速,经优化的sift匹配算法能够达到实时效果
    • 可以很方便的与其他特征向量联合
  • 4个主要步骤

    • 尺度空间的极值检测,搜索潜在的感兴趣点
    • 特征点的精确定位
    • 特征方向赋值
    • 特征点描述【重点】
  • 尺度空间的极值检测

    为了搜索潜在的感兴趣点(特征点),由于这样的点应该在不同尺度、不同模糊程度上,先要求解差分高斯图像。

    首先,对原图像进行不同程度的高斯模糊,方差倍增,构成高斯尺度金字塔;对该金字塔的每一个图像进行一组等比例的下采样,得到不同空间尺度下的高斯尺度金字塔。

    然后,对于同一个高斯尺度金字塔内的各个图像,它们之间的区别主要是高斯模糊的程度不同,为了检测出在不同模糊情况下都存在的特征点,较好的做法是使用高斯拉普拉斯算子(LoG),但是它计算量比较大,这里采用差分高斯(DoG)来替代。其计算方法简单,如下:
    常用传统图像处理方法梳理_第6张图片
    也就是说,将两个相邻的不同模糊程度的高斯空间的图像相减,就得到了差分高斯的响应图像。(k表示相邻两图的高斯方差成k倍)。将同一组内相邻的图像两两相减,就得到了差分高斯金字塔

    接下来,为了寻找极值点,同一个金字塔内,每个像素点要和其图像邻域(物理意义上相邻的像素)和尺度邻域(相邻高斯尺度空间)的所有相邻点进行比较,当它大于/小于所有相邻点时,这个点就是极值点。见下图,所有绿色点都是x点的“相邻点”。

    常用传统图像处理方法梳理_第7张图片

    尺度变化连续性【待理解】:DoG金字塔每组首末两张图像无法比较求极值,这里有一点特殊处理。见参考文献。

  • 特征点的精确定位(对不好的特征点进行剔除)

    SIFT特征提取的关键点是DoG图像邻域(包括高斯尺度邻域和图像邻域)像素值的极值点(DoG做了差分,自身的像素值已经表示梯度了)。

    但DoG的局部极值点是在离散空间搜索得到的,不一定是真正意义上的极值点。因此需要将不满足条件的点剔除。可以通过尺度空间DoG函数进行曲线拟合来寻找极值点,其本质是对DoG局部曲率非常不对称的点进行剔除。这一步主要去除的是对比度低于一定阈值的特征点以及不稳定的边缘相应点(通过检测主曲率来实现)

  • 求取特征点的主方向(与HoG特征求解思路相同)

    经过上面的步骤,找到了在不同尺度下都存在的特征点,为了实现图像的旋转不变性,需要对特征点的方向进行赋值。对某个特征点,可以确定其对应的高斯尺度图像,计算以该特征点为中心、3×1.5倍标准差范围内各个点的梯度大小和方向角:常用传统图像处理方法梳理_第8张图片
    可以将[0,360°]划分为10个范围,按梯度方向角的大小统计梯度直方图(每个范围内的梯度累加),直方图的峰值即为特征点的主方向(实际中,应该还有平滑和插值拟合等操作)。

    在梯度直方图中,当存在一个相当于主峰值80%能量的柱值时,则可以将这个方向认为是该特征点辅助方向。所以,一个特征点可能检测到多个方向(也可以理解为,一个特征点可能产生多个坐标、尺度相同,但是方向不同的特征点)

    Lowe在论文中指出:15%的关键点具有多方向,而且这些点对匹配的稳定性很关键

    得到特征点的主方向后,对于每个特征点可以得到三个信息(x,y,σ,θ),即位置、尺度和方向。由此可以确定一个SIFT特征区域,一个SIFT特征区域由三个值表示,中心表示特征点位置,半径表示关键点的尺度,箭头表示主方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点

  • 生成特征描述

    通过上面的步骤已经得到了SIFT特征点的位置、尺度(个人理解为高斯模糊程度)和方向信息,下面需要用一组向量来对关键点进行描述。这组向量既包含了特征点本身的信息,也包含了特征点周围对他有贡献的其他像素点的信息。描述子应具有较高的独立性,以保证匹配率。

    SIFT特征描述子的生成包含以下三个步骤:

    • 校正旋转主方向,确保旋转不变性
    • 生成描述子,为一个128维特征向量
    • 对特征向量进行归一化,进一步去除光照影响

    校正旋转主方向,是为了保持特征向量的旋转不变性。这里的实现方法为:以特征点为中心,在其邻域内将坐标轴旋转到特征点主方向上,旋转后邻域内像素的新坐标为:
    常用传统图像处理方法梳理_第9张图片
    接下来,以特征点为中心,选取其周围16×16的像素,每4×4个划分为一组;求得每个像素的梯度大小和方向后,在4×4窗口内统计梯度直方图,这里将[0,360°]划分为8个方向,因此每个4×4窗口产生一个8维向量;而一共有16个窗口,因此每个特征点产生一个128维向量(这里的16个窗口,是16个直梯度直方图,相当于特征点周围的16个种子点,每个种子点有8个方向的信息)。

    这种邻域方向性信息联合增强了算法的抗噪声能力,同时对于含有定位误差的特征匹配也提供了比较理性的容错性。 常用传统图像处理方法梳理_第10张图片

Ref:SIFT特征原理

3. 霍夫变换

霍夫变换是对canny等算子处理后的边缘图像,求解图中的直线、圆等目标。其基本思路为:将特定图像上的点变换到一组参数空间上,根据参数空间中点的累计结果,找到一个极大值对应的解,那么这个解就对应着我们要寻找的几何形状的参数(如直线的斜率和截距、圆的圆心和半径)

因此,关键在于找到这个参数空间,然后对其进行统计。

(1) 直线检测

假设有一条直线L,原点到该直线的垂直距离为p,垂线与x轴夹角为θ ,那么这条直线是唯一的,且直线的方程为 ρ=xcosθ+ysinθ

常用传统图像处理方法梳理_第11张图片

该直线上的所有点都只有满足一组唯一的共同参数(ρ,θ),这个(ρ,θ)决定的直线就是检测到的直线。尽管对于每个点自身而言,可以对应许多(ρ,θ),因为一个点可以出现在多条直线上。

因此,对于每个点,我们去求解它所在直线的可能值,能够获得一系列(ρ,θ)参数,将一系列参数画在极坐标上,见下面右图。右图上的每一个点,对应直角坐标系上的一条直线

常用传统图像处理方法梳理_第12张图片

而对于原直线上的每一个点,都可以在参数空间画出这么一个曲线,接下来只需要统计在参数空间中这些曲线主要相交在哪个点,这个点对应的(ρ,θ)就是原空间中直线的参数。

常用传统图像处理方法梳理_第13张图片

因此霍夫变换直线检测的步骤如下:

  • 对原图使用canny算子等方法进行边缘提取
  • 将参数空间(ρ,θ) 量化,赋初值一个二维矩阵M,M(ρ,θ) 就是一个累加器了
  • 对图像边界上的每一个点进行变换,变换到属于哪一组(ρ,θ) ,就把该组(ρ,θ) 对应的累加器数加1。具体为,给定 θ i θ_i θi,根据 ρ i = x c o s θ i + y s i n θ i ρ_i=xcosθ_i+ysinθ_i ρi=xcosθi+ysinθi计算出 ρ i ρ_i ρi,然后将M( ρ i ρ_i ρi,$ θ_i $)处的值+1。
  • 所有点处理完后,找到M矩阵上大于阈值T的点,这些点的参数值就对应原空间的一条直线。

霍夫变换直线检测的问题:

  • Hough变换进行参数空间映射时需要对每个边缘点进行多次正弦曲线计算,这就大大的加重了算法的计算负担,同时也降低了其实时性
  • 在进行Hough变换之前需要对参数空间进行量化与离散化,但在离散化之后,参数空间中本来连续的函数被离散函数所取代,这就造成了变换之后得到的(A巧的值与原有值之间存在一定的误差
  • 上述方法对于参数空间中的离散点只进行一次投票,而在一次投票过程中常常出现伪峰值被判定为目标直线的情况。这点明显的不足严重的制约了其适用范围

改进:

  • 不采用计数器+一次投票确定参数,而在计算完毕参数空间后,采用聚类算法,确定聚类中心。

(2) 霍夫变换圆检测

与直线检测类似,不过圆检测的参数空间是个三维空间(a,b,r),分别对应圆心坐标和半径。对于圆上的每一点,满足

​ $ (x-a)2+(y-a)2=r^2 $

因此同样对其参数空间进行计数统计,找到满足点数最多的圆参数。

霍夫变换圆检测的缺点:

  • 需要将参数空间离散为一个三维空间(a,b,r),送样就使得算法所需的计算时间与存储空间过大,这一问题严重制约了该算法在实际检测中的应用
  • 该算法需要对圆形的半径进行提前预判,这就导致检测过程中可能出现漏检、误检的可能,这也降低了该算法对于圆形提取的精确性

优化方案:

  • 在OpenCV的霍夫圆检测函数实现中,为提升速度,采用的并非是直接对三个参数进行投票,而是另外一种通过计算梯度来对两侧可能出现圆心的位置进行投票的方法。具体可以查看该函数的实现。

一些观点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yFyfx8Ye-1587227089216)(C:\Users\LUO YUJIE\AppData\Roaming\Typora\typora-user-images\image-20200407180059250.png)]

  • 霍夫变换直线检测这样的传统图像处理方法怎么与深度学习方法结合起来?
    • 作为图像预处理,平滑去噪、光线校正、畸变校正、变换等
    • 作为数据增强手段,各种增强,噪声,变形
    • 作为后处理手段,比如先通过目标检测分割出目标区域,然后再做霍夫变换直线检测(参考这个:https://zhuanlan.zhihu.com/p/77666653)

4. 开闭运算 腐蚀膨胀

待更新

5. 插值

待更新

你可能感兴趣的:(边缘检测,dip)