这是我的代码。皮肤检测器是一个单独的类,可以进行HSV阈值处理。我已经覆盖了它。
`
using namespace std;
using namespace cv;
// Function Headers
void Display(String s);
void detectAndDisplay(Mat frame);
void drawStuff();
void showInputWindow();
void showCannyWindow();
void showContourWindow();
void FindContour(Mat skinMat);
// Global variables
cv::Rect roi_b;
cv::Rect roi_c;
int thresh = 2;
Mat img_rgb,img_gray,img_bw,canny_output,drawing;
// Copy this file from opencv/data/haarscascades to target folder
string face_cascade_name = "c:/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Face detection";
int filenumber; // Number of file to be saved
string filename;
// Function main
int main(void)
{
// Display("3.jpg");
// Load the cascade
if (!face_cascade.load(face_cascade_name))
{
printf("--(!)Error loading\n");
return (-1);
};
// Read the image file
Mat frame = imread("c:/Emma.jpg");
// for (;;)
{
// Apply the classifier to the frame
if (!frame.empty())
{
detectAndDisplay(frame);
// detect skin
SkinDetector mySkinDetector;
Mat skinMat;
skinMat= mySkinDetector.getSkin(frame);
imshow("Skin Image",skinMat);
// for contour detection
img_rgb = skinMat;
blur( img_rgb, img_rgb, Size(3,3) );
cvtColor(img_rgb,img_gray,CV_RGB2HSV);
// showInputWindow();
drawStuff();
cv::waitKey(0);
}
else
{
printf(" --(!) No captured frame -- Break!");
// break;
}
int c = waitKey(10);
if (27 == char(c))
{
// break;
}
/*for (int s=3 ; s>=0 ; s-- )
{
Display(+s+".jpg");
}*/
getchar();
//waitKey(10);
return 0;
}
}
// Function detectAndDisplay
void detectAndDisplay(Mat frame)
{
std::vector<Rect> faces;
Mat frame_gray;
Mat crop;
Mat res;
Mat gray;
string text;
stringstream sstm;
Mat Test1 = frame;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
// Detect faces
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
// Set Region of Interest
/* cv::Rect roi_b; we need them global
cv::Rect roi_c;*/
size_t ic = 0; // ic is index of current element
int ac = 0; // ac is area of current element
size_t ib = 0; // ib is index of biggest element
int ab = 0; // ab is area of biggest element
for (ic = 0; ic < faces.size(); ic++) // Iterate through all current elements (detected faces)
{
roi_c.x = faces[ic].x;
cout<<roi_c.x<<"/n";;
roi_c.y = faces[ic].y;
cout<<roi_c.y<<"/n";
roi_c.width = (faces[ic].width);
roi_c.height = (faces[ic].height);
ac = roi_c.width * roi_c.height; // Get the area of current element (detected face)
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
ab = roi_b.width * roi_b.height; // Get the area of biggest element, at beginning it is same as "current" element
//if (ac > ab)
//{
// ib = ic;
// roi_b.x = faces[ib].x;
// roi_b.y = faces[ib].y;
// roi_b.width = (faces[ib].width);
// roi_b.height = (faces[ib].height);
//}
crop = frame(roi_b);
// resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images
// cvtColor(crop, gray, CV_BGR2HSV); // Convert cropped image to Grayscale
// Form a filename
filename = "";
stringstream ssfn;
ssfn << filenumber << ".jpg";
filename = ssfn.str();
filenumber++;
// Mat ArrayDetectedFaces []
imwrite(filename, crop);
Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window - live stream from camera
Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
rectangle(frame, pt1, pt2, Scalar(255, 0, 0), 2, 1, 0);
FindContour(frame(roi_c));
}
// Show image
sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;
text = sstm.str();
putText(frame, text, cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA);
imshow("original", frame);
Mat ccc = frame (roi_c);
Mat bbb = frame (roi_b);
Mat Img = frame;
Mat destinationROI = frame( roi_c );
Size size(roi_c.width , roi_c.height);//the dst image size,e.g.100x100
Mat dst = bbb;//dst image
Mat src = ccc;//src image
cout<< dst.cols<<"\n";
cout<< dst.rows<<"\n";
resize(src,dst,size);//resize image
cout<< dst.cols<<"\n";
cout<< dst.rows<<"\n";
cout<< src.cols<<"\n";
cout<< src.rows<<"\n";
cout<< roi_b.width<<"\n";
cout<< roi_b.height<<"\n";
cout<< roi_c.width<<"\n";
cout<< roi_c.height<<"\n";
dst.copyTo(Img( roi_c ));
Mat FML;
//compare(dst, Img(roi_c), FML , CMP_EQ );
//cout<<FML;
if (!crop.empty())
{
// imshow("c", Test1(roi_c));
// imshow("b", bbb);
// imshow("result", Img(roi_c));
}
else
destroyWindow("detected");
}
void Display(String s)
{
Mat I = imread(s);
if (I.empty())
{
std::cout << "!!! Failed imread(): image not found" << std::endl;
// don't let the execution continue, else imshow() will crash.
}
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", I );
}
void drawStuff(){
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny( img_gray, canny_output, thresh, thresh*2, 3 );
cv::dilate(canny_output, canny_output, cv::Mat(), cv::Point(-1,-1));
// showCannyWindow();
findContours( canny_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
vector<Point> approxShape;
for(size_t i = 0; i < contours.size(); i++){
approxPolyDP(contours[i], approxShape, arcLength(Mat(contours[i]), true)*0.04, true);
drawContours(drawing, contours, i, Scalar(255, 255, 255), CV_FILLED); // fill BLUE
}
showContourWindow();
}
void showContourWindow()
{
cv::namedWindow("Fill");
cv::imshow("Fill",drawing);
}
void FindContour(Mat skinMat)
{
img_rgb = skinMat;
blur( img_rgb, img_rgb, Size(3,3) );
cvtColor(img_rgb,img_gray,CV_RGB2HSV);
// showInputWindow();
drawStuff();
cv::waitKey(0);
}`
在阈值和轮廓之后,输出就像这样。!
http://postimg.org/image/5ri87c2r5/
我的问题是,如何使用此图像仅提取脸部(皮肤,眼睛,鼻子,嘴唇)的特征并将其放在另一个图像上。它会起作用吗?有没有更简单的方法呢?
如果有更简单的方法,请解释。
非常重要所以请帮助我。
此外,当我使用copyto功能时,它并没有给我一个错误,但它也没有显示图片中的任何变化。
请不要注意过多的变量和错误的编程。它是一个测试版本。
答案 0 :(得分:0)
据我所知,你使用级联和轮廓来获得面子。
然后尝试这些步骤,
检测最大轮廓,表示为脸部并移除所有其他小轮廓。
将二进制面部图像与原始图像重叠以获得真实面部,然后使用其他阈值,例如Ostu Method。
用于眼睛检测:使用圆形检测方法获取眼球,这将代表您的眼睛。
对于皮肤检测:仅使用色调,因为颜色用色调表示,并参考my paper来检测皮肤。
- 醇>
对于鼻子等其他脸部特征,请尝试其他阈值方法。
希望这有帮助。
干杯:)