2013-12-17 5 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) 

A : 그것은 아마도 가장 긍정적 인 이미지 파일 이름의 목록이 포함 된 파일 및 네거티브에 대해 동일한을 할 것이며, 사람들을 읽을 BTW

를,이 라인에 구문 오류가 있습니다 더 큰 걱정은 데이터를 어떻게 정규화 할 것인가이며 svm_params에 적절한 값을 얻기 위해 교차 유효성 검사를 어떻게 할 것입니까?

또한 svmPredict()은 모든 테스트 케이스마다 모든 것을 다시로드하므로 매우 비효율적입니다.

작동 여부를 알기 전까지는 libsvm 명령 줄 도구를 사용하는 것이 좋습니다. createTrainDataUsingBow()의 매트 출력을 libsvm 형식으로 덤프하는 것은 간단합니다.

+0

감사합니다, 나는 코드와 그 인수를 이해하지만 여전히 svmPredict() 만들기에 문제가 있습니다. 이를 위해 새로운 질문을 게시 할 예정입니다. – skm