深度好文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图像处理之物体标识与面积测量的主要内容,如果未能解决你的问题,请参考以下文章

Python+OpenCV图像处理之开闭操作

RGBD相机模型与图片处理

RGBD相机模型与图片处理

单目,双目,深度相机比较

Python+OpenCV图像处理之对象测量

如何使用传统图像处理方法进行圆的检测和测量