2012-11-02 11 views
6

मैं ओपनसीवी 2.4.2 सी ++ चला रहा हूं।लोगों की पहचान के लिए एसवीएम का उपयोग कैसे करें?

मैं ओपनसीवी का उपयोग करके लोगों की पहचान करने की कोशिश कर रहा हूं।

मैं VidTIMIT डेटासेट का उपयोग कर रहा हूं जिसमें विभिन्न अभिविन्यास में अलग-अलग लोग शामिल हैं।

मैं इन लोगों को वर्गीकृत करने के लिए सीवीएसवीएम का उपयोग कर रहा हूं।

मेरी समस्या यह है कि svm का आउटपुट हमेशा एक जैसा होता है।

एल्गोरिथ्म है कि मैं का पालन करें:

  1. चेहरा हार
  2. चेहरे के आकार (58 * 58)
  3. SVM प्रशिक्षण
  4. वर्गीकरण

का उपयोग कर पता लगाने अब, मैं सोच रहा हूं कि मैंने प्रशिक्षण में कुछ गलत किया है।

मैं इस विधि को 5 (num_name) व्यक्ति, 10 (num_images) अलग-अलग छवियों पर विचार करने की कोशिश कर रहा हूं।

void runFaceDetectionRecognition(vector<Mat_<uchar> > &images){ 
vector<vector<Rect> > faces; 
for (unsigned i=0; i<images.size(); ++i) { 

    /// detection face 
    vector<Rect> f; 
    faceDetection(images[i], f); 

    if (!f.empty()) { 
     faces.push_back(f); 

     /// I keep only the face 
     Mat_<uchar> roi = (images[i](f[0])); 

     /// resize 
     resize(roi, roi, Size(58, 58)); 

     roi.copyTo(images[i]);    
    } 
} 

/// Set up parameters 
CvSVMParams params; 
params.svm_type = CvSVM::C_SVC; 
params.kernel_type = CvSVM::LINEAR; 
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); 


/// Set up training data 
float labels[num_name][num_images]; 
float label = 0; 

/// different label for different person 
for (unsigned i=0; i<num_name; ++i) { 
    for (unsigned j=0; j<num_images; ++j) 
     labels[i][j] = label; 

    label++; 
} 

/// labeling matrix 
Mat labelsMat(num_name*num_images, 1, CV_32FC1, labels); 

/// unrolling images 
float data[images.size()][58*58]; 
for (unsigned l=0; l<images.size(); ++l) 

    for (unsigned i=0; i<58; ++i) 
     for (unsigned j=0; j<58; ++j) 
      data[l][j+58*i] = images[l].at<float>(i,j); 


/// training matrix 
Mat train((int) images.size(),58*58, CV_32FC1, data); 
CvSVM svm(train, labelsMat, Mat(), Mat(), params); 

/// Validation 
valSVM(svm, train.rowRange(0, 1)); 
} 

सत्यापन कोड:

void valSVM(CvSVM &svm, Mat train){ 

/// prediction 
float response = svm.predict(train); 

cout << "Response ===> " << response << " "; 

/// output 
if (response == 0) cout << "lea"; 
else if (response == 1) cout << "maria"; 
else if (response == 2) cout << "ramona"; 
else if (response == 3) cout << "teresa"; 
else if (response == 4) cout << "yan"; 
} 

आशा है कि आप मेरी मदद कर सकते हैं।

उत्तर

2

ऐसा लगता है कि आप अपने 58% 58 चेहरे के साथ अपने एसवीएम को प्रशिक्षण दे रहे हैं। काम करने के लिए एसवीएम के लिए आपको पीसीए (प्रिंसिपल कंपोनेंट एनालिसिस) जैसी विधि का उपयोग करके अपने आयामों को कम करने (अपने मुख्य घटक प्राप्त करने) की आवश्यकता है जो पहले से ही ओपनसीवी में शामिल है।

यदि आप 58 * 58 सरणी से एन * एन सरणी में अपने आयामों को कम करते हैं, जहां एन प्रमुख विशेषताएं हैं, तो एसवीएम का प्रशिक्षण केवल प्रमुख विशेषताओं का उपयोग करेगा और इसके परिणामस्वरूप एक बेहतर समाधान होगा।

ओपनसीवी के साथ चेहरे की पहचान के बहुत सारे दस्तावेज हैं, आप here शुरू कर सकते हैं।

+1

आपको बहुत बहुत – Gappa

4

दूसरा उत्तर यह कहने में सही नहीं है कि एसवीएम को कार्य करने के लिए पीसीए का उपयोग करना चाहिए। मैंने पीसीए के बिना 128x128 छवियों पर एसवीएम का उपयोग किया है और अच्छे परिणाम प्राप्त किए हैं। मैंने कोह्न-कानेड डेटासेट के साथ कुछ ऐसा किया है। यहां कुछ स्रोत कोड है जो मदद कर सकते हैं।

vector<Mat> preImages;//Fill this with your images from your dataset 
vector<int> labels;//Fill this with the labels from the dataset 
vector<Mat> images; 

