2013-12-17 42 views
0

我對openCV不太瞭解。我有一些圖像,我想檢查他們是否包含我正在尋找或不是的標誌。所以,我想使用SVM技術,我有一些代碼。我已經理解了代碼的大部分內容,但我不知道如何實現此代碼。該代碼具有三個功能,即createTrainDataUsingBow()秒是 int trainSVMint svmPredict使用SVM和BOW進行圖像分類?

問題:我知道,首先我必須訓練SVM,然後使用predict()。但是,我不明白在他們的電話中要傳遞的論據。我的意思是,如果我創建一個main()然後用什麼參數我應該叫int trainSVM

1.代碼createTrainDataUsingBow()

void createTrainDataUsingBow(std::vector<char*> files, cv::Mat& train, cv::Mat&  response, int label) 
{ 
    cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased"); 
    cv::Ptr<cv::DescriptorExtractor> extractor = new cv::SurfDescriptorExtractor(); 
    cv::BOWImgDescriptorExtractor dextract(extractor, matcher); 
    cv::SurfFeatureDetector detector(500); 

    // cluster count 
    int cluster = 100; 

    // create the object for the vocabulary. 
    cv::BOWKMeansTrainer bow(cluster,cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, FLT_EPSILON), 1, cv::KMEANS_PP_CENTERS); 

    // get SURF descriptors and add to BOW each input files 
    std::vector<char*>::const_iterator file; 
    for(file = files.begin(); file != files.end(); file++) 
    { 
     cv::Mat img = cv::imread(*file, CV_LOAD_IMAGE_GRAYSCALE); 
     std::vector<cv::KeyPoint> keypoints = detector.detect(img, keypoints); 
     cv::Mat descriptors; 
     extractor->compute(img, keypoints, descriptors); 
     if (!descriptors.empty()) bow.add(descriptors); 
    } 

    // Create the vocabulary with KMeans. 
    cv::Mat vocabulary; 
    vocabulary = bow.cluster(); 

    for(file = files.begin(); file != files.end(); file++) 
    { 
     // set training data using BOWImgDescriptorExtractor 
     dextract.setVocabulary(vocabulary); 
     std::vector<cv::KeyPoint> keypoints; 
     cv::Mat img = cv::imread(*file, CV_LOAD_IMAGE_GRAYSCALE); 
     detector.detect(img, keypoints); 
     cv::Mat desc; 
     dextract.compute(img, keypoints, desc); 
     if (!desc.empty()) 
     { 
      train.push_back(desc);   // update training data 
      response.push_back(label);  // update response data 
     } 
    } 
} 

2.代碼trainSVM()

int trainSVM((std::vector<char*> positive, std::vector<char*> negative) 
{ 
    // create training data 
    cv::Mat train; 
    cv::Mat response; 
    createTrainDataUsingBow(positive, train, response, 1.0); 
    createTrainDataUsingBow(negative, train, response, -1.0); 

    // svm parameters 
    CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON); 
    CvSVMParams svm_param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0,  0.5, 0.1, NULL, criteria); 

    // train svm 
    cv::SVM svm; 
    svm.train(train, response, cv::Mat(), cv::Mat(), svm_param); 
    svm.save("svm-classifier.xml"); 

    return 0; 
} 

3:下面

整個代碼中給出。 svmPredict的代碼()

int svmPredict(const char* classifier, const char* vocaname, const char* query, const char* method) 
{ 
    // load image 
    cv::Mat img = cv::imread(query, CV_LOAD_IMAGE_GRAYSCALE); 

    // load svm 
    cv::SVM svm; 
    svm.load(classifier); 

    // declare BOWImgDescriptorExtractor 
    cv::Ptr<cv::DescriptorMatcher> matcher =  cv::DescriptorMatcher::create("FlannBased"); 
    cv::Ptr<cv::DescriptorExtractor> extractor = new cv::SurfDescriptorExtractor(); 
    cv::BOWImgDescriptorExtractor dextract(extractor, matcher); 

    // load vocabulary data 
    cv::Mat vocabulary; 
    cv::FileStorage fs(vocaname, cv::FileStorage::READ); 
    fs["vocabulary data"] >> vocabulary; 
    fs.release(); 
    if(vocabulary.empty() ) return 1; 

    // Set the vocabulary 
    dextract.setVocabulary(vocabulary); 
    std::vector<cv::KeyPoint> keypoints; 
    detector.detect(img, keypoints); 
    cv::Mat desc_bow; 
    dextract.compute(img, keypoints, desc_bow); 
    if(desc_bow.empty()) return 1; 

    // svm predict 
    float predict = svm.predict(centroids, true); 

    std::cout << predict << std::endl; 

    return 0; 
} 

回答

0

what parameters i should call the int trainSVM.

trainSVM()採用兩個char *載體,其分別用於陽性和陰性樣品的圖像文件的名稱的列表。 。 這將可能是最好的,使包括正圖像文件名列表的文件,與同爲陰性,而讀那些在

順便說一句,此行有語法錯誤:

int trainSVM((std::vector<char*> positive, std::vector<char*> negative) 

一更大的擔憂是你如何規範數據,以及如何進行交叉驗證以獲得svm_params的正確值?

此外,由於svmPredict()爲每個測試用例重新加載所有內容,因此效率非常低。

你可能會更好使用libsvm命令行工具,直到你知道它是否工作。以libsvm格式轉儲來自createTrainDataUsingBow()數據的數據塊輸出並不重要。

+0

謝謝,我瞭解代碼及其參數,但我仍然面臨創建svmPredict()的問題。爲此,我將發佈一個新問題。 – skm