Deteksi OpenCV pada warna kulit tidak berubah dengan perubahan pencahayaan

8

Saya harus menangkap warna kulit yang tidak tergantung pada pencahayaan. Saya menggunakan kriteria berikut (menggunakan hsv dan rgb) tetapi tidak berfungsi:

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
}

Ini bekerja di pagi hari ketika kulit saya menyala tetapi pada malam hari tidak bekerja.

Bantuan apa pun akan dihargai. Terima kasih sebelumnya. (PS-kulitku tidak putih.)

Pulau Roney
sumber
2
Bisakah Anda memberikan contoh gambar, dan mungkin menggambarkan hasil yang diinginkan sedikit lebih baik? Apakah Anda ingin "mengklasifikasikan" piksel gambar ke dalam kelas non-kulit dan kulit ? Selain itu, dapatkah Anda mencoba dan membenarkan kriteria Anda, mungkin tidak terlalu buruk tetapi akan membantu kami dalam meningkatkannya jika kami memahami bagaimana Anda memunculkannya.
penelope
2
Ini mungkin membantu (yaitu untuk menghilangkan efek penerangan terlebih dahulu): dsp.stackexchange.com/a/459/35
datageist
dua kriteria ini saya baru saja dapatkan dari googling dan ya saya harus membedakan kulit dari area yang bukan kulit
Roney Island
Saya menemukan citeseerx.ist.psu.edu/viewdoc/…
Roney Island
1
di sini adalah pertanyaan lama saya, mungkin itu bisa membantu: dsp.stackexchange.com/questions/1625/…
nkint

Jawaban:

4

Dalam pengalaman saya metode terbaik untuk ini adalah mengubahnya menjadi ruang warna Lab. L mewakili cahaya, dan a dan b independen terhadap cahaya. OpenCV mendukung konversi skala warna Lab.

Vladimir Perkovic
sumber
Saya telah melihat komentar yang sama di buku pegangan Pengenalan Wajah (Springer). Lab harus menjadi ruang warna yang lebih baik.
sansuiso
2

Untuk kasus khusus ini, saya sarankan membaca pada model LAB Color.

Dan sehubungan dengan model LAB Color, baca di Delta E. Jarak antara 2 warna. Rincian lebih lanjut tentang ruang warna dapat ditemukan di sini: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

Saya belum pernah mencoba model warna LAB melalui OpenCV karena ini merepotkan untuk mengkonversi dari RGB ke LAB dan kembali (membutuhkan langkah segera).

Tetapi saya telah menjelajahi Delta E di MatLab dengan sukses besar. Anda harus memilih kulit terlebih dahulu, menggambar ROI kecil pada video / gambar dan program akan menemukan semua nada warna yang sama persis dengan kulit yang Anda pilih melalui ROI.

Pilihan lain adalah melihat ke dalam tekstur. Sebuah preview singkat di sini: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JB979_-ccyrhDJlqA&hl=en&sa=X&ei=aAuFUsHhJoWJrQfpkoCgBg&ved = 0CDUQ6AEwAQ # v = halaman web & q = skin% 20pengaturan% 20dari% 20tekstur & f = salah

Ini pada dasarnya melatih basis data gambar. Beri komentar di sini jika Anda memerlukan bantuan untuk melatih basis data gambar atau konversi ColorSpace. Agak sibuk, jadi jawabannya hanya saran yang bisa Anda lakukan. Bersulang.

rockinfresh
sumber
1

coba ini:

''' 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()
samkhan13
sumber