0
votes

I trying to do skin color detection in Opencv.

1) First i converted the image into HSV from RGB

cvCvtColor(frame, hsv, CV_BGR2HSV);

2) Than i had applied skin color threshold in the HSV image

cvInRangeS(hsv, hsv_min, hsv_max, mask); // hsv_min & hsv_max are the value for skin detection

3) So it generates the mash which has only skin color but in Black & white image, so i converted that image in to RGB

 cvCvtColor(mask, temp, CV_GRAY2RGB);

4) so now i want the skin color in only RGB value.

for(c = 0; c <  frame -> height; c++) {
            uchar* ptr = (uchar*) ((frame->imageData) + (c * frame->widthStep));
            uchar* ptr2 = (uchar*) ((temp->imageData) + (c * temp->widthStep));
            for(d = 0; d < frame -> width; d++) {
                if(ptr2[3*d+0] != 255 && ptr2[3*d+1] != 255 && ptr2[3*d+2] != 255 && ptr2[3*d+3] != 255 ){
                    ptr[3 * d + 0] = 0;
                    ptr[3 * d + 1] = 0;
                    ptr[3 * d + 2] = 0;
                    ptr[3 * d + 3] = 0;
                }   
            }
        }

now i am not getting the image that i want actually that has only skin color in RGB.

Any Solution,

Thanks

enter image description here

1st Original Image 2nd Skin Detected Image in Black & White 3rd Output (Not Actual)

2
please do not use the outdated c-api, but the c++ one instead. - berak
ohk will in future. but any solution on this ? - mf_starboi_8041

2 Answers

4
votes

you're already quite close.

given, you have a 3 channel mask already:

Mat mask, temp;
cv::cvtColor(mask, temp, CV_GRAY2RGB);

all you need to do is combine it with your original image to mask out all non-skin color:

(and no, don't write [error prone] loops there, better rely on the builtin functionality !)

Mat draw = frame & temp; // short for bitwise_and()

imshow("skin",draw);
waitKey();
2
votes

Alternatively, without having to convert mask to RGB, you could .copyTo() passing the mask parameter

cv::cvtColor(inputFrame, hsv, CV_BGR2HSV);
cv::inRange(hsv, hsv_min, hsv_max, mask);

cv::Mat outputFrame;
inputFrame.copyTo(outputFrame, mask);