Question

I've been doing some skin detection but can't get a smooth one. The image below contains the input (left) and output (right) using the code also attached below. Now, the desired output should have been the bottom most image (the one that is smooth on the edges and doesn't have holes within). How do I achieve this output? A sample code on where to start would be of great help.

Input (left) and Incorrect output (right):

enter image description here

Desired output:

enter image description here

Code to generate the Incorect output:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main(){
    Mat src = imread("qq.jpg");
    if (src.empty())
        return -1;
    blur( src, src, Size(3,3) );
    Mat hsv;
    cvtColor(src, hsv, CV_BGR2HSV);
    Mat bw;
    inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
    imshow("src", src);
    imshow("dst", bw);
    waitKey(0);
    return 0;
}

Modified Code (after Astor's suggestion): (the problem now is: how do you smoothen the output?)

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int findBiggestContour(vector<vector<Point> >);

int main(){
    Mat src = imread("qq.jpg");
    if (src.empty())
        return -1;
    blur( src, src, Size(3,3) );

    Mat hsv;
    cvtColor(src, hsv, CV_BGR2HSV);

    Mat bw;
    inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
    imshow("src", src);
    imshow("dst", bw);

    Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours( bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    int s = findBiggestContour(contours);

    Mat drawing = Mat::zeros( src.size(), CV_8UC1 );
    drawContours( drawing, contours, s, Scalar(255), -1, 8, hierarchy, 0, Point() );

    imshow("drw", drawing);
    waitKey(0);
    return 0;
}

int findBiggestContour(vector<vector<Point> > contours){
    int indexOfBiggestContour = -1;
    int sizeOfBiggestContour = 0;
    for (int i = 0; i < contours.size(); i++){
        if(contours[i].size() > sizeOfBiggestContour){
            sizeOfBiggestContour = contours[i].size();
            indexOfBiggestContour = i;
        }
    }
    return indexOfBiggestContour;
}
Was it helpful?

Solution

You should use findContours to detect the biggest contour and after this draw founded contour with fill parameter -1 using method drawContours. Here's useful link: http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html

OTHER TIPS

To improve the smoothness of the output, or in other words to reduce the black holes in the detected area try performing morphological operations on the resulting image. Following documentation explains the eroding and dilating functions in opencv. http://docs.opencv.org/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top