图像处理与分析

2020-02-22  本文已影响0人  Shine_ahuii

一、照明与图像

光通量(Φ 流明 lm):光通量指人眼所能感觉到的辐射功率,它等于单位时间内某一波段的辐射能量和该波段的相对视见率的乘积。
辐照度(E 勒克斯 lux):辐照度指投射到一平表面上的辐射通量密度。指到达一表平面上,单位时间,单位面积上的辐射能。

1lux = 1 lm /m³

RGB与CMYK颜色模型

RGB:红绿蓝三原色
CMYK:品红 黄 青 三补色


两种颜色模型
HSI颜色模型
HSI(HSV颜色模型)
OpenCV颜色空间转换

dst = cv.cvtColor(src, dst, code)
*src:输入
dst:输出
code:色彩空间转换模式

二、图像平滑滤波

图像的卷积
4-邻域 8-邻域
平均滤波

使图像边缘变得平滑,损失了图像的细节,核越大,图像越模糊,对椒盐噪声效果不佳


加权平均滤波

高斯滤波:根据像素位置赋不同的权值,临近的像素具有更高的重要度

高斯滤波
使图像边缘变得平滑的同时不损失图像的细节,应用广泛

双边滤波

中值滤波

对孤立噪声特别有效,核越大图像越模糊,核必须是奇数


三、数学形态学滤波

膨胀

A \oplus B = \bigcup _ { b \in B } ( A ) _ { b }

膨胀操作
腐蚀

A \ominus B = \bigcap _ { b \in B } ( A ) _ { - b }

腐蚀操作 腐蚀与膨胀

腐蚀:灰度值大的变小(图像变暗)
膨胀:灰度值大的变大(图像变亮)
膨胀腐蚀都会使图像颗粒化

开闭运算

开运算:先腐蚀后膨胀
A \circ B = ( A \ominus B ) \oplus B
闭运算:先膨胀后腐蚀
A \cdot B = ( A \oplus B ) \ominus B

先开后闭:可有效去除噪声

开闭运算
OpenCV 图像滤波
滤波函数

dst = cv2.filter2D(src , ddepth, kernel, dst, anchor, delta, borderType)
src:输入图像
ddepth:目标图像的所需深度,包括CV_16S/CV_32F/CV_64F等
kernel:卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用拆分将图像拆分为单独的颜色平面,然后单独处理它们
dst:输出图像,与输入图像尺寸和通道数相同
anchor:内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1) 表示锚位于内核中心
delta:在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置
borderType:卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT 等

常用滤波函数
  • 平均滤波
    dst=cv2.blur(src,ksizel,dst,anchor,borderType)
  • 高斯平滑滤波
    dst=cv2.GaussianBlur(src,ksize,sigmaX,dst,sigmaY,borderType)
  • 中值滤波
    dst=cv2.medianBlur(src,ksizeL,dst)
参数 描述
ksize 滤波器大小,如(5,5)
  • 双边滤波
    dst=cv2. bilateralFilter(src, d, sigmaColor, sigmaSpace, dst, borderType)
参数 描述
src 原始图像:8-bit或floating-point,1-channel或3-channel
dst 目标图像:size和type与原始图像相同
d 过滤期间使用的各像素邻域的直径
sigmacolor 色彩空间的sigma参数,该参数较大时,各像素邻域内相距较远的颜色会被混合到一起,从而造成更大范围的半相等颜色
sigmaSpace 坐标空间的sigma参数,该参数较大时,只要颜色相近,越远的像素会相互影响
borderType 卷积填充方式,包括BORDER_CONSTANT,BORDERREPLICATE, BORDER_REFLECT等
原图——————————均值滤波——————————高斯滤波——————————中值滤波——————————双边滤波

四、边缘检测

