如何使用支持向量机从视频中检测对象
How to detect object from video using SVM
这是我训练数据集的代码,例如车辆,当它完全训练时,我希望它从视频(.avi)预测数据(车辆),how to predict trained data from video and how to add that part in it ?
,我希望当车辆在视频中显示时,它将其计数为1,并确保检测到对象,如果第二辆车来了,它将计数增加为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("%sn", "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.awi中检测到这些车辆,并将5
作为输出
如何在上面的代码中完成这一部分
从查看您的代码设置
params.svm_type = CvSVM::C_SVC;
似乎您用两个以上的类来训练分类器。交通场景中的一个典型例子可能是汽车/行人/自行车/。。。然而,你要求的是一种只检测汽车的方法。如果没有对你的训练数据和视频的描述,很难判断你的想法是否有意义。我想前面的答案是假设如下:
循环浏览每一帧,并希望输出该帧中的汽车数量。因此,一个车架可以包含多个汽车,例如5辆。如果您将整个帧作为分类器的输入,它可能会响应"car",即使设置在概念上可能有点偏离。用这种方法无法可靠地检索汽车数量。
相反,建议尝试滑动窗口方法。这意味着,例如,在帧的每个像素上循环,并将像素周围的区域(称为子窗口或感兴趣区域)作为分类器的输入。假设固定的比例,子窗口的大小可能与训练数据的大小一样为150x50px。你可能会在训练数据中固定汽车的比例,但在现实世界的视频中,汽车的尺寸会有所不同。为了找到一辆不同规模的汽车,假设它是训练数据中的两倍大,典型的方法是缩放图像(比如用系数2),然后重复滑动窗口方法。
通过对所有相关的尺度重复这一点,你最终会得到一个算法,为每个像素位置和每个尺度提供分类器的结果。这意味着你有三个循环,换句话说,有三个维度(图像宽度、图像高度、比例)。这最好理解为一个三维金字塔。"为什么是金字塔?"你可能会问。因为每次缩放图像(比如2),图像都会变小(/变大),下一个缩放是不同大小的图像(例如大小的一半)。
像素位置表示汽车的位置,刻度表示汽车的大小。现在,如果你有一个N类分类器,这个金字塔中的每个槽都会包含一个数字(1,…,N)来表示类别。如果你有一个二进制分类器(car/no-car),那么你会得到每个包含0或1的槽。即使在这种简单的情况下,你会很想简单地计算1的数量,并将其输出为汽车数量,但你仍然存在同一辆汽车可能有多个响应的问题。因此,如果你有一个汽车探测器,它能给出0到1之间的连续响应,然后你可以在这个金字塔中找到最大值,那就更好了。每个最大值表示一辆车。这种检测成功地与角点特征一起使用,在所谓的比例空间金字塔中检测感兴趣的角点。
总之,无论你是将问题简化为二元分类问题("车"/"无车"),还是坚持更难的任务,即区分多个类别("车"/"动物"/"行人"/…),你仍然需要解决每个框架中的规模和位置问题。
使用图像的代码是用OpenCV的C接口编写的,所以使用它可能比使用C++视频接口更容易。
在这种情况下,沿着这些路线的某些事情应该起作用:
CvCapture *capture = cvCaptureFromFile("movie.avi");
IplImage *img = 0;
while(img = cvQueryFrame(capture))
{
// Process image
...
}
您应该实现一种滑动窗口方法。在每个窗口中,您都应该应用SVM来获取候选者。然后,一旦你对整个图像进行了合并,你就应该合并候选对象(如果你检测到一个对象,那么你很可能会在几个像素的偏移中再次检测到它——这就是候选对象的意义)。
看看V&J代码或latentSVM代码(通过部件检测),看看它是如何在那里完成的。
顺便说一句,我会使用LatentSVM代码(通过部件检测)来检测车辆。它训练了汽车和公共汽车的模型。
祝你好运。
您需要检测器,而不是分类器。看看前面提到的Haar级联、LBP级联、latentSVM或HOG检测器。
我会解释原因。探测器通常通过滑动窗口逐行扫描图像。在几个尺度上。在每个窗口检测器解决问题:"对象/非对象"。它可能会给你带来粗略的结果,但速度非常快。像BOW这样的分类器在执行此任务时工作非常缓慢。然后,您应该将分类器应用于由检测器找到的区域。
- 检测 COFF 对象文件中C++内联符号
- Tensorflow对象检测在Python和C++(OpenCV)之间有不同的结果
- C++中的张量流对象检测
- 如何检测图像中的特定对象
- 微调张量流对象检测预训练模型
- 我的视频流程在运行darknet.exe以进行检测对象时崩溃了
- 是否可以从成员函数中检测对象是否为临时对象
- 如何检测对象是否主要由堆栈或动态内存组成
- C++预处理器+检测对象类型和新操作
- 如何使用支持向量机从视频中检测对象
- 一种自动检测对象的方法,该方法通过值传递给c++中的函数
- 使用cv::Mat图像(opencv)如何检测对象
- 正在检测对象是否为智能指针所拥有
- 模糊保存图像检测对象使用OpenCV
- 如何传播或检测对象的删除
- 如何检测对象来自哪个类?Qt
- 如何在OpenCV 3.1上使用SIFT特征绘制检测对象
- 有什么技巧可以检测对象是否是在执行另一个析构函数时创建的
- 检测对象是否仍处于活动状态或已被销毁
- Knapsnack算法检测对象