기본 HSB 피부 감지, 네온 조명


14

나는 이것이 올바른 장소가되기를 바란다. 다른 한편으로 내 실수에 대해 유감스럽게 생각하고 나에게 더 좋은 사이트를 알려줍니다.

일부 hsb 이미지 범위를 사용하여 매우 간단한 피부 감지기를 구현하려고합니다. 여기여기에 설명 된 접근 방식을 사용 하고 있습니다 .

웹캠에서 비디오 소스를 사용하려고합니다. 내가 태양 조명을 사용하면 꽤 잘 작동하지만 (아주 좋지는 않지만) 네온 빛으로 작동합니다. 엉망입니다. 많은 흰색 영역이 감지되고 모든 곳에서 많은 소음이 발생합니다.

왜?

두 번째 소스에 설명 된 알고리즘을 사용하고 있습니다 .

  1. 이미지 변환 HSV 색 공간
  2. 0 <H <38 범위에 흰색을 놓으십시오
  3. 필터 팽창
  4. 침식 필터
  5. 블러 필터

여기에 이미지 설명을 입력하십시오

답변:


10

이것은 실제로 HSV가 아닌 RGB의 간단한 생성 모델을 사용하면 더 잘 작동 할 수 있습니다.

  1. 피부가있는 훈련 이미지 또는 여러 훈련 이미지를받습니다.
  2. 스킨 픽셀 수동 선택 (예 : 이진 마스크 ​​만들기)
  3. RGB에서 피부 톤의 평균 및 공분산을 계산합니다 (각각 3 요소 벡터 여야 함).
  4. 알 수없는 픽셀의 경우 공분산을 사용하여 평균과의 거리에서 Mahalanobis 거리를 계산합니다.
  5. 거리가 임계 값보다 작 으면 스킨으로 분류하십시오.
  6. 최상의 성능을 위해 임계 값을 조정하십시오.

미디엄미디엄미디엄=' 3 x 3입니다.

Edit2 : 얻는 값이 너무 큰 것 같습니다. 최대 공분산을 얻으려면 다음 행렬을 만듭니다.

255 255 255
 0   0   0

그 공분산을 계산합니다. 모든 값이 약 32513 인 행렬을 가져와야합니다. 따라서 픽셀 값의 범위가 0에서 255 사이인지 확인하고 플로트 또는 배로 올바르게 복사해야합니다. Mahalanobis 거리는 분산 단위로되어 있으므로 숫자가 작아야합니다. 피부 분류 기준은 아마도 4보다 작아야합니다.


이미지에서 opencv를 사용하여 3x3 공분산 행렬을 얻는 방법을 이해하는 데 문제가 있습니다.
nkint

@nkint, 수정 된 답변을 참조하십시오.
Dima

큰 확인. 5 줄로 공분산이 무엇인지 이해하게 만들었습니다. 감사. 효과가있다. 그러나 결과를 저장하는 데 문제가 있습니다. 내가 0-255의 픽셀을 가지고 있다면 Mahalanobis 거리에 대해 어떤 종류의 숫자를 기대해야합니까? 내가 8-uint에 그들을 저장하면 그것은 피부의 작은 부분을 차지합니다, 내가 32-float에 저장하면 강한 백색 잡음을 얻습니다
nkint

예, 공분산 행렬이 다음과 같기 때문에 내가 잘못한 것 같습니다. [10913058.00000000, 7046611.50000000, 3290781.50000000; 7046611.50000000, 4811646.00000000, 2225078.00000000; 3290781.50000000, 2225078.00000000, 1387631.87500000]
nkint

1
공분산을 3D에서 타원체를 정의하는 것으로 생각할 수 있습니다. Matlab에서 시각화 할 수는 있지만 많은 작업이 필요할 수 있습니다. 또는 타원체의 2D 투영을 볼 수도 있지만 약간의 작업이 필요합니다.
Dima

4

네온 조명이 적용될 때 HSV 색상에서 얻은 다른 값을 고려 하십시오 . 편차의 예는 여기에 있습니다 . 이 값에 맞게 알고리즘을 조정하십시오.

여기 가 피부를 감지하는 또 다른 알고리즘, 그리고 조명 조건을 검출 당신이 사용할 수있는 이 일을 .

또 다른 알고리즘, 피부 탐지와 관련,하지만 너무 많은 네온 빛의 효과와 관련이없는이며, 이 중 하나 .


2

지금까지 얻은 답변은 좋은 대체 방법을 가리키고 있지만 초기 알고리즘과 같은 것을 사용하는 데 관심이 있다면 수정하기가 어렵지 않습니다. OpenCV의 HSV 특성에 맞게 조정하면됩니다. 별난 결과를 얻었을 때 임계 값을 선택하거나 픽셀을 변환하는 데 HSV의 일반적인 숫자 표현 중 하나를 사용했다고 가정합니다.

OpenCV는 발견 한 대부분의 다른 소스와 다르게 HSV를 나타냅니다.

  • 가장 큰 차이점은 w / r / t 색조입니다. OpenCV는 색조를 0에서 179 사이의 범위로 나타냅니다. 거의 모든 것이 다른 정보를 유지하기 위해 행잉 비트를 사용하는 경우 0-255입니다.
  • 다른 차이점 : 포화 측정은 표준과 비교하여 반전됩니다. 따라서 255 채도는 흰색 대신 opencv에서 밝음을 의미합니다 (참고로, 우리는 다시 255로 돌아갑니다. 색조는 0-180입니다. 아마도 '바퀴'표시 때문입니까?)

아마 당신을 돕기에는 너무 늦었지만 그것은 흥미로운 질문이었고 다른 누군가가 같은 문제를 겪을 수도 있습니다.


-1
import sys
import numpy
import cv2

cap = cv2.VideoCapture(0)
while(1):
    _, im = cap.read()

    im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)

    skin_ycrcb_mint = numpy.array((0, 133, 77))
    skin_ycrcb_maxt = numpy.array((255, 173, 127))
    skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)

    cv2.imshow("Second Image", skin_ycrcb) # Second image
    contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE)
    for i, c in enumerate(contours):
        area = cv2.contourArea(c)
            if area > 1000:
                cv2.drawContours(im, contours, i, (255, 0, 0), 3)
    cv2.imshow("Final Image", im)         # Final image
    cv2.waitKey(1)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.