计算过程
基本算子
  1. 边缘检测即图像差分
  2. 常见边缘检测算子包括Robert算子,Sobel算子,LoG 算子等,其中Sobel算子最为常用
  3. 二维图像的边缘具有强度和方向两个性质
  • 算法步骤:
    1.平滑图像
  • 使用高斯函数完成平滑,以 5×5 为例
    \begin{aligned} G(x,y) &= \frac {1} { \sqrt{2\pi} \sigma }{ exp \left[ { - \frac{x^2 + y^2 }{ \sigma^2 }} \right]} \\ K &= \frac {1} {139} \left[ \begin{array} { c c c c c} { 2 } & { 4 } & { 5 } &{ 4 } &{ 2 }\\ { 4 } & { 9 } & { 12 } &{ 9 } &{ 4 } \\ { 5 } & { 12 } & { 15 } &{ 12 } &{ 9 }\\ { 4 } & { 9 } & { 12 } &{ 9 } &{ 4 }\\ { 2 } & { 4 } & { 5 } &{ 4 } &{ 2 } \end{array} \right] \end{aligned}

2.计算梯度(幅值和方向)

  • 使用Sobel边缘检测算子对平滑图像进行xy方向的边缘检测,假设得到结果分别为E_{x}E_{y}
  • 进一步计算梯度幅值和方向:
    \begin{aligned} M ( x , y ) &= \sqrt { E _ { x } ^ { 2 } ( x , y ) + E _ { y } ^ { 2 } ( x , y ) } \\ \theta ( x , y ) &= \tan ^ { - 1 } \left( \frac { E _ { y } ( x , y ) } { E _ { x } ( x , y ) } \right) \end{aligned}
  • 方向离散化

3.梯度幅值进行非极大值抑制

细化梯度幅值图像中的屋脊带,只保留幅值局部变化最大的点

