图像分割__阈值分割

阈值分割

  • 为得到图像中的物体信息, 必须进行图像分割, 即提取图像中与感兴趣物体相对应的区域, 而其中最简单的分割算法是图像的阈值分割。

1. 全局阈值

在这里插入图片描述

  • 使用过程中的五种阈值类型如上图所示

这种设定全局阈值的来进行图像分割的方法还是比较好理解的, 即设定一个阈值, 跟图像的每一个像素点的灰度值比较, 然后根据上面的五种类型的对应规则改变图中像素点的灰度值来达到图像分割的目的.

1.1 cv2.threshold()函数

ret, img = cv2.threshold (src, thresh, maxval, type)
参数解释
src源图片, 必须是单通道
thresh阈值, 取值范围 0 ~ 255 / 使用 OSTU时传入0值
maxal分配给像素值的最大值, 取值范围 0 ~ 255
type阈值类型, 即上图阈值类型的五种类型, 具体参数见下表
type解释
cv2.THRESH_BINARY二进制阈值化
cv2.THRESH_BINARY_INV反二进制阈值化
cv2.THRESH_TRUNC截断阈值化
cv2.THRESH_TOZERO阈值化为0
cv2.THRESH_TOZERO_INV反阈值化为0
返回值解释
ret设定的阈值 / 或自动计算得到的阈值
img阈值化后的图像

1.2 代码

import cv2

def main(filename:str)->None:
    img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
    print(img.dtype)
    ret, b_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
    ret, b_img_inv = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
    ret, img_trunc = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
    ret, img_tozero = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
    ret, img_tozero_inv = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
    cv2.imshow("img", img)
    cv2.imshow("THRESH_BINAR", b_img)
    cv2.imshow("THRESH_BINAR_INV", b_img_inv)
    cv2.imshow("THRESH_TRUC", img_trunc)
    cv2.imshow("THRESH_TOZERO", img_tozero)
    cv2.imshow("THRESH_TOZERO_INV", img_tozero_inv)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if(__name__ == "__main__"):
    main("img/car.png")

运行结果
在这里插入图片描述

1.3 自动阈值分割 Otsu二值化

在上面使用全局阈值时, 我们是手动自己设置了一个阈值, 那么如何确定这个阈值应该设置在那个范围合适, 一个做法即不停尝试不同的数值, 然后查看图片的处理结果, 而一个阈值是可以基于图像的灰度直方图来确定, 例如一副图像的灰度直方图是一副双峰图像, 一个好的阈值应该对应着两个峰之间的最小值, 而这里说的Otsu二值化就是选定阈值的其中一种方法.

opencv中使用OSTU还是用到 cv2.threshold()这个函数, 这不过在type类型这个参数需要多传入一个cv2.THRESH_OTSU, 同时还要把thresh阈值这个参数设置为0, 然后函数的返回值中的ret即根据这个算法找到的一个最优阈值。

ret, b_img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)

1.4 全局阈值的不足

全局阈值仅在物体的灰度值和背景的灰度值不变的情况下效果很好, 但更多的情况是照明情况并不均匀, 故会造成使用全局阈值进行分割的结果不理想, 即使使用OSTU也不能有很好的效果(对于非双峰图像,这种方法得到的结果可能会不理想)。 即下面的第一幅和第二幅的处理结果都不是理想的情况

在这里插入图片描述

2. 动态阈值

对于上面的问题是由于不均匀照明造成的, 因此不能找出一个对整幅图像都适用的固定阈值, 因为整幅图像在整体虽然光照不均匀, 但在局部区域中, 如上图所示文字是要比周围更暗的, 这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果,故这种将图像与局部背景进行比较的操作被称为动态阈值分割处理.

2.1 cv2.adaptiveThreshold()函数

dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
参数解释
src源图片, 必须是单通道
maxValue分配给像素值的最大值, 取值范围 0 ~ 255
adaptiveMethod阈值的计算方法, 两种:
1. cv2.ADAPTIVE_THRESH_MEAN_C 区域内均值
2. cv2.ADAPTIVE_THRESH_GAUSSIAN_C 区域内像素点加权和,权重为一个高斯窗口
thresholdType阈值类型, 就是前面说的五种, 不过这里只能用 cv2.THRESH_BINARY 和 cv2.THRESH_BINARY_INV这两种类型
blockSize规定领域大小(一个正方形的领域)
C阈值等于均值或者加权值减去这个常数(为0相当于阈值 就是求得领域内均值或者加权值)
返回值解释
dst阈值化后的图像

2.2 代码实现

 import cv2

def main(filename:str)->None:
    img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
    print(img.dtype)
    adv_img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
    cv2.imshow("img", adv_img)

    cv2.waitKey(0)
    cv2.imwrite("img/save3.bmp", adv_img)
    cv2.destroyAllWindows()


if(__name__ == "__main__"):
    main("img/test3.png")

运行结果
在这里插入图片描述

可以看到效果相比于上面的全局阈值出来的效果好很多.

2.3 动态阈值应用

  • 检测某一物体的缺陷, 如印刷缺陷

图像 g r , c g_{r, c} gr,c 代表理想物体, 即无缺陷物体的图像, 即作为参考图像. 图像 f r , c f_{r, c} fr,c 为待检测图像, 可以利用下面式子找出与参考图像相比偏差太大的像素点.

S = { ( r , c ) T ∈ R     ∣     ∣ f r , c − g r , c ∣ > g a b s } S = \{(r, c) ^ T \in R \,\,\, |\,\,\,|f_{r, c} - g_{r, c}| > g_{abs} \} S={(r,c)TRfr,cgr,c>gabs}

  • 前提: f r , c f_{r,c} fr,c 和参考图像 g r , c g_{r,c} gr,c 必须精确地对准, 只有这样才能避免将虚假的灰度值差错误解释为缺陷

3. Variation Model 变差模型

  • 为改善算法, 在进行阈值分割处理时, 需要考虑图像中预期的灰度值偏差。用 v r , c v_{r, c} vr,c 表示灰度值容许偏差

S = { ( r , c ) T ∈ R     ∣     ∣ f r , c − g r , c ∣ > v r , c } S = \{(r, c) ^ T \in R \,\,\, |\,\,\,|f_{r, c} - g_{r, c}| > v_{r, c} \} S={(r,c)TRfr,cgr,c>vr,c}

通过上式中将分割出与参考图像的偏差大于容许偏差的那些像素值

书中用 m r , c m_{r, c} mr,c s r , c s_{r,c} sr,c 来分别作为模型化参考图像 和 模型化参考图像的容许偏差

m r , c m_{r,c} mr,c​ = 1 n ∑ i = 1 n g r , c ; i \frac{1}{n} \sum_{i = 1}^{n}g_{r,c; i} n1i=1ngr,c;i

s r , c s_{r,c} sr,c​ = 1 n ∑ i = 1 n ( g r , c ; i − m r , c ) \sqrt{\frac{1}{n} \sum_{i = 1}^{n}(g_{r,c; i - m_{r,c}})} n1i=1n(gr,c;imr,c)

变差模型需要从n幅训练图像来构造参考图像和偏差图像, 但面对只可能采集一副参考图像的情况下, 建立变差模型有两个方法:

(1) 人为创建一些偏差, 如对图像进行平移

(2) 在物体边缘处存在的相应最大偏差推导出变差模型

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值