[英]image classification using SVM and BOW?
我對openCV不太了解。 我有一些圖像,我想檢查它們是否包含我正在尋找的標志。 因此,我想使用我有一些代碼的SVM技術。 我已經了解了代碼的大部分內容,但是我不知道如何實現此代碼。 該代碼具有三個功能,即createTrainDataUsingBow()
其次是int trainSVM
和int svmPredict
。
問題:我知道首先我必須訓練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;
}
我應該將哪些參數稱為int trainSVM。
trainSVM()采用兩個char *向量,分別是正樣本和負樣本的圖像文件名稱列表。 最好制作一個包含正片圖像文件名列表的文件,對於負片文件名也是如此,然后讀取其中的文件名。
順便說一句,這行有一個語法錯誤:
int trainSVM((std::vector<char*> positive, std::vector<char*> negative)
一個更大的問題是如何對數據進行規范化處理,以及如何進行交叉驗證以獲取svm_params的正確值?
另外,由於svmPredict()
為每個測試用例重新加載所有內容,因此效率很低。
使用libsvm命令行工具可能會更好,直到您知道它是否將起作用。 以libsvm格式轉儲來自createTrainDataUsingBow()
數據的createTrainDataUsingBow()
輸出將很簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.