深度好文Python图像处理之物体标识与面积测量
Posted 赵卓不凡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度好文Python图像处理之物体标识与面积测量相关的知识,希望对你有一定的参考价值。
1 引言
在二值图像f中,相互联结的白色像素的集合成为一个前景目标白色区域。本章对二值图像f内每个区域进行标记操作,进而求得区域的数目,并计算每个区域的面积。
物体标识的一般过程如下:
- 从左到右,从上到下逐个像素扫描
- 若该点为前景物体,则以该点为种子进行区域增长并标记。(区域增长算法可参考上节文章)
- 重复上述过程,直至所有像素都被访问过为止。最后输出标记后的图像。
2 物体标识代码实现
2.1 读入彩色图像执行灰度化和二值化
def get_binary_img(img):
# gray img to bin image
bin_img = np.zeros(shape=(img.shape), dtype=np.uint8)
h = img.shape[0]
w = img.shape[1]
for i in range(h):
for j in range(w):
bin_img[i][j] = 255 if img[i][j] < 255 else 0
return bin_img
# 调用
file_name = "./test.bmp"
img = cv2.imread(file_name)
# 灰度化
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
bin_img = get_binary_img(gray_img)
结果如下:
上图中左侧为原图,中间为灰度图,右侧为二值图
2.2 目标标记
# 标记目标
def label_region(bin_img,width,height):
visited = np.zeros(shape=bin_img.shape,dtype=np.uint8)
label_img = np.zeros(shape=bin_img.shape, dtype=np.uint8)
label = 0
for i in range(height):
for j in range(width):
if bin_img[i][j] == 255 and visited[i][j]==0 : //找到种子点
# visit
visited[i][j] = 1
label += 1
label_img[i][j] = label
# label
label_from_seed(bin_img, visited, i, j, label, label_img)
return label_img
# 区域增长法进行标记
def label_from_seed(bin_img,visited,i,j,label,out_img):
directs = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]
seeds = [(i,j)]
height = bin_img.shape[0]
width = bin_img.shape[1]
while len(seeds):
seed = seeds.pop(0)
i = seed[0]
j = seed[1]
if visited[i][j] == 0:
visited[i][j] = 1
out_img[i][j] = label
# 以(i,j)为起点进行标记
for direct in directs:
cur_i = i + direct[0]
cur_j = j + direct[1]
# 非法
if cur_i < 0 or cur_j < 0 or cur_i >= height or cur_j >= width:
continue
# 没有访问过
if visited[cur_i][cur_j] == 0 and bin_img[cur_i][cur_j] == 255:
visited[cur_i][cur_j] = 1
out_img[cur_i][cur_j] = label
seeds.append((cur_i,cur_j))
得到结果如下:
上图中左侧为原图,右侧为物体标记图,其中每一个物体的像素值就是该物体的标号,为计算面积打下基础。
3 目标面积
对标记后的图像进行遍历,统计每种编号出现的像素个数,即可求得不同区域的面积大小。
代码如下:
def get_region_area(label_img,label):
count = { key: 0 for key in range(label + 1)}
start_pt = {key:(0,0) for key in range(label + 1)}
height = label_img.shape[0]
width = label_img.shape[1]
for i in range(height):
for j in range(width):
key = label_img[i][j]
count[key] += 1
if count[key] == 1:
start_pt[key] = (j,i)
return count,start_pt
画图函数如下:
def draw_area_reslult(img,count,start_pt):
draw = img.copy()
for key in count.keys():
if key > 0:
pt = start_pt[key]
x = pt[0]
y = pt[1]
area = count[key]
if y < 20:
y = 20
cv2.putText(draw, str(area),(x,y), cv2.FONT_HERSHEY_COMPLEX, 0.8, (128, 0, 128), 1)
return draw
结果如下:
通过上图,可以知道我们共标记出4个目标,并且四个目标的面积依次为86,5680,6544和860。
4 总结
通过上述简单步骤,我们实现了物体标识和面积测量,相应的处理效果如下:
上图中左侧为原图,中间为目标标记图,右侧为我们面积测量图,数值代表对于目标的面积。
您学肥了嘛?
关注公众号《AI算法之道》,获取更多AI算法资讯。
注:关注公众号号,后台回复 面积测量 ,即可获得完整代码。
以上是关于深度好文Python图像处理之物体标识与面积测量的主要内容,如果未能解决你的问题,请参考以下文章