【发布时间】:2015-07-21 19:03:13
【问题描述】:
我已经为 20 个类训练了 SVM,现在对于一个新图像,我想首先将其分类为 20 个训练类之一,然后显示其分类依据的置信度分数。
问题:当我测试第 1 类的一些图像时,它们都返回了相同的置信度分数。我知道每张图片都应该有不同的分数,并以此为基础进行分类。所以我知道我的代码有问题。
我什至把“opencv”框架上的实例变量float *decision_function从protected改成了public并重建了,但是问题还是没有解决。
我想计算正确的分数,因为我想稍后根据置信度分数对与我的查询图像最匹配的图像进行排名。
请告诉我为什么我在同一类中的每张图片都获得相同的置信度分数,以及我在代码中的哪个地方犯了错误。
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor();
SurfFeatureDetector detector(500);// hemessian threshold
int dictionarySize = 100; //number of clusters=100
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(extractor, matcher);
int main( int argc, char** argv )
{
int i,j;
Mat dictionary; // creating a dictionary
FileStorage fs("dictionary_new.yml", FileStorage::READ);
fs ["vocabulary"]>> dictionary;
fs.release();
bowDE.setVocabulary(dictionary);
Mat labels(0, 1, CV_32FC1); //to store labels of images
Mat trainingData(0, dictionarySize, CV_32FC1);
int k=0;
CvSVMParams params;
params.kernel_type=CvSVM::RBF;
params.svm_type=CvSVM::C_SVC;
params.gamma=0.50625000000000009;
params.C=312.50000000000000;
params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER,100,0.000001);
CvSVM svm;
svm.load("svm_new.yml");
cout<<"Processing evaluation data..."<<endl;
string tags[] = {"none","Plane","Bike","Face","Car","Bag","binocular","Gloves","Bread_Maker","Revolver","Ring","Guitar","Elephant","boat","French_horn","Gorilla","Headphone","Flower","Penguin","Tiger","Laptop"};
Mat evalData(0, dictionarySize, CV_32FC1);
k=0;
vector<KeyPoint> keypoint2;
Mat bowDescriptor2;
Mat img2; //to load an image
img2 = imread("3 (14).jpg");
detector.detect(img2, keypoint2);
bowDE.compute(img2, keypoint2, bowDescriptor2);
evalData.push_back(bowDescriptor2);
float response = svm.predict(bowDescriptor2, true);
float confidence=0;
int f_to_i=(int)response;
confidence=1.0/(1.0+exp(-response));
cout<<"\n\nIt's a "<<tags[f_to_i]<<" and its confidence: "<<confidence;
_getch();
return 0;
}
计算分数:
1 (1).jpg,Plane,0.731059
1 (2).jpg,Plane,0.731059
1 (3).jpg,Plane,0.731059
1 (4).jpg,Plane,0.731059
1 (5).jpg,Plane,0.731059
1 (6).jpg,Plane,0.731059
1 (7).jpg,Plane,0.731059
1 (8).jpg,Plane,0.731059
1 (9).jpg,Plane,0.731059
1 (10).jpg,Plane,0.731059
1 (11).jpg,Plane,0.731059
1 (12).jpg,Plane,0.731059
1 (13).jpg,Plane,0.731059
1 (14).jpg,Plane,0.731059
1 (15).jpg,Plane,0.731059
1 (16).jpg,Plane,0.731059
1 (17).jpg,Plane,0.731059
1 (18).jpg,Plane,0.731059
1 (19).jpg,Plane,0.731059
1 (20).jpg,Plane,0.731059
【问题讨论】:
-
将变量从受保护更改为公共应该永远不会影响程序的输出。
-
我跟着这个:link 因为我有点遇到同样的问题。 @MSalters
-
尝试另一个内核,不同的 svm 参数,但请注意,当您从文件加载 svm 时,您的 svm 参数也会被覆盖(来自 xml 中的数据)
-
会试一试。谢谢。 @berak
-
@berak 就像你说的,我确保我的内核和参数在代码以及我正在加载的 yml 的数据中是相同的。但我仍然在整个班级中获得相同的分数。