구현 알고리즘
1. global luminance Enhansment 적용(어두운 곳에서 이미지가 촬영되는 경우 적용)

위의 알고리즘은 논문에서는 지역적으로 적용하여 어두운 이미지를 밝게 만들지만 능력이 부족하여 global하게 위의 알고리즘을 적용하였다. 아래 코드는 global luminance Enhansment 코드이다. 여러분은 코드와 논문을 참조하여 local luminance Enhansment를 구현해보길 바란다.
def luminence_Enhansment(src):
'''
parameter :
- src : image frame
return :
- new_hsv: image frame
'''
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
H, S, V = cv2.split(hsv)
V_N = V/255
img_size = len(V[0]) * len(V)
hist, bins = np.histogram(V.flatten(), 255,[0,255])
cdf = hist.cumsum()
if cdf[50] > img_size * 0.1:
z = 0
elif img_size * 0.1 > cdf[150]:
z = 1
elif cdf[50] <= img_size * 0.1 <= cdf[150]:
z = ((img_size*0.1)-50)/100
for i in range(0, len(H)):
for j in range(0, len(H[0])):
V_I = V_N[i, j]
V_N[i, j] = ((V_I**(0.75*z+0.25))+(0.4*(1-z)*(1-V_I))+V_I**(2-z))*0.5
V_N[i, j] = int(V_N[i, j]*255)
V_N = np.array(V_N, dtype=S.dtype)
new_hsv = cv2.merge([H, S, V_N])
new_hsv = cv2.cvtColor(new_hsv, cv2.COLOR_HSV2BGR)
return new_hsv
2. YCbCr based Skin Detection
Skin detect는 단순히 특정 YCbCr 값을 가지고 탐지를 진행하였다. 코드는 아래와 같다.
def skindetector(img):
'''
parameter :
- img : image frame
return :
- YCrCn_result : image frame
'''
#converting from gbr to YCbCr color space
img_YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
#skin color range for hsv color space
YCrCb_mask = cv2.inRange(img_YCrCb, (0, 135, 85), (255,180,135))
YCrCb_mask = cv2.morphologyEx(YCrCb_mask, cv2.MORPH_OPEN, np.ones((3,3), np.uint8))
YCrCb_result = cv2.bitwise_not(YCrCb_mask)
return YCrCb_result
응용 application
휴대폰을 들고있는 손을 예측하는 application 구현
알고리즘 설명
1. 이미지 input
2. 이미지 좌측상단, 우측상단, 좌측하단, 우측하단 4개의 image로 crop
3. 사람 손은 보통 아래에 있기 때문에 좌측하단, 우측하단 이미지를 이용해 skin detection
4. 좌측하단의 0픽셀이 더 많은 경우 오른손, 우측하단의 0픽셀이 더 많은 경우 왼손
5. 결과 출력
아래는 위의 알고리즘을 구현한 코드이다.
from . import SkinDetector
def counting_black(img):
'''
counting 0 value pixel for counting black pixels
'''
count = 0
for i in range(0, len(img)):
for j in range(0, len(img[0])):
if img[i, j] == 0:
count += 1
return count
def call_decision(img):
'''
parameters :
img = image frame
return :
left or right = black pixels / all pixels of crop_image
'right_hand' or 'left_hand' (str)
'''
height, width = img.shape[0], img.shape[1]
Enhan_img = SkinDetector.luminence_Enhansment(img)
skin_img = SkinDetector.skindetector(Enhan_img)
l_img = skin_img[height-(height//2): height, 0:width-(width//2)]
r_img = skin_img[height-(height//2): height, width-(width//2):width]
l_pixels = counting_black(l_img)
r_pixels = counting_black(r_img)
left = l_pixels/(l_img.shape[0]*l_img.shape[1])
right = r_pixels/(r_img.shape[0]*r_img.shape[1])
if l_pixels > r_pixels:
return left, 'right_hand'
elif l_pixels <= r_pixels:
return right, 'left_hand'
실행코드는 아래 github를 들어가서 실행해 보시거나 혹은 위의 코드를 베이스로 직접 구현해보시기 바랍니다.
https://github.com/22ema/ComputerVision/tree/main/SkinDetector
참고 논문
A Robust Face Detection Method Based on Skin Color and Edges
Nonlinear transfer function-based local approach for color image enhancement
'Computer Vision' 카테고리의 다른 글
LBP (Local Binary Pattern) for Face Recognition (0) | 2022.07.18 |
---|---|
OpenCV Face Detection and Recognition(얼굴 탐지 및 인식) - 1부 (0) | 2022.07.09 |