图像阈值分割
一、简介
阈值分割常用在灰度图像中,将灰度值以一定的阈值进行分割,分为0或者255,使图像的像素值只有0或者255(非黑即白)。由于不同物体的像素值不同,根据设置的阈值,将图像中的物体以像素级分割出来,有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。
二、二值化处理(全局阈值)
图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。
常用的二值化处理格式选择:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429201548509.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xteHQ1MjA=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020042920160735.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xteHQ1MjA=,size_16,color_FFFFFF,t_70)
# -*- coding:utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img.jpg')
#img --彩色图片
#阈值 这里将80 设置为阈值,大于80的全部变为后边给定的255,小于80的转为0
#最大值 255
#格式cv2.THRESH_BINARY 二值处理,
# ret,阈值;bin,二值处理后的图像
ret, thresh1 = cv2.threshold(img, 80, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img, 80, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img, 80, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img, 80, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img, 80, 255, cv2.THRESH_TOZERO_INV)
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2,3, i+1)
plt.imshow(images[i])
plt.suptitle('fixed threshold')
plt.show()
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429201625517.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xteHQ1MjA=,size_16,color_FFFFFF,t_70)
示例中使用的是原彩色图,二值化时将图片每个通道都进行了二值化处理。当使用灰度图片时,即可显示非黑即白的图片。
示例:
import cv2
import numpy as np
# 直接读取灰度图,没有其他色彩,阈值变换后只剩黑白。
img = cv2.imread('img.jpg', 0)
ret,bin = cv2.threshold(img,80,255,cv2.THRESH_BINARY)
原图:![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429201640612.jpg)
效果图:![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429201652526.jpg)
三、自适应阈值
当同一副图像需要不同部分需要不同的亮度时,全局阈值就不太适用了,这时需要使用到自适应阈值,自适应阈值会在图片中的不同区域计算不同的阈值,得到一个层次分明的图像。
代码示例:
# -*- coding:utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
#使用自动阈值时,只能使用单通道图片
img = cv2.imread('img.jpg',0)
# adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,dst=None)
#maxValue:Double类型的,阈值的最大值
#adaptiveMethod:Int类型的,这里有两种选择
# ADAPTIVE_THRESH_MEAN_C(通过平均的方法取得平均值)
# ADAPTIVE_THRESH_GAUSSIAN_C(通过高斯取得高斯值)
# thresholdType:Int类型的,方法如下:
# THRESH_BINARY 二进制阈值化 -> 大于阈值为1 小于阈值为0
# THRESH_BINARY_INV 反二进制阈值化 -> 大于阈值为0 小于阈值为1
# THRESH_TRUNC 截断阈值化 -> 大于阈值为阈值,小于阈值不变
# THRESH_TOZERO 阈值化为0 -> 大于阈值的不变,小于阈值的全为0
# THRESH_TOZERO_INV 反阈值化为0 -> 大于阈值为0,小于阈值不变
#blockSize:Int类型的,这个值来决定像素的邻域块有多大。
# C:偏移值调整量,计算adaptiveMethod用到的参数。
thresh1 =cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,10)
thresh2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
images = [img,thresh1,thresh2]
for i in range(3):
plt.subplot(1,3, i+1)
plt.imshow(images[i])
plt.show()
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429201709932.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xteHQ1MjA=,size_16,color_FFFFFF,t_70)
四、大津阈值法(Otsu’s Binarization)
大津阈值法是一种基于直方图的二值化方法,需要和全局阈值共同使用。
过程:
- 计算图像直方图;
- 设定一阈值,把直方图强度大于阈值的像素分成一组,把小于阈值的像素分成另外一组;
- 分别计算两组内的偏移数,并把偏移数相加;
- 把0~255依照顺序多为阈值,重复1-3的步骤,直到得到最小偏移数,其所对应的值即为结果阈值。
代码示例:
img = cv2.imread('img.jpg',0)
ret,thresh = cv2.threshold(img,80,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020042920172182.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xteHQ1MjA=,size_16,color_FFFFFF,t_70)