user_4685247
user_4685247

Reputation: 2995

Trouble detecting skin

I'm trying to detect skin on images using opencv (new at it) but I've managed to get SOME of the skin to be detected, however the rest seems to cause some noise on the image. Here's the original image:

original

The result of my code is:

result

The code that prouduces this:

Mat image = Imgcodecs.imread(name);

Imgproc.pyrMeanShiftFiltering(image, image, 10, 20);
Imgproc.blur(image, image, new Size(3, 3));

Mat hsv = new Mat();
Imgproc.cvtColor(image, hsv, Imgproc.COLOR_BGR2HSV);

Mat bw = new Mat();
Core.inRange(hsv, new Scalar(0, 10, 60), new Scalar(20, 150, 255), bw);

List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(bw, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE, new Point(0, 0));
int s = findBiggestContour(contours);

Mat drawing = new Mat(image.size(), CvType.CV_8UC1);
Imgproc.drawContours(drawing, contours, s, new Scalar(255), -1, 8, hierarchy, 0, new Point(0, 0));

Imgcodecs.imwrite(rename(name), drawing);

How do I fix the code to detect the remaining skin on the image and get rid of the noise?

I'm using Java with OpenCV 3.0.0.

Upvotes: 3

Views: 239

Answers (2)

koshy george
koshy george

Reputation: 680

Just to add to what JanSLO said here above, I tried your code and instead of drawing just the biggest contour, I drew all contours and got the following result.

//c++ code, not java
Mat drawing = Mat::zeros(img.size(), CV_8UC1 );
for(int i=0; i < contours.size(); ++i) {
    drawContours(drawing, contours, i, Scalar(255), 3, 8, hierarchy, 0, Point(0, 0));
}
imwrite("data/skin_detect_out.jpg", drawing);

skin_detect_out.jpg

I am pleasantly surprised at the result, since this is such a simple piece of code. More advanced pixel based skin detection methods involve making a probability model of skin pixels using training data, and using that model to classify whether a given pixel is skin or not.

Upvotes: 0

JanSLO
JanSLO

Reputation: 388

Since you're using the findBiggestConour() I think you only draw the biggest match, not all of them. Since the biggest contour happens to be the one on the second image only that is shown.

Upvotes: 1

Related Questions