4.自动边缘连接

  • 对上一步得到的图像使用低、高阈值\tau_1 \tau_2阈值化,得到三幅图像
    \left\{ \begin{array} \\{ T _ { 1 } [ i , j ] \left( M ( i , j ) < \tau _ { 1 } \right) } \\ { T _ { 2 } [ i , j ] \left( \tau _ { 1 } \leq M ( i , j ) \leq \tau _ { 2 } \right) } \\ { T _ { 3 } [ i , j ] \left( M ( i , j ) > \tau _ { 2 } \right) } \end{array} \right.
    T_1对应假边缘,去除
    T_2对应真边缘,全部保留
    T_3连接:临接像素中是否有属于T_3的像素
  • 通过查看弱边缘像素及其8个邻域像素,只要其中一个为强 边缘像素,则该弱边缘点就可以保留为真实的边缘。

数学形态学边缘检测


r = ( A \oplus B ) - ( A \ominus B )


顶帽变换(tophat)定义为图像与其开运算的差值:
r = A -(A \circ B)
黑帽变换(blackhat)定义为图像闭运算与自身的差值:
r = (A \cdot B) - A

原图 顶帽变换 底帽变换

顶帽变换和底帽变换的结合使用能够应用于灰度图像的对比度增强
常用做法:将源图像加上顶帽变换再减去底帽变换 →增强对比度


r = A ⊛ B = \left( A \ominus B _ { 1 } \right) \cap \left( A ^ { c } \ominus B _ { 2 } \right)

OpenCV实现边缘检测
  • Sobel算子边缘检测
    dst = cv2.Sobel(src , ddepth , dx , dy [, dst [, ksize [, scale [, delta [, borderType ]]]]] )
  • Laplace算子
    dst = cv2.Laplacian( src , ddepth [, dst [, ksize [, scale [, delta [, borderType ]]]]] )
  • Canny算子
    dst = cv2.Canny( image , threshold1 , threshold2 [, edges [, apertureSize [, L2gradient ]]] )
参数 描述
ddepth 目标图像的所需深度,包括CV_16S/CV_32F/CV_64F等
ksize 滤波器大小,通常可选为(5,5)或(3,3),或直接使用缺省
  • 形态学滤波
    dst = cv2.morphologyEx( src , op , kernel [, dst [, anchor [, iterations [, borderType [, borderValue ]]]]] )
参数 描述
src 原图像
op 形态学操作,包括MORPH_ERODE, MORPH_DILATE, MORPH_OPEN, MORPH_CLOSE,MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT, MORPH_HITMISS
kernel 滤波结构元素,参见getStructuringElement
iterations 进行操作的次数

dst = cv2.getStructuringElement(shape , ksize [, anchor ] )
这个函数的第一个参数表示内核的形状,有三种形状可以选择。
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;

1.OpenCV提供了Sobel,Canny等函数用于边缘检测
2. OpenCV提供了MorphologyEx函数用于形态学滤波


五、图像变换

常见几何变换
距离变换
距离变换
对数极坐标变换(Log-Polar变换)
Log-Polar变换

Log-Polar变换应用:全景展开

六、灰度直方图

灰度直方图是关于灰度级分布的函数,是对图像中灰度级分布的统计。灰度直方图是将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。灰度直方图是灰度级的函数,它表示图像中具有某种灰度级的像素的个数,反映了图像中某种灰度出现的频率。通过直方图可判断图像曝光及对比度等情况 .


灰度直方图对图像照明特征的反映

越集中对比度越低

直方图均衡化
局部直方图均衡化
利用局部直方图统计进行灰度增强

七、霍夫(Hough)变换

Hough变换步骤
图像变换OpenCV函数
dst  =   cv.distanceTransform(  src, distanceType ,  maskSize [ , dst [,  dstType ]]   ) 
参数 功能
distanceType 距离计算方式,DIST_L1DIST_L2DIST_C
maskSize 掩模尺寸,可取DIST_MASK_PRECISEDIST_MASK_3,5
dst  =   cv.logPolar(  src ,  center ,  M ,  flags [, dst] )
参数 功能
center 变换中心点
M 幅值尺度参数
flags 标志位,是插值方法和下面选项的组合:CV_WARP_FILL_OUTLIERS 填充目标图像中的所 有像素;CV_WARP_INVERSE_MAP 表示矩阵是从目标图像到源图像的反变换
  matplotlib.pyplot.hist( x, bins=None, range=None,  ...) 
参数 功能
bins 多少个柱
range 显示的范围
dst  =   cv.equalizeHist(  src  [, dst] )
lines  = cv.HoughLines(  image ,  rho ,  theta ,  threshold [,  lines [,  srn [,  stn [,  min_theta [,  max_theta ]]]]] ) 
参数 功能
image 输入图像,应为二值图像,通常使用边缘检测结果;
rho 线段以像素为单位的距离精度,double类型的,推荐用1.0
theta 线段以弧度为单位的角度精度,推荐用numpy.pi/180
threshod 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线 段越长,检出的线段个数越少
lines  = cv.HoughLinesP(  image ,  rho ,  theta ,  threshold [,  lines [,  minLineLength [,  maxLineGap ]]] ) 

效果更好,能检测大部分的直线线条!

八、图像分割

  1. 图像分割是中层视觉的重要内容,具有广泛应用
  2. 图像分割的主要方法包括阈值法、区域法等
  3. 图像标记为分割后的结果打上不同标签,便于后续处理
灰度阈值分割
自动阈值分割

自动确定最佳阈值,使背景和目标之间的差异 最大

  • 大津(Otsu)算法原理I
    根据统计分析理论,最佳阈值确定的最佳二分类应使类内方差最小,等同于类间方差最大
    大津算法基本思想:确定使灰度直方图类间方差最大的最佳阈值假设灰度直方图已经归一化,即
    p_i = \frac{n_i} {N}, \sum p_i = 1
  • 假设阈值T将像素灰度划为两类:C_0C_1,则每一类出现的概率:
    \omega_0 = \sum_{i=1}^{T} { \frac {ip_i} {\omega_0} } = \frac{ \mu_{0}^{'} }{ \omega_0 }
    \mu_1 = \sum_{ i = T + 1}^{N} {\frac {ip_i} {\omega_1} } = \frac{\mu_{1}^{'} }{ \omega_{1} } = \frac{\mu - \mu_{0}^{'} }{1-\omega_0}
    其中 \mu = \sum_{i=1}^{N} ip_i。显然有\omega_0 \mu_0 + \omega_1 \mu_1 = \mu
  • 两类的类内方差:
    \sigma _ { 0 } ^ { 2 } = \sum _ { i = 1 } ^ { T } \left( i - \mu _ { 0 } \right) ^ { 2 } p _ { i } / \omega _ { 0 } , \sigma _ { 1 } ^ { 2 } = \sum _ { i = T + 1 } ^ { N } \left( i - \mu _ { 1 } \right) ^ { 2 } p _ { i } / \omega _ { 1 }
    对应的类间方差:
    \sigma _ { B } ^ { 2 } = \omega _ { 0 } \left( \mu _ { 0 } - \mu \right) ^ { 2 } + \omega _ { 1 } \left( \mu _ { 1 } - \mu \right) ^ { 2 } = \omega _ { 0 } \omega _ { 1 } \left( \mu _ { 1 } - \mu _ { 0 } \right) ^ { 2 }
  • 显然,\omega_B是关于最佳阈值r的隐函数,应选取T
    T = \underset { 1 \leq T < L } { \operatorname { argmax } } \sigma _ { B } ^ { 2 }
  • 大津算法是常用的一类灰度阈值自动选取方式,目标是令类间方差最大
  • 大津算法求解采用遍历方式,思想直接,实现速度快。
OpenCV边缘轮廓分割

image , contours , hierarchy = cv.findContours( image, mode, method [, contours [, hierarchy [,offset ]]])

参数 含义
image 单通道图像矩阵,可以是灰度图,但更常用的是经过边缘检测算子处理后的二值图像
contours 定义为vector<vector<Point>>contours,是一个轮廓列表
hierarchy 存在嵌套轮廓时,分别为第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号
mode 定义轮廓的检索模式, 包括CV_RETR_EXTERNAL只检测最外围轮廓,CV_RETR_LIST检测所有轮廓,但不建立等级关系等
method 包括CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours
offset 所有的轮廓信息相对于原始图像对应点的偏移量, 缺省不设置

局部阈值分割

多阈值分割
多阈值分割

1. 局部阈值法可有效解决照明不均的问题
2. 多阈值法是二值化分割方法的扩展,可解决多值目标 的分割问题


区域生长法分割

区域生长法:从种子点开始,按照一定准则(如 相邻像素灰度相似性)向周围扩散 ,将邻域相似像素加入区域中

区域生长实现步骤:

  1. 对图像顺序扫描。找到第1个还没有归属的像素, 设该像素为(x_0, y_0);
  2. (x0, y0)为中心, 考虑(x_0, y_0)的8邻域像素(x, y),如果(x, y)满足生长 准则, 将(x, y)(x_0, y_0)合并, 同时将(x, y)压入堆栈;
  3. 从堆栈中取出一个像素, 把它当作(x_0, y_0)返回到步骤2;
  4. 当堆栈为空时,返回到步骤1;
  5. 重复步骤1 - 4直到图像中的每个点都有归属时。生长结束。

图像分裂
图像分裂
  • 对区域分裂合并法无需预先指定种子点,它按某种一致性准则分裂 或者合并区域。
  • 可以先进行分裂运算,然后再进行合并运算;也可以分裂和合并运算 同时进行,经过连续的分裂和合并,最后得到图像的精确分割效果。
  • 分裂合并法对分割复杂的场景图像比较有效。

1. 区域生长法基于相邻像素间的相似性,由种子像素逐 步生长得到
2. 分裂-合并基于图像块内在的相似性,通过不断分裂得 到区域外边界,通过合并将不同块连接


分水岭分割
分水岭分割

漫水原则

局部极小值点:该点对应一个盆地的最低点,当我们在盆地滴一滴水的时候,由于重力作用,水最终会汇聚到该点。注意:可能存在一个最小值面,该平面内的都是最小值点。
盆地的其它位置点:该位置滴的水滴会汇聚到局部最小点。
盆地的边缘点:是该盆地和其它盆地交接点,在该点滴一滴水,会等概率的流向任何一个盆地。

分水岭算法的过分割问题

由于噪声点或者其它干扰因素的存在,使用分水岭算法常常存在过度分 割的现象,这是因为很多很小的局部极值点的存在


分水岭算法的过分割问题

在初始时给marker,改善过分割问题,为了解决过度分割的问题,可以使用基于标记(mark)图像的分水岭算法,就是指定mark 图像,在这个区域的洪水淹没过程中,水平面都是从定义的marker开始的,这样可以避 免一些很小的噪声极值区域的分割。

加入Marker改善后的分割结果
Opencv实现

区域生长法:retval , image , mask , rect = cv.floodFill( image , mask , seedPoint , newVal [, loDiff [, upDiff [, flags]]] )
分水岭算法:markers = cv.watershed( image, markers #marker种子点

上一篇 下一篇

猜你喜欢

热点阅读