How to remove noises and hairy image lines?

Asked

Viewed 513 times

7

I’m working on hair removal on skin images. Researching the literature, the means to achieve my goal, applying some techniques of segmentation and removal of noise in images. Which I’m applying to. An example of what an image I work is this: inserir a descrição da imagem aqui

Applying the Diference of de Gaussian in the image I have the exit:

import cv2
import numpy as np


#read the input file
img = cv2.imread('014.bmp')

#run a 5x5 gaussian blur then a 3x3 gaussian blr
blur5 = cv2.GaussianBlur(img,(5,5),0)
blur3 = cv2.GaussianBlur(img,(3,3),0)

DoGim = blur5 - blur3
cv2.imwrite('014-DoG.jpg', DoGim)

inserir a descrição da imagem aqui

Then I use the morphological operator: cv2.morphologyEx to remove the noise from the image, leaving only the hair, so that I can later apply a mask to remove the hair. However, the exit both to the cv2.morphologyEx(img2gray,cv2.MORPH_OPEN,kernel) as cv2.morphologyEx(img2gray,cv2.MORPH_CLOSE,kernel) do not meet the expectation.

import numpy as np
import matplotlib.pyplot as plt
import cv2

pic = cv2.imread('014DoG.jpg')
img2gray = cv2.cvtColor(pic, cv2.COLOR_RGB2GRAY)

# Remove hair with opening
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img2gray,cv2.MORPH_OPEN,kernel)
plt.imshow(opening, cmap='gray')
plt.show()

Open: inserir a descrição da imagem aqui

Close-up: inserir a descrição da imagem aqui

Can someone help me remove these noises and remove the hairs?

1 answer

3


If you are already using morphological operations, why not directly use a lock to eliminate hairs?

You will need to know more or less their average thickness for the generation of the structuring element, or you can leave this value configurable in your system. Anyway, I suggest using a cross instead of a rectangle because it eliminates the hairs while maintaining a greater connection of "istmos" between the spots (in the later result of the limiarization).

Incidentally, I’m guessing that your interest is to detect the spot areas, so it also includes a simple example of limiarization (thresholding). I’m using the mean grayscale value (127), but you may need to make a fine-tune depending on your images.

Here’s the code (I read your own disk image, called test.png here in my example):

import numpy as np
import matplotlib.pyplot as plt
import cv2

pic = cv2.imread('teste.png')
img2gray = cv2.cvtColor(pic, cv2.COLOR_RGB2GRAY)

# Remove hair with closing and blur
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(10,10))
closing = cv2.morphologyEx(img2gray, cv2.MORPH_CLOSE, kernel)
closing = cv2.GaussianBlur(closing, (5, 5), 0)

# Thresholding for the skin patches
_,threshold = cv2.threshold(closing, 127, 255, cv2.THRESH_BINARY)

fig = plt.figure('Deteção de Pintas')

plt.subplot(131)
plt.title('Imagem original')
plt.imshow(img2gray, cmap='gray')

plt.subplot(132)
plt.title('Resultado do Fechamento')
plt.imshow(closing, cmap='gray')

plt.subplot(133)
plt.title('Resultado da Limiarização')
plt.imshow(threshold, cmap='gray')

plt.show()

And the result:

inserir a descrição da imagem aqui

P.S.: If the limiarization result is not good enough (even if it is to be used as a mask), you can try a different approach with Kmédias: https://docs.opencv.org/3.4.3/d1/d5c/tutorial_py_kmeans_opencv.html Use 3 (or 4) clusters (clusters), for example, and throw away only the pixels of the lightest cluster, keeping the original pixels of the other two clusters darker.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.