一、图像分割
图像分割就是将图像分为一些有意义的区域,然后可以对这些区域进行描述,相当于提取出某些目标区域的特征。图像分割的基础是像素间的相似性和跳变性
。
通常,我们对图像进行分割,分割的小区域是某种意义下具有共同属性的像素的连通集合。各区域类某种性质,如灰度、纹理有相似性。区域内部是连通,无过多小孔。并且有明显边界。
图像分割的四种不同的基本方法
- 边缘检测:检测出边缘,再将边缘像素连接,构成边界形成分割。找出目标物理的轮廓,进行目标的分析、识别、测量
- 阈值分割:最常用法。有直方图门限选择,半阈值选择图像分割,迭代阈值。
- 边界方法:直接确定取余边界,实现分割;有边界跟踪法,轮廓提取法。
- 区域法:将各个像素划归到相应物体或者区域的像素聚类法
图像的阈值分割
有以下三种基本方法
- 直方图门限选择
- 半阈值选择图像分割
- 迭代阈值图像分割
第一种直方图门限选择
确定阈值T的原理主要是根据,物理的背景和前景往往是不通,体现在直方图上的化就是其灰度值成明显的双峰值。
例:下面有一幅图
其对应的,灰度级直方图如下:
我们可以很清晰的看到,波谷大概位于215处为止。现在我们对此进行阈值分割,其效果如下
那么,我们怎么选择对应的波谷呢?如果有多个波谷、波峰该怎么办呢?
最简单粗暴的就是通过人工来填写阈值。当然这种方法也就违背了我们做图像识别的意义了。
如果有多个波谷,那么我们选择多个阈值即可。其数学表达式大概如下
半阈值选择分割法
该方法原理就是,不论图像的直方图具有双峰还是多峰,阈值化之后原多值图像都将会变成二值图像。如果希望只将图像的背景变成二值图像,而物理任然为多值图像,此时,我们可以采用半阈值分割法
半阈值分割法的
效果图如下
迭代阈值分割法
迭代阈值分割法是一种自动算出阈值的,不需要人工参与的。
其基本思想,选择一个阈值作为初值,按照某种策略,直到满足某种条件,跳出循环,输出阈值。
用代码实现,即如下
# 自动迭代阈值法
def GetThresholdvalue(self):
# 辅助函数,得到图像的统计数据
def helper1():
static = np.array([0 for i in range(0, 256)])
s = np.array([])
for y in range(0,len(self.Img)):
for x in range(0,len(self.Img[y])):
Col=self.Img[y][x][0]
static[Col]=static[Col]+1
return static
# 下面几步是用来确定初始化阈值的
def helper2(arr,pos):
sum=0
c=0
for i in range(0,len(arr)):
sum=sum+arr[i]*(i+pos)
c = c + arr[i]
if c==0:
return 0
return int(sum/c)
tv = helper1() #得到图像的统计数据
c_init=helper2(tv,0) # 计算出平均灰度值,作为初始阈值
# 下面开始迭代
l_tv=tv[:c_init]
r_tv=tv[c_init:]
lastavg=c_init
while True:
L_avg=helper2(l_tv,pos=0)
R_avg=helper2(r_tv,pos=lastavg)
avg=int((L_avg+R_avg)/2)
if np.abs(avg-lastavg)<2:
break
l_tv = tv[:avg]
r_tv = tv[avg:]
lastavg=avg
return lastavg