照明が変化するOpenCVの皮膚色不変


8

照明とは無関係に肌の色をとらなければなりません。次の基準を使用しましたが(hsvとrgbを使用)、機能しません。

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
}

それは私の肌が照らされている朝には機能しますが、夕方までには機能しません。

どんな助けでもありがたいです。前もって感謝します。(PS-私の肌は白くありません。)


2
サンプル画像を提供できますか、そしておそらく望ましい出力をもう少しよく説明できますか?イメージピクセルをスキンクラスとスキンクラスに「分類」しますか?また、基準を試して正当化してもらえますか。それほど悪くはないかもしれませんが、それがどのように考え出されたかを理解できれば、改善に役立ちます。
ペネロペ2012年

2
これは役立つ場合があります(つまり、最初に照明の効果を削除するため):dsp.stackexchange.com/a/459/35
datageist

これら2つの基準は、グーグルで取得したばかりであり、そうです。皮膚と皮膚以外の領域を区別する必要があります
Roney Island


1
ここに私の古い質問は、多分それは助けることができる:dsp.stackexchange.com/questions/1625/...
nkint

回答:


4

私の経験では、このための最良の方法は、Labの色空間に変換することです。Lは光を表し、aとbは光に依存しません。OpenCVはLabカラースケール変換をサポートしています。


顔認識ハンドブック(Springer)でも同じ発言を見ました。ラボはより良い色空間であるべきです。
sansuiso 2013年

2

この特別なケースについては、LABカラーモデルを読むことをお勧めします。

LABカラーモデルについては、Delta Eを参照してください。2色間の距離。色空間の詳細については、こちらをご覧くださいhttp : //www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

OpenCVを介してLABカラーモデルを試したことがありません。これは、RGBからLABに変換して戻すのが面倒だからです(すぐに手順が必要です)。

しかし、私はMatLabでDelta Eを探索して大きな成功を収めました。最初に肌を選択し、ビデオ/画像に小さなROIを描画する必要があります。プログラムは、ROIを介して選択した肌とまったく同じ色調をすべて見つけます。

別のオプションもテクスチャを調べることです。ここでの短いプレビュー:http : //books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JB979J-qAAQQQAQAQAQUQAQAQQQAQAQQAQQQA = 0CDUQ6AEwAQ#v = onepage&q = skin%20thresholding%20from%20texture&f = false

これは基本的に画像データベースのトレーニングです。画像データベースのトレーニングやColorSpaceの変換についてサポートが必要な場合は、ここにコメントしてください。少し忙しいので、答えはあなたができる提案にすぎません。乾杯。


1

これを試して:

''' 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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.