简体   繁体   English

从阈值蒙版生成圆形粒子的分割蒙版?

[英]Generating a segmentation mask for circular particles from threshold mask?

I am trying to find all the circular particles in the image attached.我试图在附加的图像中找到所有圆形粒子。 This is the only image I am have (along with its inverse)这是我唯一的图像(连同它的反面) 在此处输入图像描述 . .

I have read this post and yet I can't use hsv values for thresholding.我已经阅读了这篇文章,但我不能使用 hsv 值进行阈值处理。 I have tried using Hough Transform.我尝试过使用霍夫变换。

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, dp=0.01, minDist=0.1, param1=10, param2=5, minRadius=3,maxRadius=6)

and using the following code to plot并使用以下代码 plot

names =[circles]
for nums in names:
  color_img = cv2.imread(path)
  blue = (211,211,211)
  for x, y, r in nums[0]:
    cv2.circle(color_img, (x,y), r, blue, 1)
    
  plt.figure(figsize=(15,15))
  plt.title("Hough")
  plt.imshow(color_img, cmap='gray')

The following code was to plot the mask:以下代码是 plot 掩码:

for masks in names:
  black = np.zeros(img_gray.shape)
  for x, y, r in masks[0]:
    cv2.circle(black, (x,y), int(r), 255, -1)  # -1 to draw filled circles
plt.imshow(black, gray)
  

Yet I am only able to get the following mask which if fairly poor.然而,我只能得到以下面具,如果相当差的话。 结果

This is an image of what is considered a particle and what is not.这是一张关于什么被认为是粒子而什么不是粒子的图像。 标记图像

My approach is based on a simple observation that most of the particles in your image have approximately same perimeter and the "not particles" have greater perimeter than them.我的方法基于一个简单的观察,即图像中的大多数粒子的周长大致相同,而“非粒子”的周长比它们大。

First, have a look at the RANSAC algorithm and how does it find inliers and outliers.首先,看一下 RANSAC 算法以及它是如何找到异常值和异常值的。 It basically is for 2D data but we will have to transform it to 1D data in our case.它基本上适用于 2D 数据,但在我们的案例中我们必须将其转换为 1D 数据。

In your case, I am calling inliers to the correct particles and Outliers to incorrect particles.在您的情况下,我将内点称为正确粒子,将异常值称为不正确粒子。

Our data on which we have to work on will be the perimeter of these particles.我们必须处理的数据将是这些粒子的周长。 To get the perimeter, find contours in this image and get the perimeter of each contour.要获取周长,请在此图像中找到轮廓并获取每个轮廓的周长。 Refer this for information about Contours . 有关 Contours 的信息,请参阅此处

Now we have the data, knowledge about RANSAC algo and our simple observation mentioned above.现在我们有了关于 RANSAC 算法的数据、知识和我们上面提到的简单观察。 Now in this data, we have to find the most dense and compact cluster which will contain all the inliers and others will be outliers.现在在这个数据中,我们必须找到最密集和最紧凑的集群,它将包含所有的内点,而其他的将是异常点。

Now let's assume the inliers are in the range of 40-60 and the outliers are beyond 60. Let's define a threshold value T = 0. We say that for each point in the data, inliers for that point are in the range of (value of that point - T, value of that point + T).现在让我们假设内点在 40-60 的范围内,离群值超过 60。让我们定义一个阈值 T = 0。我们说对于数据中的每个点,该点的内点都在 (值该点的值 - T,该点的值 + T)。

Now first iterate over all the points in the data and count number of inliers to that point for a T and store this information.现在首先遍历数据中的所有点,并为 T 计算到该点的内点数并存储此信息。 Find the maximum number of inliers possible for a value of T. Now increment the value of T by 1 and again find the maximum number of inliers possible for that T. Repeat these steps by incrementing value of T one by one.找到 T 值可能的最大内点数。现在将 T 的值增加 1 并再次找到该 T 可能的最大内点数。通过将 T 的值一一递增来重复这些步骤。

There will be a range of values of T for which Maximum number of inliers are the same.将有一系列 T 值,其中最大内点数相同。 These inliers are the particles in your image and the particles having perimeter greater than these inliers are the outliers thus the "not particles" in your image.这些内点是图像中的粒子,周长大于这些内点的粒子是异常值,因此是图像中的“非粒子”。

I have tried this algorithm in my test cases which are similar to your and it works.我已经在我的测试用例中尝试过这个算法,它与你的相似并且它有效。 I am always able to determine the outliers.我总是能够确定异常值。 I hope it works for you too.我希望它也适合你。

One last thing, I see that boundary of your particles are irregular and not smooth, try to make them smooth and use this algorithm if this doesn't work for you in this image.最后一件事,我看到你的粒子的边界是不规则的并且不光滑,如果这在这张图片中对你不起作用,试着让它们变得光滑并使用这个算法。

One simple approach involves slightly eroding the image, to separate touching circular objects, then doing a connected component analysis and discarding all objects larger than some chosen threshold, and finally dilating the image back so the circular objects are approximately of the original size again.一种简单的方法是稍微腐蚀图像,分离接触的圆形物体,然后进行连通分量分析并丢弃所有大于某个选定阈值的物体,最后将图像放大,使圆形物体再次近似于原始大小。 We can do this dilation on the labelled image, such that you retain the separated objects.我们可以对标记的图像进行这种膨胀,这样您就可以保留分离的对象。

I'm using DIPlib because I'm most familiar with it (I'm an author).我使用DIPlib是因为我最熟悉它(我是作者)。

import diplib as dip

a = dip.ImageRead('6O0Oe.png')
a = a(0) > 127        # the PNG is a color image, but OP's image is binary,
                      # so we binarize here to simulate OP's condition.

separation = 7        # tweak these two parameters as necessary
size_threshold = 500

b = dip.Erosion(a, dip.SE(separation))
b = dip.Label(b, maxSize=size_threshold)
b = dip.Dilation(b, dip.SE(separation))

上面代码的输出

Do note that the image we use here seems to be a zoomed-in screen grab rather than the original image OP is dealing with.请注意,我们在这里使用的图像似乎是放大的屏幕抓取,而不是 OP 正在处理的原始图像。 If so, the parameters must be made smaller to identify the smaller objects in the smaller image.如果是这样,则必须使参数变小以识别较小图像中的较小对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM