You can filter using contour area then apply morpholgical closing to fill the small holes in the image. Here's the result:

import cv2

# Load image, convert to grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Filter using contour area and remove small noise
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 5500:
        cv2.drawContours(thresh, [c], -1, (0,0,0), -1)

# Morph close and invert image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = 255 - cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)

cv2.imshow('thresh', thresh)
cv2.imshow('close', close)
cv2.waitKey()
Answer from nathancy on Stack Overflow
🌐
O'Reilly
oreilly.com › library › view › hands-on-image-processing › 9781789343731 › 045fdc91-5fc4-49a0-9943-4e60bd558b7a.xhtml
Removing small objects - Hands-On Image Processing with Python [Book]
November 30, 2018 - from skimage.morphology import remove_small_objectsim = rgb2gray(imread('../images/circles.jpg'))im[im > 0.5] = 1 # create binary image by thresholding with fixed threshold0.5im[im <= 0.5] = 0im = im.astype(np.bool)pylab.figure(figsize=(20,20))pylab.subplot(2,2,1), plot_image(im, 'original')i = 2for osz in [50, 200, 500]: im1 = remove_small_objects(im, osz, connectivity=1) pylab.subplot(2,2,i), plot_image(im1, 'removing small objects below size ' + str(osz)) i += 1pylab.show()
Author   Sandipan Dey
Published   2018
Pages   492
Discussions

