我有一张二值图像,包含多个白色斑点,背景为黑色。我想用Python统计这张图像中斑点的数量
我尝试了Python中的cv.findContours函数和skimage.measure.find_contours(),但没有得到我需要的结果
img = cv2.imread('test.png', 0)con = measure.find_contours(img, 0.8)fig, ax = plt.subplots()ax.imshow(img, interpolation='nearest', cmap=plt.cm.gray)for n, contour in enumerate(con): ax.plot(contour[:, 1], contour[:, 0], linewidth=2)ax.axis('image')ax.set_xticks([])ax.set_yticks([])plt.show()# 尝试保存带轮廓的图像但失败了。cv2.imwrite('contour.png', con)# 不知道如何在二值图像中统计斑点的数量
回答:
您可以使用一个函数来统计连通组件的数量。有已经实现的选项,您也可以轻松编写自己的函数。以下是一个示例代码:
def connected_components(image): # 我们使用过的标签列表 tags = [] # 当前标签(因为图像中已经有1和0,所以从2开始) tag = 2 # 计数器 cntr = 0 for i in range(image.shape[0]): for j in range(image.shape[1]): if image[i, j] != 0: if i != 0 and j != 0 and image[i, j-1] != 0 and image[i-1, j] != 0 and image[i-1, j] != image[i, j-1]: image[i, j] = image[i, j - 1] tags.remove(image[i - 1, j]) cntr -= 1 image[image == image[i - 1, j]] = image[i, j] elif i != 0 and image[i-1, j] != 0: image[i, j] = image[i-1, j] elif j != 0 and image[i, j-1] != 0: image[i, j] = image[i, j-1] else: image[i, j] = tag tags.append(tag) tag += 1 cntr += 1 return image, tags, cntr
这段代码的作用是:我们遍历每个像素,如果它是一个新像素且值为1:
- 如果其左侧或右侧的像素值不是1,我们给它一个新的标签。
- 如果其左侧或上方的像素值也是1,我们给它与它们相同的标签
- 如果其左侧和上方的像素值也是1:
- 如果它们已经有相同的标签,我们给它与它们相同的标签
- 我们给它与其中一个相同的标签,并将所有具有第二个标签的像素转换为第一个标签,这样这两个组件现在就是一个(因为它们通过这个像素连接)
您也可以使用预定义的方法,例如这个示例。