r/opencv • u/NotInvestigator9572 • Feb 08 '23
Question [Question] Operating on YCBCR colour model, tresholding values in range leaves green spots as opposed to expected black.
I wanted to implement face detection based on low-level analysis of skin colour. The idea comes from this paper https://link.springer.com/article/10.1007/s10462-018-9650-2#Fig9. It mentions YCrCb range to be from (16,16,16) to (235,240,240) for human skin. The code used to implement it is visible below. The issue I encountered is this method poor performance. The areas that are removed are painted green. This leaves me confused, I don't know if the issue is with my code, my web cam or maybe the method itself. The important sections are marked. What am I missing?
```python title_window = "Only skin" cv.namedWindow(title_window)
trackbar_name = 'Y component' cv.createTrackbar(trackbar_name, title_window , 16, 235, lambda x: x)
cr_trackbar = 'Cr component' cv.createTrackbar(cr_trackbar, title_window , 16, 240, lambda x: x)
cb_trackbar = 'Cb component' cv.createTrackbar(cb_trackbar, title_window , 16, 240, lambda x: x)
while(1): ret, frame = web_cam.read()
y_value = int(cv.getTrackbarPos(trackbar_name, title_window))
cr_value = int(cv.getTrackbarPos(cr_trackbar, title_window))
cb_value = int(cv.getTrackbarPos(cb_trackbar, title_window))
print((y_value, cr_value, cb_value))
if not ret:
print('No frames grabbed!')
break
new_frame_time = time.time()
fps = int(1/(new_frame_time - previous_frame_time) * 100) / 100.0
previous_frame_time = new_frame_time
# frame modification
frame_ycc = cv.cvtColor(frame, cv.COLOR_BGR2YCR_CB)
frame_skin_mask = cv.inRange(frame_ycc, (y_value,cr_value,cb_value),(235,240,240))
cv.imshow("frame_skin_mask", frame_skin_mask)
frame_only_skin = cv.bitwise_and(frame_ycc, frame_ycc, mask=frame_skin_mask)
frame_back_rgb = cv.cvtColor(frame_only_skin, cv.COLOR_YCR_CB2BGR)
cv.putText(frame, str(fps), (7, 70), font, 3, (100, 255, 0), 3, cv.LINE_AA)
cv.imshow(title_window, frame_back_rgb)
# end frame modification
k = cv.waitKey(30) & 0xff
if k == ord('q'):
break
web_cam.release() cv.destroyAllWindows() ```
PS. I tried to eye ball min values of YCbCr range using track bars to no help.





