Troubleshooting
I'm trying to detect skin in images using opencv (new to it), but I managed to get SOME part of the skin to be detected, but it all seems to create some noise in the image. Here's the original image:
The result of my code:
Code that prides itself on 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 can I fix the code to detect the remaining skin in the image and get rid of the noise?
I am using Java with OpenCV 3.0.0.
Since you are using findBiggestConour()
I think you are hitting the greatest match, not all of them. Since the largest contour is the one shown in the second image.
Just to add to what JanSLO said here above, I tried your code and instead of drawing only the largest outline, I drew all the outlines 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);
I am pleasantly surprised with the result as it is such a simple piece of code. More advanced pixel-based detection techniques include creating a probabilistic model of skin pixels using training data and using that model to classify whether a given pixel is skin or not.