OpenCV detektiert die Hautfarbe unveränderlich bei Beleuchtungsänderungen


8

Ich muss die Hautfarbe unabhängig von der Beleuchtung erfassen. Ich habe die folgenden Kriterien verwendet (mit hsv und rgb), aber es funktioniert nicht:

int h = get_hue(...);
int s = get_saturation(...);
int r = get_red_component(...);
int g = get_green_component(...);
int b = get_blue_component(...);

if ((h<38)&&(h>6)&&(s>0.23)&&(s<0.68)){
    // skin color
}
else if ((r>95) && (g>40) && (b>20) && 
         ((maximum(r,g,b)-minimum(r,g,b))>15) && 
         (abs(r-g)>15)&&(r>g)&&(r>b)){
   // also skin color
}

Es funktioniert morgens, wenn meine Haut beleuchtet ist, aber abends funktioniert es nicht.

Jede Hilfe wird geschätzt. Danke im Voraus. (PS - meine Haut ist nicht weiß.)


2
Könnten Sie Beispielbilder bereitstellen und die gewünschte Ausgabe vielleicht etwas besser beschreiben? Möchten Sie Bildpixel in Nicht-Skin- und Skin- Klassen "klassifizieren" ? Könnten Sie auch versuchen, Ihre Kriterien zu rechtfertigen, vielleicht ist es nicht so schlimm, aber es würde uns helfen, es zu verbessern, wenn wir verstehen würden, wie Sie darauf gekommen sind.
Penelope

2
Dies könnte hilfreich sein (dh zum Entfernen von Beleuchtungseffekten zuerst): dsp.stackexchange.com/a/459/35
Datageist

Diese beiden Kriterien habe ich gerade beim Googeln erhalten und ja, ich muss Haut von Nicht-Hautbereichen unterscheiden
Roney Island


1
Hier ist eine alte Frage von mir, vielleicht könnte es helfen: dsp.stackexchange.com/questions/1625/…
nkint

Antworten:


4

Nach meiner Erfahrung ist die beste Methode dafür, es in den Lab-Farbraum zu konvertieren. L repräsentiert das Licht und a und b sind lichtunabhängig. OpenCV unterstützt die Konvertierung von Lab-Farbskalen.


Ich habe die gleiche Bemerkung im Handbuch zur Gesichtserkennung (Springer) gesehen. Das Labor sollte einen besseren Farbraum haben.
Sansuiso

2

Für diesen speziellen Fall empfehle ich, das LAB Color-Modell nachzulesen.

Lesen Sie in Bezug auf das LAB-Farbmodell Delta E. Der Abstand zwischen zwei Farben. Weitere Details zum Farbraum finden Sie hier: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

Ich habe das LAB-Farbmodell noch nie über OpenCV versucht, da die Konvertierung von RGB nach LAB und zurück mühsam ist (erfordert einen sofortigen Schritt).

Aber ich habe Delta E auf MatLab mit großem Erfolg erkundet. Sie müssen zuerst den Skin auswählen, einen kleinen ROI auf das Video / Bild zeichnen und das Programm findet genau den gleichen Farbton wie der Skin, den Sie über den ROI ausgewählt haben.

Eine andere Möglichkeit ist auch die Textur zu untersuchen. Eine kurze Vorschau hier: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JhJs = 0CDUQ6AEwAQ # v = onepage & q = skin% 20thresholding% 20from% 20texture & f = false

Dies ist im Grunde ein Training einer Bilddatenbank. Kommentieren Sie hier, wenn Sie Hilfe beim Trainieren der Bilddatenbank oder beim Konvertieren von ColorSpace benötigen. Ein wenig beschäftigt, daher sind die Antworten nur Vorschläge, die Sie machen können. Prost.


1

Versuche dies:

''' Detect human skin tone and draw a boundary around it.
Useful for gesture recognition and motion tracking.

Inspired by: http://stackoverflow.com/a/14756351/1463143

Date: 08 June 2013
'''

# Required moduls
import cv2
import numpy

# Constants for finding range of skin color in YCrCb
min_YCrCb = numpy.array([0,133,77],numpy.uint8)
max_YCrCb = numpy.array([255,173,127],numpy.uint8)

# Create a window to display the camera feed
cv2.namedWindow('Camera Output')

# Get pointer to video frames from primary device
videoFrame = cv2.VideoCapture(0)

# Process the video frames
keyPressed = -1 # -1 indicates no key pressed

while(keyPressed < 0): # any key pressed has a value >= 0

    # Grab video frame, decode it and return next video frame
    readSucsess, sourceImage = videoFrame.read()

    # Convert image to YCrCb
    imageYCrCb = cv2.cvtColor(sourceImage,cv2.COLOR_BGR2YCR_CB)

    # Find region with skin tone in YCrCb image
    skinRegion = cv2.inRange(imageYCrCb,min_YCrCb,max_YCrCb)

    # Do contour detection on skin region
    contours, hierarchy = cv2.findContours(skinRegion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # Draw the contour on the source image
    for i, c in enumerate(contours):
        area = cv2.contourArea(c)
        if area > 1000:
            cv2.drawContours(sourceImage, contours, i, (0, 255, 0), 3)

    # Display the source image
    cv2.imshow('Camera Output',sourceImage)

    # Check for user input to close program
    keyPressed = cv2.waitKey(1) # wait 1 milisecond in each iteration of while loop

# Close window and camera after exiting the while loop
cv2.destroyWindow('Camera Output')
videoFrame.release()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.