i have a binary image and I want to remove small white dots from the image using opencv python.You can refer to my problem here enter link description here
My original image is
i want the output image as:
But image processing is a bit complex and beginners get bored in their first approach. So in this article, we have a very basic image processing python program to count black dots in white surface and white dots in the black surface using OpenCV functions ( cv2.imread, cv2.threshold, cv2.findContours, cv2.contourArea ).
I have used scipy.ndimage.label function to detect them. Now you can delete the small object by defining a criteria of size of object by counting the number of pixels each object has in your image. From this you can delete those object which has size smaller then certain threshold.
The basic algorithm for removing contours from an image goes something like this: Step 1: Detect and find contours in your image. Step 2: Loop over contours individually. Step 3: Determine if the contour is “bad” and should be removed according to some criterion. Step 4: Accumulate a mask of “bad” contours to be removed.
Connected Components might be closer to what you want. It finds all the blobs of white pixels. You simply filter the ones that have too small an area, and it keeps both the inner and outer boundaries. Which one is best depends on what exactly you're doing with them, but both should work.
This seems to work using connected components in Python Opencv.
#!/bin/python3.7
import cv2
import numpy as np
src = cv2.imread('img.png', cv2.IMREAD_GRAYSCALE)
# convert to binary by thresholding
ret, binary_map = cv2.threshold(src,127,255,0)
# do connected components processing
nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_map, None, None, None, 8, cv2.CV_32S)
#get CC_STAT_AREA component as stats[label, COLUMN]
areas = stats[1:,cv2.CC_STAT_AREA]
result = np.zeros((labels.shape), np.uint8)
for i in range(0, nlabels - 1):
if areas[i] >= 100: #keep
result[labels == i + 1] = 255
cv2.imshow("Binary", binary_map)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite("Filterd_result.png, result)
See here
You can simply use image smoothing techniques like gaussian blur, etc. to remove noise from the image, followed by binary thresholding like below:
img = cv2.imread("your-image.png",0)
blur = cv2.GaussianBlur(img,(13,13),0)
thresh = cv2.threshold(blur, 100, 255, cv2.THRESH_BINARY)[1]
cv2.imshow('original', img)
cv2.imshow('output', thresh)
cv2.waitKey(0)
cv2.destroyAllWinsdows()
output:
Read about different image smoothing/blurring techniques from here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With