1 | initial version |
A real skin detector is a difficult process. But if you only want to be able to filter some face detection, you could use the inRange function. You could find many values on the web, especially in the YCrCb color space, something like (133, 173) and (77, 127) should work.
There is also an interesting technic with a bit of simple learning that could work in your case. Create a map of color reported as skin and color reported as non skin:
int skin_colors[255][255];
and for each pixels of the detected boxes, create some manual mask for the skin color. Then compute the statistics of color, and normalize it. Do the same for non skin color, and compare the values for each pixels. A simple approach could be like that:
for( r = 0 ; r < rows ; ++r )
{
for( c = 0 ; c < cols ; ++c )
{
cv::Vec3b val = img.at< cv::Vec3b >( r, c );
if( skin_colors[ val.x ][ val.y ] > non_skin_colors[ val.x ][ val.y ] )
{
// this pixel is a color pixel
}
}
}
And only keep detected boxes with "enough" skin pixels.