【问题标题】:How can I calculate the area inside non contiguous shapes in an image?如何计算图像中非连续形状内的面积?
【发布时间】:2019-08-27 21:19:47
【问题描述】:

我有一系列有趣的细胞生长图像,我的公司正在尝试以编程方式量化培养皿中有多少含有细胞,有多少没有。

我在下面添加了一张图片作为我的示例。任何封闭区域都是细胞生长,而任何其他非黑色区域则不是。

我尝试了几种不同的过滤器和填充算法来在细胞生长区域之间进行搜索,但是在图像处理方面经验不足并没有取得太大的成功。这是我从互联网上收集的一些代码,用于计算黑色像素的数量。不过,太慢了,我觉得还是问问大家比较好。

image = Image.open("Images/24Hour/HB15_2.jpg")
image = image.getdata()

def is_black_enough(pixel):
    r, g, b = pixel
    return r < 10 and g < 10 and b < 10
w, h = np.asarray(image).shape
black_pixels = 0
for pixel in image:
    if is_black_enough(pixel)==True:
        black_pixels+=1
        print(black_pixels)
black_pixels/(w*h)

编辑

我用谷歌搜索并管理了几件事。首先,我有一个有效的黑色像素计算器。其次,我有一个细胞生长区域的初始计算器。有人知道如何计算下面封闭的黄色边界或完全有不同的解决方案吗?

img = Image.open("Images/24Hour/HB15_2.jpg")
img = img.convert('L')
img = np.asarray(img)
img = 1 * (img < 130) * (img > 90)
m,n = img.shape
plt.figure(figsize=(20,10))
plt.imshow(img)

【问题讨论】:

    标签: python image opencv image-processing python-imaging-library


    【解决方案1】:

    由于您的细胞生长是不连续的形状,我们不能使用形状检测器。所以另一种选择可能是对细胞进行斑点检测,然后找到该区域以获得定量数字。为了检测斑点,我们首先将图像转为灰度图像并使用Canny edge detection,这有助于我们隔离细胞生长。

    接下来我们可以使用cv2.contourArea()获取所有轮廓并找到每个轮廓的面积。我们将每个单独的轮廓区域相加以获得总面积。这是一种简单的方法,并不完美,但它可以抓取大部分 blob。

    import cv2
    import numpy
    
    def grab_contours(cnts):
        # OpenCV v2.4, v4-official
        if len(cnts) == 2:
            return cnts[0]
        # OpenCV v3
        elif len(cnts) == 3:
            return cnts[1]
    
    image = cv2.imread("test.png")
    
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edged = cv2.Canny(gray, 120, 255, 1)
    cv2.imshow("canny", edged)
    
    cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
    cnts = grab_contours(cnts)
    
    contour_image = edged.copy()
    area = 0
    
    for c in cnts:
        area += cv2.contourArea(c) 
        cv2.drawContours(contour_image,[c], 0, (100,5,10), 3)
    
    print(area)
    cv2.putText(contour_image, str(area), (50,50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (100,255,100), 2)
    cv2.imshow("area", contour_image)
    cv2.waitKey(0)
    

    【讨论】:

      【解决方案2】:

      一个简单的方法是把所有的黄色变成白色,把所有的紫色变成黑色。然后得到图像的平均值并乘以宽度和高度。这将计算黄色像素的数量(即区域)。也许您应该将图像保存为灰度或二进制而不是对其进行着色。例如,这里有一种使用 ImageMagick 的方法。但是您可能可以使用 Python Wand、OpenCV 或 scipy (skimage) 来做同样的事情。

      请注意,我已下载您的图片并对其进行裁剪以删除其他标记。所以你需要使用你的完整图片。

      convert img_sub.png -alpha off -fuzz 10% -fill black -opaque "rgb(68,1,84)" -fill white +opaque black +write binary.png -format "%[fx:mean*w*h]\n" info:
      
      58464
      

      这是保存的二进制图像。

      【讨论】:

        猜你喜欢
        • 2020-08-24
        • 1970-01-01
        • 1970-01-01
        • 2013-08-12
        • 2011-04-22
        • 1970-01-01
        • 2020-09-15
        • 2014-02-16
        • 2018-10-06
        相关资源
        最近更新 更多