【深度好文】Python图像处理之物体标识与面积测量

本文介绍了如何对二值图像进行物体标识和面积计算。首先,通过从上到下、从左到右扫描二值图像并进行区域增长标记,然后遍历标记图像以统计各区域像素数,从而得到物体的面积。提供了详细的代码实现,包括灰度化、二值化、物体标记和面积测量,最终展示了标记和测量结果。
摘要由CSDN通过智能技术生成

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算法资讯。
在这里插入图片描述

注:关注公众号号,后台回复 面积测量 ,即可获得完整代码。

  • 6
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值