首页 > 解决方案 > 如何计算图像中一定大小的粒子数?

问题描述

有没有一种基于大小检测粒子的好算法?例如,我有下图,我想检测和计数下图中突出显示的粒子: 在此处输入图像描述

在此处输入图像描述

基本上是根据大小来的。左边第三个圆圈大约是 20 微米,我想计算所有符合该阈值的粒子。

我该怎么做呢?我需要为 10,000 张图像执行此操作吗?

谢谢

标签: pythonopencvimage-processingpython-imaging-library

解决方案


正如 Mark Setchell 在评论中所述,如果没有参考图像,我们无法测量 20 微米。但是,您已经说过我们可以将第三个轮廓作为参考,所以我首先在使用阈值化图像后将其裁剪掉

import cv2

img = cv2.imread('stars.png', 0)
ret, img = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('star.png', img)

裁剪后的油漆

星星提取

现在,它的面积可以作为其他人的参考。现在再次读取原始图像和提取的星形图像,并为后一个图像计算最大轮廓的面积。然后在对原始图像进行阈值处理后计算原始图像的轮廓并循环它们。它们是根据参考区域进行测量的。(我取了获得的面积的一半。在确定最佳值之前,您可能还必须在其他图像之后为此执行参数调整。)满足给定条件的任何轮廓都绘制在使用创建的结果白色图像上np.ones并且具有与原始图像相同的大小,并且计数器变量递增。cv2.bitwise_and用于仅获取接受的轮廓并显示总计数。

阈值处理后的图像

最后结果

源代码-:

import cv2
import numpy as np

img = cv2.imread('stars.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
match = cv2.imread('star.png', 0)
h, w = img.shape[:2]
res = np.ones((h, w), np.uint8)*255
ret, thresh = cv2.threshold(gray,64,255,cv2.THRESH_BINARY)
_, cnts, _ = cv2.findContours(match, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = max(cnts, key = cv2.contourArea)
area = cv2.contourArea(cnt)
_, cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
count = 0
for cnt in cnts:
    if cv2.contourArea(cnt)>=area/2:
        cv2.drawContours(res, cnt, -1, 0, 2)
        count += 1
res = cv2.bitwise_and(img, img, mask = cv2.bitwise_not(res))
cv2.imshow("res", res)
cv2.imshow("star", match)
cv2.imshow("image", img)
cv2.imshow("result", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
print("total count is =", count)

这给出了 Output total count is = 3


推荐阅读