Hasnain
Hasnain

Reputation: 73

Remove little edges from picture in python with Opencv

I am new to OpenCv. I am trying to create a white and black cartoonist picture of person through OpenCV in python. I am kind of successful, in creating black and white cartoon type picture of person. But the problem is, I want to remove black little dots from the output image. Please help me. I want to remove these black dots as pointed in picture. Here is my code.

    image = cv2.imread('input1.jpg')
    img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    img_gray = cv2.medianBlur(img_gray, 5)
    edges = cv2.Laplacian(img_gray, cv2.CV_8U, ksize=5)
    ret,mask =cv2.threshold(edges,100,255,cv2.THRESH_BINARY_INV)
    image2 = cv2.bitwise_and(image, image, mask=mask)
    cv2.imshow("Mask", mask)

enter image description here

Upvotes: 3

Views: 5678

Answers (2)

George K
George K

Reputation: 499

You need to apply a filter to your image using OpenCV to remove the black dots (which are called "noise"). There are many 2D convolutions you can apply to the image.

Median Filter

This filter will find the median value of every pixel and its surrounding pixels. It can gather as many pixels away from the centre as you like amplifying the effect.

Gaussian Blur

You can apply another type of blurring which should remove noise, maybe not entirely but it will surely reduce it's effect. If you're working on black and white, which it seems you are, then this might actually remove noise entirely.

Edit

Try applying a median filter again after you apply the threshold, that should remove noise much better than before since the values are binary:

image = cv2.imread('input1.jpg')
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
img_gray = cv2.medianBlur(img_gray, 5)
edges = cv2.Laplacian(img_gray, cv2.CV_8U, ksize=5)
ret,mask =cv2.threshold(edges,100,255,cv2.THRESH_BINARY_INV)
image2 = cv2.bitwise_and(image, image, mask=mask)
image2 = cv2.medianBlur(image2, 3)  # this
cv2.imshow("Mask", mask)

Hope this helps!

Upvotes: 2

kavko
kavko

Reputation: 2831

You could also try to find little countours and draw them out. Something like this:

img = cv2.imread('input1.jpg')
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,220,255,0)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
number_contours = len(contours)
print(number_contours)
for i in range(0, number_contours):
    lenght = cv2.contourArea(contours[i])
    if float(1)<lenght<float(5000):
        cv2.drawContours(img, contours[i], 0, (255,255,255), 7)
cv2.imshow("image", img)
cv2.imwrite("brez_pikic.jpg", img)

enter image description here

Upvotes: 0

Related Questions