如何使用OpenCV移除小的连接对象

ioekq8ef  于 2023-01-26  发布在  其他
关注(0)|答案(4)|浏览(202)

我使用OpenCV和Python,我想从我的图像中删除小的连接对象。
我有以下二进制图像作为输入:

该图像是以下代码的结果:

dilation = cv2.dilate(dst,kernel,iterations = 2)
erosion = cv2.erode(dilation,kernel,iterations = 3)

我想删除以红色突出显示的对象:

如何使用OpenCV实现这一点?

1tu0hz3e

1tu0hz3e1#

使用connectedComponentsWithStats(doc)如何:

# find all of the connected components (white blobs in your image).
# im_with_separated_blobs is an image where each detected blob has a different pixel value ranging from 1 to nb_blobs - 1.
nb_blobs, im_with_separated_blobs, stats, _ = cv2.connectedComponentsWithStats(im)
# stats (and the silenced output centroids) gives some information about the blobs. See the docs for more information. 
# here, we're interested only in the size of the blobs, contained in the last column of stats.
sizes = stats[:, -1]
# the following lines result in taking out the background which is also considered a component, which I find for most applications to not be the expected output.
# you may also keep the results as they are by commenting out the following lines. You'll have to update the ranges in the for loop below. 
sizes = sizes[1:]
nb_blobs -= 1

# minimum size of particles we want to keep (number of pixels).
# here, it's a fixed value, but you can set it as you want, eg the mean of the sizes or whatever.
min_size = 150  

# output image with only the kept components
im_result = np.zeros_like(im_with_separated_blobs)
# for every component in the image, keep it only if it's above min_size
for blob in range(nb_blobs):
    if sizes[blob] >= min_size:
        # see description of im_with_separated_blobs above
        im_result[im_with_separated_blobs == blob + 1] = 255

输出:

bnlyeluc

bnlyeluc2#

为了自动删除对象,您需要在图像中找到它们。从您提供的图像中,我看不到任何可以区分7个突出显示的项目的内容。您必须告诉您的计算机如何识别您不想要的对象。如果它们看起来相同,这是不可能的。
如果你有多个图像,其中的对象总是看起来像你可以使用模板匹配技术。
此外,关闭操作对我来说没有多大意义。

dhxwm5r4

dhxwm5r43#

对于孤立或未连接的Blob:试试这个(你可以设置noise_removal_threshold为你喜欢的任何值,并使它相对于最大的轮廓,例如,或者像100或25这样的标称值)。

mask = np.zeros_like(img)
    for contour in contours:
      area = cv2.contourArea(contour)
      if area > noise_removal_threshold:
        cv2.fillPoly(mask, [contour], 255)
niknxzdl

niknxzdl4#

按区域去除小连通分量称为区域打开,OpenCV没有这个功能,可以按其他答案实现,但大多数其他图像处理包都有区域打开功能。
例如,使用scikit-image:

import skimage
import imageio.v3 as iio

img = iio.imread('cQMZm.png')[:,:,0]

out = skimage.morphology.area_opening(img, area_threshold=150, connectivity=2)

例如,使用DIPlib:

import diplib as dip

out = dip.AreaOpening(img, filterSize=150, connectivity=2)

PS:DIPlib的实现明显更快。免责声明:我是DIPlib的作者。

相关问题