连通域求解
图像处理中连通域指由前景相同像素,并且相同像素邻接的像素组成的域。图像处理中一般都是对二值图像(1白色,0为黑色,一般前景为0黑色)做连通域分析。连通域分析指把连通域找出来并且标记出来。
连通域标记方法:(1)两次遍历实现;(2)深度优先搜索遍历
1.第一次遍历
如果当前元素为0则赋值一个label,lebel从大于1开始,如果像素的邻接像素的标签有大于1的,则当前元素赋值为大于1的最小的label。记录等价标签。
第二次遍历
遍历找到等价标签,标记等价标签的最小值为label。
如果只求连通域的数量则只需循环一次就够了,连通域数等于label-等价标签的个数-label起始值。
如:起始标记为label = 1,等价标签存放在列表中,list=[(2,6),(3,7)],即等价标签个数有len(list),则连通域个数为label -1-len(list).
如果需要将连通区域标记的的话需要循环两次。
import numpy
a = [[1 for i in range(10)] for j in range(10)]
a = [[1, 0, 0, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1]]
a = numpy.array(a)
#cv2.imwrite('/home/lijq/IdeaProjects/AnimalRecognition_Demo/demo/person3.jpg',a)
label = 1
list = []
if a[0][0]<1:
label +=1
a[0][0] = label
for j in range(1,len(a[0])):
if a[0][j]<1:
if a[0][j-1]>1:
a[0][j]=a[0][j-1]
else:
label +=1
a[0][j] = label
for i in range(1,len(a)):
if a[i][0]<1:
if a[i-1][0]>1:
a[i][0]=a[i-1][0]
else:
label +=1
a[i][0] = label
for i in range(1,len(a)):
for j in range(1,len(a[0])):
if a[i][j]<1:
if a[i][j-1]>1 and a[i-1][j]>1:
a[i][j] = min(a[i][j-1],a[i-1][j])
if a[i][j-1]!=a[i-1][j]:
list.append((a[i][j-1],a[i-1][j]))
elif a[i][j-1]>1 and a[i-1][j]==1:
a[i][j] = a[i][j-1]
elif a[i-1][j]>1 and a[i][j-1] ==1:
a[i][j] = a[i-1][j]
else:
label += 1
a[i][j] = label
nums_lt = label-1-len(list)
print label,list,nums_lt
print a
2.深度遍历标记
通过深度优先把所有连通的找出来标记完,再继续遍历下一个连通区域。连通域数量为 label-1.(设置的label默认值为1,歧视标记为2,如果从1标记的话会和图像值里的1混淆,所以为了方便起始值可以是任意大于1的数)
a = [[1, 0, 0, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1]]
a = numpy.array(a)
def dfs(nums,i,j,label):
if i >=len(nums) or j>=len(nums[0]) or i<0 or j<0:
return
if nums[i][j]<1:
nums[i][j]=label
dfs(nums,i,j+1,label)
dfs(nums,i+1,j,label)
dfs(nums,i-1,j,label)
dfs(nums,i,j-1,label)
dfs(nums,i-1,j-1,label)
label = 1
for i in range(len(a)):
for j in range(len(a[0])):
if a[i][j]<1:
label +=1
a[i][j] = label
dfs(a,i,j+1,label)
dfs(a,i+1,j,label)
print a
版权声明:本文为lijjianqing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END