这是我训练例如车辆数据集的代码,当它完全训练时,我希望它从视频(.avi)预测数据(车辆),how to predict trained data from video and how to add that part in it ?
,我想要当车辆在视频中显示它被视为1并且cout表示检测到物体,如果第二辆车到达它则将计数增加为2
IplImage *img2;
cout<<"Vector quantization..."<<endl;
collectclasscentroids();
vector<Mat> descriptors = bowTrainer.getDescriptors();
int count=0;
for(vector<Mat>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
count += iter->rows;
}
cout<<"Clustering "<<count<<" features"<<endl;
//choosing cluster's centroids as dictionary's words
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
cout<<"extracting histograms in the form of BOW for each image "<<endl;
Mat labels(0, 1, CV_32FC1);
Mat trainingData(0, dictionarySize, CV_32FC1);
int k = 0;
vector<KeyPoint> keypoint1;
Mat bowDescriptor1;
//extracting histogram in the form of bow for each image
for(j = 1; j <= 4; j++)
for(i = 1; i <= 60; i++)
{
sprintf( ch,"%s%d%s%d%s","train/",j," (",i,").jpg");
const char* imageName = ch;
img2 = cvLoadImage(imageName, 0);
detector.detect(img2, keypoint1);
bowDE.compute(img2, keypoint1, bowDescriptor1);
trainingData.push_back(bowDescriptor1);
labels.push_back((float) j);
}
//Setting up SVM parameters
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;
printf("%s\n", "Training SVM classifier");
bool res = svm.train(trainingData, labels, cv::Mat(), cv::Mat(), params);
cout<<"Processing evaluation data..."<<endl;
Mat groundTruth(0, 1, CV_32FC1);
Mat evalData(0, dictionarySize, CV_32FC1);
k = 0;
vector<KeyPoint> keypoint2;
Mat bowDescriptor2;
Mat results(0, 1, CV_32FC1);;
for(j = 1; j <= 4; j++)
for(i = 1; i <= 60; i++)
{
sprintf( ch, "%s%d%s%d%s", "eval/", j, " (",i,").jpg");
const char* imageName = ch;
img2 = cvLoadImage(imageName,0);
detector.detect(img2, keypoint2);
bowDE.compute(img2, keypoint2, bowDescriptor2);
evalData.push_back(bowDescriptor2);
groundTruth.push_back((float) j);
float response = svm.predict(bowDescriptor2);
results.push_back(response);
}
//calculate the number of unmatched classes
double errorRate = (double) countNonZero(groundTruth- results) / evalData.rows;
The question is
此代码不是从视频中预测的,我想知道如何从视频中预测它,就像我想要从电影中检测到车辆一样,就像它应该在找到车辆时显示1电影
对于那些不理解这个问题的人:
我想在上面的代码中播放电影
VideoCapture cap("movie.avi"); //movie.avi is with deleted background
假设我有一个包含车辆的训练数据,而且“movie.avi”包含5辆车,所以它应该从movie.avi中检测到这些车辆并给我5
作为输出
如何在上面的代码中执行此部分
答案 0 :(得分:2)
从查看代码设置
params.svm_type = CvSVM::C_SVC;
您似乎用两个以上的课程训练您的分类器。交通场景中的一个典型例子可能是汽车/行人/自行车/ ......但是,您只是想要一种方法来检测汽车。如果没有您的训练数据和视频的描述,很难说,如果您的想法有意义。我想以前的答案假设如下:
您遍历每个帧并想要输出该帧中的汽车数量。因此,一个框架可能包含多个汽车,比如说5.如果你将整个框架作为分类器的输入,它可能会响应“汽车”,即使设置可能稍微偏离概念。使用这种方法无法可靠地检索汽车数量。
相反,建议是尝试滑动窗口方法。这意味着,例如,您循环遍历帧的每个像素,并将像素周围的区域(称为子窗口或感兴趣区域)作为输入分类器。假设一个固定的比例,子窗口的大小可以是150x50px,也可以是你的训练数据。您可以在训练数据中固定汽车的比例,但在真实世界的视频中,汽车将具有不同的尺寸。为了找到不同规模的汽车,假设它的数量是训练数据的两倍,典型的方法是缩放图像(例如用2倍)并重复滑动窗口方法。 p>
通过对所有相关比例重复此操作,您最终会得到一个算法,该算法为您提供每个像素位置,并为每个比例缩放结果。这意味着您有三个循环,换句话说,有三个维度(图像宽度,图像高度,比例)。这最好被理解为三维金字塔。 “为什么是金字塔?”你可能会问。因为每次缩放图像(例如2)时图像变小(/更大),下一个刻度是不同大小的图像(例如,大小的一半)。
像素位置表示汽车的位置,刻度表示尺寸。现在,如果你有一个N级分类器,这个金字塔中的每个插槽都将包含一个表示该类的数字(1,...,N)。如果你有一个二元分类器(汽车/没有汽车),那么你最终会得到每个包含0或1的插槽。即使在这个简单的情况下,你也很想简单地计算1的数量并将计数输出为汽车数量,你仍然有一个问题,即同一辆车可能有多个响应。因此,如果你有一个汽车探测器可以提供0到1之间的连续响应,然后你可以在这个金字塔中找到最大值,那就更好了。每个最大值表示一辆车。这种检测成功地与角落特征一起使用,您可以在所谓的尺度空间金字塔中检测感兴趣的角落。
总结一下,无论你是将问题简化为二元分类问题(“汽车”/“没有汽车”),还是你正在坚持区分多个类别(“汽车”/)的更困难的任务“动物”/“行人”/ ...),你仍然有每个框架中的尺度和位置问题需要解决。
答案 1 :(得分:0)
使用图像的代码是使用OpenCV的C接口编写的,因此可能很容易使用它而不是使用C ++视频接口。
在这种情况下,沿着这些方向的东西应该起作用:
CvCapture *capture = cvCaptureFromFile("movie.avi");
IplImage *img = 0;
while(img = cvQueryFrame(capture))
{
// Process image
...
}
答案 2 :(得分:0)
您应该实现滑动窗口方法。在每个窗口中,您应该应用SVM来获取候选人。然后,一旦你为整个图像完成了它,你应该合并候选者(如果你检测到一个对象,那么很可能你会在几个像素的移位中再次检测到它 - 这就是候选者的意思)
查看openCV上的V&amp; J代码或latentSVM代码(按部分检测),看看它是如何在那里完成的。
顺便说一下,我会使用LatentSVM代码(按部件检测)来检测车辆。它训练了汽车和公共汽车的模型。
祝你好运。答案 3 :(得分:0)
你需要探测器,而不是分类器。看看之前提到的Haar级联,LBP级联,latentSVM或HOG探测器。
我会解释原因。检测器通常通过滑动窗口逐行扫描图像。在几个尺度。在每个窗口检测器中解决问题:“对象/非对象”。它可能会给你粗略的结果,但速度非常快。诸如BOW之类的分类器对于此任务的工作非常缓慢。然后,您应该将分类器应用于检测器找到的区域。