Removing small objects
Hi, I’m trying to remove the small objects outside of my main object as seen here in this picture: trabecular_mask.tiff (207.2 KB) I’ve been using: trabecular_mask = remove_small_objects(trabecular_mask, min_size=400) But nothing changes, changing “min_size” doesn’t seem to do anything. More on forum.image.sc
🌐 forum.image.sc
3
0
February 6, 2020
python - Remove small objects from binary image with skimage - Stack Overflow
I have the following binary image and I want to remove the spots with a value 0 inside the area of the pixels with value 1. I tried following code from the skimage package: im1 = morphology. More on stackoverflow.com
🌐 stackoverflow.com
July 13, 2022
Mailman 3 Can morphology.remove_small_objects be used to remove small noise? - scikit-image - python.org
My binary image has lots of noise (small white blobs about 3-6 pixels in area). Can the function skimage.morphology.remove_small_objects() be used to remove these small blobs? In my experimentation, the function leaves the image unchanged. Am I using the function incorrectly or is the function ... More on mail.python.org
🌐 mail.python.org
October 26, 2019
python - How to remove small connected objects using OpenCV - Stack Overflow
I use OpenCV and Python and I want to remove the small connected object from my image. I have the following binary image as input: The image is the result of this code: dilation = cv2.dilate(dst,... More on stackoverflow.com
🌐 stackoverflow.com
🌐
scikit-image
scikit-image.org › docs › stable › auto_examples › features_detection › plot_remove_objects.html
Removing objects — skimage 0.26.0 documentation
This example shows how to remove objects based on their size, or their distances from other objects. import matplotlib.pyplot as plt import skimage as ski # Extract foreground by thresholding an image taken by the Hubble Telescope image = ski.color.rgb2gray(ski.data.hubble_deep_field()) foreground = image > ski.filters.threshold_li(image) objects = ski.measure.label(foreground) # Separate objects into regions larger and smaller than 100 pixels large_objects = ski.morphology.remove_small_objects(objects, max_size=99) small_objects = objects ^ large_objects # Remove objects until remaining ones are at least 100 pixels apart.
🌐
Image.sc
forum.image.sc › image analysis
Removing small objects - Image Analysis - Image.sc Forum
February 6, 2020 - Hi, I’m trying to remove the small objects outside of my main object as seen here in this picture: trabecular_mask.tiff (207.2 KB) I’ve been using: trabecular_mask = remove_small_objects(trabecular_mask, min_size=400…
🌐
ProgramCreek
programcreek.com › python › example › 94369 › skimage.morphology.remove_small_objects
Python Examples of skimage.morphology.remove_small_objects
These are beach or swash pixels that are # erroneously identified as clouds by the CFMASK algorithm applied to the images by the USGS. if sum(sum(cloud_mask)) > 0 and sum(sum(~cloud_mask)) > 0: morphology.remove_small_objects(cloud_mask, min_size=10, connectivity=1, in_place=True) if cloud_mask_issue: elem = morphology.square(3) # use a square of width 3 pixels cloud_mask = morphology.binary_opening(cloud_mask,elem) # perform image opening # remove objects with less than 25 connected pixels morphology.remove_small_objects(cloud_mask, min_size=25, connectivity=1, in_place=True) return cloud_mask
🌐
CODE SEMINAR
egomerit.com › home › front-end development › how to remove very small objects from image – python
How To Remove Very Small Objects From Image - Python
October 22, 2023 - Apply a binary threshold to create a binary image. Set a threshold value that separates the small objects from the background. ... Perform morphological operations to remove small white regions or objects from the binary image.
🌐
scikit-image
scikit-image.org › docs › 0.25.x › auto_examples › features_detection › plot_remove_objects.html
Removing objects — skimage 0.25.2 documentation
This example shows how to remove objects based on their size, or their distances from other objects. import matplotlib.pyplot as plt import skimage as ski # Extract foreground by thresholding an image taken by the Hubble Telescope image = ski.color.rgb2gray(ski.data.hubble_deep_field()) foreground = image > ski.filters.threshold_li(image) objects = ski.measure.label(foreground) # Separate objects into regions larger and smaller than 100 pixels large_objects = ski.morphology.remove_small_objects(objects, min_size=100) small_objects = objects ^ large_objects # Remove objects until remaining ones are at least 100 pixels apart.
🌐
scikit-image
scikit-image.org › docs › 0.24.x › auto_examples › features_detection › plot_remove_objects.html
Removing objects — skimage 0.24.0 documentation
This example shows how to remove objects based on their size, or their distances from other objects. import matplotlib.pyplot as plt import skimage as ski # Extract foreground by thresholding an image taken by the Hubble Telescope image = ski.color.rgb2gray(ski.data.hubble_deep_field()) foreground = image > ski.filters.threshold_li(image) objects = ski.measure.label(foreground) # Separate objects into regions larger and smaller than 100 pixels large_objects = ski.morphology.remove_small_objects(objects, min_size=100) small_objects = objects ^ large_objects # Remove objects until remaining ones are at least 100 pixels apart.
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › scikit-image › scikit-image-removing-small-objects-from-image.htm
Scikit Image − Removing Small Objects from an Image
The scikit-image (skimage) library provides a remove_small_objects() function in the morphology module to identify and remove connected components or objects in a binary or labeled image based on the specified size.
🌐
Python
mail.python.org › archives › list › scikit-image@python.org › thread › AU53A2XWIKFT5C45FLWYLQSLJMKE7JMX
Mailman 3 Can morphology.remove_small_objects be used to remove small noise? - scikit-image - python.org
October 26, 2019 - src = cv2.imread('plan4.png') src = cv2.GaussianBlur(src, (3,3), 1) edges = get_edges(src.copy()) noise_reduced = morphology.remove_small_objects(edges .copy(), 2,) cv2.imshow('src', src) cv2.imshow('noise_reduced', noise_reduced) cv2.imshow('edges ', edges ) Below is the original with small white blobs (that I want to remove) and the result of remove_small_objects() notice they are the same and no blobs are removed. *Note: morphological closing or opening the image would remove these small blobs but it also degrades my lines too much.
Top answer
1 of 4
59

Use cv2.connectedComponentsWithStats (doc):

import cv2
import numpy as np

# Start by finding all of the connected components (white blobs in your image).
# 'im' needs to be grayscale and 8bit.
nb_blobs, im_with_separated_blobs, stats, _ = cv2.connectedComponentsWithStats(im)
# im_with_separated_blobs is an image where each detected blob has a different pixel value ranging from 1 to nb_blobs - 1.
# The background pixels have value 0.

im_with_separated_blobs looks like this :

# 'stats' (and the silenced output 'centroids') provides information about the blobs. See the docs for more information. 
# Here, we're interested only in the size of the blobs :
sizes = stats[:, cv2.CC_STAT_AREA]
# You can also directly index the column with '-1' instead of 'cv2.CC_STAT_AREA' as it's the last column.

# A small gotcha is that the background is considered as a blob, and so its stats are included in the stats vector at position 0.

# 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  

# create empty output image with will contain only the biggest composents
im_result = np.zeros_like(im_with_separated_blobs)

# for every component in the image, keep it only if it's above min_size.
# we start at 1 to avoid considering the background
for index_blob in range(1, nb_blobs):
    if sizes[index_blob] >= min_size:
        im_result[im_with_separated_blobs == index_blob] = 255

im_result looks like this :


Bonus : An alternative way of coding the same process, taking advantage of indexing a numpy array with another array and of the numpy.where function. It's probably more Pythonic insofar that it avoids the for loop, but is also possibly less flexible rearding other filtering conditions (and perhaps less readable) :

_, im_with_separated_blobs, stats, _ = cv2.connectedComponentsWithStats(im)

sizes = stats[:, cv2.CC_STAT_AREA]

im_result = np.where(sizes[im_with_separated_blobs] >= min_size, im, 0)

The key here is to rely on the indexing of a numpy array with a 2D array. sizes[im_with_separated_blobs] is a 2D numpy array with the same shape as im_with_separated_blobs, but where every value has been replaced by sizes[value], i.e. the size of that blob.

2 of 4
2

Removing small connected components by area is called area opening. OpenCV does not have this as a function, it can be implemented as shown in other answers. But most other image processing packages will have an area opening function.

For example using 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)

For example using DIPlib:

import diplib as dip

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

PS: The DIPlib implementation is noticeably faster. Disclaimer: I'm an author of DIPlib.

🌐
scikit-image
scikit-image.org › docs › stable › auto_examples › filters › plot_tophat.html
Removing small objects in grayscale images with a top hat filter — skimage 0.26.0 documentation
This example shows how to remove small objects from grayscale images. The top-hat transform [1] is an operation that extracts small elements and details from given images.
🌐
Data Carpentry
datacarpentry.github.io › image-processing › instructor › 08-connected-components.html
Image Processing with Python: Connected Component Analysis
March 20, 2026 - To remove the small objects from the labeled image, we change the value of all pixels that belong to the small objects to the background label 0.
🌐
Pydocs
pydocs.github.io › p › skimage › 0.17.2 › api › skimage.morphology.misc.remove_small_objects
skimage.morphology.misc.remove_small_objects
Expects ar to be an array with labeled objects, and removes objects smaller than min_size. If :None:None:`ar` is bool, the image is first labeled.
🌐
woteq
woteq.com › home › how to remove small objects using scikit-image morphology
How to remove small objects using scikit-image morphology - woteq Softwares
October 12, 2025 - Now, let’s use the remove_small_objects function to clean our image: # Remove small objects (components with fewer than 50 pixels) cleaned_image = morphology.remove_small_objects(sample_image, min_size=50) # Optional: Remove small holes as well cleaned_image = morphology.remove_small_hol...
🌐
CSDN
devpress.csdn.net › python › 62fe014d7e66823466192f4f.html
How to remove small connected objects using OpenCV_python_Mangs-Python
August 18, 2022 - # 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((output.shape)) # 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