Preface
Recently, I want to use skin information, but I always reject skin Information Application in object detection and object recognition. I think skin information is not sufficient for this job. In fact, the ultimate realization of computer vision is a long-term process and a classic problem in the AI field. Therefore, before AI completely breaks through, any information useful to CV deserves further research, unless there is an algorithm that can work in all circumstances. Okay, you can get started with this nonsense. You have to use it if you are biased. Skin models include single Gaussian, mixed Gaussian, Bayesian, and elliptical models. After a large amount of skin statistics from previous scholars, we can know that if we map skin information to the ycrcb space, the skin pixels in the two-dimensional CrCb space are approximately an elliptical distribution. Therefore, if we get a CrCb elliptic, next time we come to a coordinate (Cr, CB), we only need to determine whether it is in the elliptic (including the boundary). If yes, it can be determined as the skin, otherwise it is a non-skin pixel.
Development Environment: opencv2.4.3 + qtcreator2.5.1
Lab Basics
This experiment is based on the short article a super-simple skin detector in opencv. In this article, we first provide a reasonable elliptic, that is, the ellipse can represent the distribution of CrCb in most people's skin information. The elliptical distribution is as follows:
It is interesting because we use an image to store the elliptic above, rather than simply using an elliptical mathematical equation. The image is a binary image, that is, the interior of the elliptical area is white, and the rest is black. So when it needs to determine its pixel point, it only needs to convert the pixel point to the CR and CB coordinates, and then find the value of the coordinate in the above ellipse. If it is not 0, it is the skin, and vice versa.
In actual code, the ellipse is drawn to the image using the painting function, just a piece of code:
ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 15.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1);
Void ellipse (MAT & IMG, Point Center, size axes, double angle, double startangle, double endangle, const scalar & color, int Thickness = 1, int linetype = 8, int shift = 0)
This function is used to draw an elliptical arc on a specified image.
The parameter image is the image to draw an elliptical image;
The center parameter is the center coordinate of the ellipse;
The axes parameter is the long half axis and short half axis of the elliptic;
The angle parameter is the rotation angle between the ellipse and the horizontal direction;
The startangle parameter indicates the starting angle of an elliptical arc relative to its own horizontal axis;
The endangel parameter indicates the end angle of an elliptical arc relative to its own horizontal axis;
The following parameters are common and will not be described.
The following shows how to draw an elliptic curve:
Lab results
Pre-detection image:
The two-value graph after skin detection using this algorithm:
Lab code and comments
Main. cpp:
# Include <opencv2/CORE/core. HPP> # include <opencv2/highgui. HPP> # include <opencv2/contrib. HPP> # include <opencv2/imgproc. HPP> # include <iostream> using namespace STD; using namespace CV; MAT input_image; MAT output_mask; MAT output_image; void main () {videocapture cam (0); If (! Cam. isopened () return; namedwindow ("input image"); namedwindow ("output mask"); namedwindow ("output image "); /* elliptical skin model */MAT skincrcbhist = mat: zeros (SIZE (256,256), cv_8uc1); ellipse (skincrcbhist, point (113,155.6), size (23.4, 15.2 ), 43.0, 0.0, 360.0, scalar (255,255,255),-1); While (true) {cam> input_image; If (input_image.empty () return; MAT ycrcb_image; output_mask = mat:: zeros (input_image.size (), cv_8uc1); cvtcolor (input_image, ycrcb_image, watermark); // first convert to ycrcb space for (INT I = 0; I <input_image.cols; I ++) // use an elliptical skin model for Skin Detection (Int J = 0; j <input_image.rows; j ++) {vec3b ycrcb = ycrcb_image.at <vec3b> (J, i); If (skincrcbhist. at <uchar> (ycrcb [1], ycrcb [2])> 0) output_mask.at <uchar> (J, I) = 255;} input_image.copyto (output_image, output_mask ); imshow ("input image", input_image); imshow ("output mask", output_mask); imshow ("output image", output_image); output_image.setto (0 ); if (27 = waitkey (30) return ;}
Experiment summary:The skin's elliptical model can indeed be used for skin detection. Once confirmed, the elliptical model can be used for skin detection.
References:
A super-simple skin detector in opencv
Skin Detection and connection domain identification to overcome the impact of light
Http://docs.opencv.org/modules/core/doc/drawing_functions.html? Highlight = ellipse # cv. Ellipse