python+OpenCV图像处理(五)图像的阈值分割

您所在的位置:网站首页 opencv图像分割方法 python+OpenCV图像处理(五)图像的阈值分割

python+OpenCV图像处理(五)图像的阈值分割

2024-03-29 14:06| 来源: 网络整理| 查看: 265

图像的阈值处理

      一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。

       阈值分割法的特点是:适用于目标与背景灰度有较强对比的情况,重要的是背景或物体的灰度比较单一,而且总可以得到封闭且连通区域的边界。

(一)简单阈值

选取一个全局阈值,然后就把整幅图像分成非黑即白的二值图像。

函数为cv2.threshold( )

这个函数有四个参数,第一个是原图像矩阵,第二个是进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数,常用的有:

cv2.THRESH_BINARY(黑白二值)cv2.THRESH_BINARY_INV(黑白二值翻转)cv2.THRESH_TRUNC(得到额图像为多像素值)cv2.THRESH_TOZERO(当像素高于阈值时像素设置为自己提供的像素值,低于阈值时不作处理)cv2.THRESH_TOZERO_INV(当像素低于阈值时设置为自己提供的像素值,高于阈值时不作处理)

这个函数返回两个值,第一个值为阈值,第二个就是阈值处理后的图像矩阵。

img = cv2.imread('4.jpg', 0) ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # binary (黑白二值) ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV) # (黑白二值反转) ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC) # 得到的图像为多像素值 ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO) # 高于阈值时像素设置为255,低于阈值时不作处理 ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV) # 低于阈值时设置为255,高于阈值时不作处理 print(ret) cv2.imshow('thresh1', thresh1) cv2.imshow('thresh2', thresh2) cv2.imshow('thresh3', thresh3) cv2.imshow('thresh4', thresh4) cv2.imshow('thresh5', thresh5) cv2.imshow('grey-map', img) cv2.waitKey(0) cv2.destroyAllWindows()

(二)自适应阈值

一中的简单阈值是一种全局性的阈值,只需要设定一个阈值,整个图像都和这个阈值比较。而自适应阈值可以看成一种局部性的阈值,通过设定一个区域大小,比较这个点与区域大小里面像素点 的平均值(或者其他特征)的大小关系确定这个像素点的情况。使用的函数为:

# 第一个参数为原始图像矩阵,第二个参数为像素值上限,第三个是自适应方法(adaptive method):#                                              -----cv2.ADAPTIVE_THRESH_MEAN_C:领域内均值#                                              -----cv2.ADAPTIVE_THRESH_GAUSSIAN_C:领域内像素点加权和,权重为一个高斯窗口# 第四个值的赋值方法:只有cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV# 第五个Block size:设定领域大小(一个正方形的领域)# 第六个参数C,阈值等于均值或者加权值减去这个常数(为0相当于阈值,就是求得领域内均值或者加权值)

# 这种方法理论上得到的效果更好,相当于在动态自适应的调整属于自己像素点的阈值,而不是整幅图都用一个阈值

img = cv2.imread('4.jpg', 0) ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # 第一个参数为原始图像矩阵,第二个参数为像素值上限,第三个是自适应方法(adaptive method): # -----cv2.ADAPTIVE_THRESH_MEAN_C:领域内均值 # -----cv2.ADAPTIVE_THRESH_GAUSSIAN_C:领域内像素点加权和,权重为一个高斯窗口 # 第四个值的赋值方法:只有cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV # 第五个Block size:设定领域大小(一个正方形的领域) # 第六个参数C,阈值等于均值或者加权值减去这个常数(为0相当于阈值,就是求得领域内均值或者加权值) # 这种方法理论上得到的效果更好,相当于在动态自适应的调整属于自己像素点的阈值,而不是整幅图都用一个阈值 th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 2) th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th4 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) cv2.imshow('img', img) cv2.imshow('th1', th1) cv2.imshow('th2', th2) cv2.imshow('th3', th3) cv2.imshow('th4', th4) cv2.waitKey(0) cv2.destroyAllWindows()

对于第五个参数的窗口越来越小时,发现得到的图像越来越细了,可以设想,如果把窗口设置的足够大的话(不能超过图像大小),那么得到的结果可能就和第二幅图像的相同了。

(三)Otsu's二值化

cv2.threshold( )函数有两个返回值,一个是阈值,第二个是处理后的图像矩阵。

前面对于阈值的设定上,我们选择的阈值都是127,在实际情况中,有的图像阈值不是127得到的图像效果更好。那么这里就需要算法自己去寻找一个阈值,而Otsu's就可以自己找到一个认为最好的阈值。并且Otsu's非常适合于图像灰度直方图(只有灰度图像才有)具有双峰的情况。他会在双峰之间找到一个值作为阈值,对于非双峰图像,可能并不是很好用。那么经过Otsu's得到的那个阈值就是函数cv2.threshold的第一个参数了。因为Otsu's方法会产生一个阈值,那么函数cv2.threshold( )的第二个参数(设定阈值)就是0了,并且在cv2.threshold的方法参数中还得加上语句cv2.THRESH_OTSU.

在下列这些程序和图片中大家会有鲜明的体会:

img = cv2.imread('2.jpg', 0) ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # 简单滤波 ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) # Otsu 滤波 print(ret2) cv2.imshow('img', img) cv2.imshow('th1', th1) cv2.imshow('th2', th2) # 用于解决matplotlib中显示图像的中文乱码问题 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False plt.hist(img.ravel(), 256) plt.title('灰度直方图') plt.show() cv2.waitKey(0) cv2.destroyAllWindows()



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3