wake-up-neo.com

Wie entferne ich mit opencv Haare von Hautbildern?

Ich arbeite mit der Erkennung von Hautflecken. Dafür arbeite ich mit einer Reihe von Bildern mit unterschiedlichen Geräuschen. Eines dieser Geräusche sind die Haare, da ich Bilder mit Haaren über dem Fleckenbereich (ROI) habe. Wie kann man diese Arten von Bildrauschen verringern oder entfernen?

Der folgende Code verringert den Bereich, in dem sich Haare befinden, entfernt jedoch keine Haare, die sich über dem interessierenden Bereich (ROI) befinden.

import numpy as np
import cv2

IMD = 'IMD436'
# Read the image and perfrom an OTSU threshold
img = cv2.imread(IMD+'.bmp')
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((2,2),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.imwrite(IMD+'.png', res)
cv2.imshow('img', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

 enter image description here

Ausgang:  enter image description here

Wie kann ich Haare von oben in meiner Region entfernen?

Verwendete Bilder:  enter image description here

 enter image description here

 enter image description here

6
Carlos Diego

Ich antworte auf Ihren Tag in einem verwandten Beitrag. Wie ich verstehe, arbeiten Sie und ein anderer Colege an einem Projekt, um die Maulwürfe auf der Haut zu lokalisieren. Ich glaube, ich habe einem oder vielleicht auch schon beiden bei ähnlichen Fragen geholfen und bereits erwähnt, dass das Entfernen der Haare eine sehr schwierige und schwierige Aufgabe ist. Wenn Sie die Haare auf dem Bild entfernen, verlieren Sie Informationen und Sie können diesen Teil des Bildes nicht ersetzen (kein Programm oder Algorithmus kann erraten, was sich unter den Haaren befindet - aber es kann eine Abschätzung machen). Was Sie tun könnten, wie ich in anderen Beiträgen erwähnt habe, und ich denke, es wäre der beste Ansatz, um über tiefe neuronale Netzwerke zu lernen und Ihre eigenen für die Haarentfernung zu entwickeln. Sie können "Wasserentfernung tiefes neuronales Netzwerk" googeln und sehen, was ich meine. Davon abgesehen scheint Ihr Code nicht alle ROIs (die Mole) zu extrahieren, die Sie im Beispielbild angegeben haben. Ich habe ein weiteres Beispiel gemacht, wie man die Maulwürfe besser extrahieren kann. Grundsätzlich sollten Sie vor dem Umwandeln in Binärdateien einen Abschluss durchführen, um bessere Ergebnisse zu erzielen.

Für den zweiten Teil - Haarentfernung: Wenn Sie kein neuronales Netzwerk erstellen möchten, könnte die alternative Lösung darin bestehen, die mittlere Pixelintensität der Region zu berechnen, in der sich der Maulwurf befindet. Dann iterieren Sie durch jedes Pixel und legen Sie einige Kriterien fest, wie stark sich das Pixel vom Mittelwert unterscheiden kann. Haare scheinen mit Pixeln dargestellt zu werden, die dunkler als der Maulwurfbereich sind. Wenn Sie das Pixel finden, ersetzen Sie es durch das Nachbarpixel, das nicht in dieses Kriterium fällt. In dem Beispiel habe ich eine einfache Logik erstellt, die nicht mit jedem Bild funktioniert, sondern als Beispiel dienen kann. Um eine voll funktionsfähige Lösung zu erhalten, sollten Sie einen besseren, komplexeren Algorithmus erstellen, der vermutlich einige Zeit in Anspruch nimmt. Hoffe es hilft ein bisschen! Prost!

import numpy as np
import cv2
from PIL import Image

# Read the image and perfrom an OTSU threshold
img = cv2.imread('skin2.png')
kernel = np.ones((15,15),np.uint8)

# Perform closing to remove hair and blur the image
closing = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel, iterations = 2)
blur = cv2.blur(closing,(15,15))

# Binarize the image
gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)


# Search for contours and select the biggest one
_, 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)

# Calculate the mean color of the contour
mean = cv2.mean(res, mask = mask)
print(mean)

# Make some sort of criterion as the ratio hair vs. skin color varies
# thus makes it hard to unify the threshold.
# NOTE that this is only for example and it will not work with all images!!!

if mean[2] >182:
    bp = mean[0]/100*35
    gp = mean[1]/100*35
    rp = mean[2]/100*35   

Elif 182 > mean[2] >160:
    bp = mean[0]/100*30
    gp = mean[1]/100*30
    rp = mean[2]/100*30

Elif 160>mean[2]>150:
    bp = mean[0]/100*50
    gp = mean[1]/100*50
    rp = mean[2]/100*50

Elif 150>mean[2]>120:
    bp = mean[0]/100*60
    gp = mean[1]/100*60
    rp = mean[2]/100*60

else:
    bp = mean[0]/100*53
    gp = mean[1]/100*53
    rp = mean[2]/100*53

# Write temporary image
cv2.imwrite('temp.png', res)

# Open the image with PIL and load it to RGB pixelpoints
mask2 = Image.open('temp.png')
pix = mask2.load()
x,y = mask2.size

# Itearate through the image and make some sort of logic to replace the pixels that
# differs from the mean of the image
# NOTE that this alghorithm is for example and it will not work with other images

for i in range(0,x):
    for j in range(0,y):
        if -1<pix[i,j][0]<bp or -1<pix[i,j][1]<gp or -1<pix[i,j][2]<rp:
            try:
                pix[i,j] = b,g,r
            except:
                pix[i,j] = (int(mean[0]),int(mean[1]),int(mean[2]))
        else:
            b,g,r = pix[i,j]

# Transform the image back to cv2 format and mask the result         
res = np.array(mask2)
res = res[:,:,::-1].copy()
final = cv2.bitwise_and(res, res, mask=mask)

# Display the result
cv2.imshow('img', final)
cv2.waitKey(0)
cv2.destroyAllWindows()

 enter image description here

 enter image description here

 enter image description here

 enter image description here

1
kavko

Sie können die folgenden Schritte ausführen, um zumindest eine Roadmap zur richtigen Lösungsimplementierung zu erhalten:

  1. Finden Sie die Haarregion durch adaptives lokales Thresholding - Otsus Methode oder eine andere Methode. Ich denke, "lokales Thresholding" oder sogar "Histogrammausgleich und dann globales Thresholding" werden die Haarregionen finden.
  2. Um die Haarbereiche zu füllen, verwenden Sie die "Textur-Synthese", um die Haut zu synthetisieren. Die Textur des Haarbereichs ist ähnlich.

Eine gute und einfache Methode für die Textursynthese ist beschrieben in "AA Efros und TK Leung, Textursynthese durch nichtparametrische Probenahme", in Proceedings der Internationalen Konferenz für Computer Vision (ICCV), Kerkyra, Griechenland, 1999 ". Die Textsynthese liefert ein besseres Ergebnis als die Mittelwertbildung oder Medianfilterung, um die Pixel im Haarbereich abzuschätzen.

Schauen Sie sich auch dieses Dokument an, es sollte Ihnen sehr helfen:

http://link.springer.com/article/10.1007%2Fs00521-012-1149-1?LI=true

2
Abdul Rehman