How to remove image noise using opencv - python?

后端 未结 1 1408
孤街浪徒
孤街浪徒 2021-02-06 09:01

I am working with skin images, in recognition of skin blemishes, and due to the presence of noises, mainly by the presence of hairs, this work becomes more complicated.

1条回答
  •  暖寄归人
    2021-02-06 09:53

    This is quite a difficult task becasue the hair goes over your ROI (mole). I don't know how to help remove it from the mole but I can help to remove the backround like in the picture without hairs. For the removal of hairs from mole I advise you to search for "removing of watermarks from image" and "deep neural networks" to maybe train a model to remove the hairs (note that this task will be quite difficult).

    That being said, for the removing of background you could try the same code that you allready have for detection without hairs. You will get a binary image like this:

    Now your region is filled with white lines (hairs) that go over your contour that is your ROI and cv2.findContours() would also pick them out because they are connected. But if you look at the picture you will find out that the white lines are quite thin and you can remove it from the image by performing opening (cv2.morphologyEx) on the image. Opening is erosion followed by dilation so when you erode the image with a big enough kernel size the white lines will dissapear:

    Now you have a white spot with some noises arround which you can connect by performing another dilation (cv2.dilate()):

    To make the ROI a bit smoother you can blur the image cv2.blur():

    After that you can make another treshold and search for the biggest contour. The final result:

    Hope it helps a bit. Cheers!

    Example code:

    import numpy as np
    import cv2
    
    # Read the image and perfrom an OTSU threshold
    img = cv2.imread('hair.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    
    # Remove hair with opening
    kernel = np.ones((5,5),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
    
    # Combine surrounding noise with ROI
    kernel = np.ones((6,6),np.uint8)
    dilate = cv2.dilate(opening,kernel,iterations=3)
    
    # Blur the image for smoother ROI
    blur = cv2.blur(dilate,(15,15))
    
    # Perform another OTSU threshold and search for biggest contour
    ret, thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    _, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    cnt = max(contours, key=cv2.contourArea)
    
    # Create a new mask for the result image
    h, w = img.shape[:2]
    mask = np.zeros((h, w), np.uint8)
    
    # Draw the contour on the new mask and perform the bitwise operation
    cv2.drawContours(mask, [cnt],-1, 255, -1)
    res = cv2.bitwise_and(img, img, mask=mask)
    
    # Display the result
    cv2.imshow('img', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    0 讨论(0)
提交回复
热议问题