CascadeClassifier haar_cascade; 
haar_cascade.load("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"); 
vector< Rect_<int> > faces; 
Mat procFace; 
cout << "images: " << preImages.size() << " labels: " << labels.size() << endl; 
for(unsigned int i = 0; i < preImages.size(); i++) 
{ 
    procFace = preImages[i].clone(); 
    //haar_cascade.detectMultiScale(procFace, faces); 
    haar_cascade.detectMultiScale(
      procFace, 
      faces, 
      1.1, 
      3, 
      CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH, 
      Size(110, 110) 
    ); 

    if(faces.size() > 0) 
    { 

     // Process face by face: 
     Rect face_i = faces[0]; 
     // Crop the face from the image. 
     Mat face = procFace(face_i); 

     ////You can maybe use the equalizeHist function here instead////// 
     face = illuminationComp(face); 

     //crop face 
     Rect cropped(face_i.width*0.18, face_i.height*0.2, int(face_i.width*0.7), int(face_i.height*0.78)); 
     Mat Cface = face(cropped); 

     Mat face_resized; 
     resize(Cface, face_resized, Size(128, 128), 1.0, 1.0, INTER_CUBIC); 

     images.push_back(face_resized); 
    } 
} 


//svm parameters: 
SVMParams params = SVMParams(); 
params.svm_type = SVM::C_SVC; 
params.kernel_type = SVM::LINEAR; 
params.degree = 3.43; // for poly 
params.gamma = 0.00225; // for poly/rbf/sigmoid 
params.coef0 = 19.6; // for poly/sigmoid 
params.C = 0.5; // for CV_SVM_C_SVC , CV_SVM_EPS_SVR and CV_SVM_NU_SVR 
params.nu = 0.0; // for CV_SVM_NU_SVC , CV_SVM_ONE_CLASS , and CV_SVM_NU_SVR 
params.p = 0.0; // for CV_SVM_EPS_SVR 
params.class_weights = NULL; // for CV_SVM_C_SVC 
params.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS; 
params.term_crit.max_iter = 1000; 
params.term_crit.epsilon = 1e-6; 

if(images.size() == labels.size()) 
{ 
    cout << "Creating SVM Classification" << endl << endl; 

    int rowsSize = images.size(); 
    int trainingArea = images[0].rows * images[0].cols; 
    Mat trainingMat = Mat::zeros(rowsSize, trainingArea, CV_32FC1); 
    int counter; 


    for(int index = 0; index < rowsSize; index++) 
    { 
     counter = 0; 
     for(int rows = 0; rows < images[0].rows; rows++) 
     { 
      for(int cols = 0; cols < images[0].cols; cols++) 
      { 
       trainingMat.at<float>(index, counter) = images[index].at<uchar>(rows,cols); 
        counter++; 
      } 
     } 
    } 


    Mat matLabels = Mat::zeros(labels.size(),1,CV_32FC1); 
    for(size_t index = 0; index < labels.size(); index++) 
    { 
     matLabels.at<float>(index,0) = float(labels[index]); 
    } 

    if(trainingMat.rows == matLabels.rows) 
    { 
     SVM svm; 
     svm.train(trainingMat,matLabels,Mat(),Mat(),params); 
     svm.save("svm_model.yml"); 
    } 
} 
+0

आप कच्चे छवि का उपयोग कर रहे प्रशिक्षित करने के लिए धन्यवाद किया है? इसमें फीचर निष्कर्षण भाग नहीं है। अगर मैं एलबीपी का उपयोग कर सुविधा निकालता हूं और इसे एसवीएम ट्रेन के इनपुट के रूप में उपयोग करता हूं तो कैसे? क्या मुझे एलबीपी फीचर को एलबीपी हिस्टोग्राम और ट्रेन में बदलने की ज़रूरत है या नहीं? – Jame

+0

@ user8430: एलपीबी सुविधाओं को निकालने के बाद, आपको संबंधित हिस्टोग्राम की गणना करने की आवश्यकता है, फिर उस हिस्टोग्राम वेक्टर को अपने एसवीएम क्लासिफायर को पास करें। – Derman

+0

@ user8430 हां, मैंने ट्रेन करने के लिए कच्ची छवियों का उपयोग किया। प्रशिक्षण से पहले मैंने केवल एक चीज छवियों और क्रॉपिंग/संरेखण पर रोशनी बराबरता को चलाया था। – jmo

0

मैं एक ऐसी परियोजना भी बना रहा हूं जिसमें मैंने किसी ऑब्जेक्ट को वर्गीकृत किया हो। मैं एसवीएम और बैग ऑफ फीचर्स (बीओएफ)/बो के संयोजन का उपयोग कर रहा हूं। इस विधि में सबसे पहले आप शब्दकोश/कोडबुक बनाते हैं और फिर अपने एसवीएम को प्रशिक्षित करते हैं। परिणाम काफी अच्छे हैं।

आप ca इस लिंक पर एक नज़र पाने के लिए एक विचार http://www.morethantechnical.com/2011/08/25/a-simple-object-classifier-with-bag-of-words-using-opencv-2-3-w-code/

संबंधित मुद्दे

 संबंधित मुद्दे