2015-04-18 27 views
1

這是我的代碼。皮膚檢測器是一個獨立的類,可以進行HSV閾值處理。我已經覆蓋了它。如何在OpenCv中使用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

據,據我所知,您使用級聯和輪廓得到的臉。

然後嘗試這些步驟,

  1. 檢測最大的輪廓,它代表的臉上,並刪除所有其他的小輪廓。

  2. 重疊原始圖像的二進制人臉圖像,讓您真正的臉,然後用其他一些門檻喜歡Ostu Method

  3. 對於人眼檢測:採用圓檢測方法來獲取眼球,這將代表了你的眼睛。

  4. 皮膚檢測:僅使用色相,因爲色彩以色相表示,並參照my paper檢測皮膚。

  5. 而對於其他的面部特徵,如鼻子,嘗試其他的閾值法。

希望這會有所幫助。

乾杯:)