使用 connectedComponentsWithStats
(文档) 怎么样?
# 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
im_result = np.zeros(im.shape)
总是创建一个dtype为float64的数组,而不是适应输入图像的dtype。在更复杂的图像处理链中更改图像数组的dtype可能会导致意外错误,因此我建议将该行更改为im_result = np.zeros_like(im)
。 - Thomas Fritz通过面积来移除小的连通组件被称为面积开放。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)
import diplib as dip
out = dip.AreaOpening(img, filterSize=150, connectivity=2)
PS:DIPlib 的实现明显更快。免责声明:我是 DIPlib 的作者。
mask = np.zeros_like(img)
for contour in contours:
area = cv2.contourArea(contour)
if area > noise_removal_threshold:
cv2.fillPoly(mask, [contour], 255)