gpt4 book ai didi

c++ - 如何使用 SVM 从视频中检测对象

转载 作者:行者123 更新时间:2023-11-28 03:12:00 26 4
gpt4 key购买 nike

这是我用于训练车辆数据集的代码,当它完全训练时,我希望它从视频(.avi)预测数据(车辆),如何从视频预测训练数据以及如何在其中添加该部分?,我希望当车辆在视频中显示时将其计为 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("%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;

问题是这段代码不是从视频中预测的,我想知道如何从视频中预测它,意思是我想从电影中检测车辆,就像它应该在什么时候显示 1它从电影中找到车辆

对于那些不明白问题的人:

我想用上面的代码播放电影

VideoCapture cap("movie.avi"); //movie.avi is with deleted background

假设我有一个包含车辆的训练数据,而“movie.avi”包含 5 辆车,所以它应该从 movie.avi 中检测到车辆并给我 5 作为输出

上面代码中这部分是怎么做的

最佳答案

通过查看您的代码设置

params.svm_type = CvSVM::C_SVC;

您似乎用两个以上的类来训练分类器。交通场景中的一个典型示例可能是汽车/行人/自行车/......但是,您正在寻求一种仅检测汽车的方法。如果没有对您的训练数据和视频的描述,就很难判断您的想法是否有意义。我猜前面的答案假设如下:

您遍历每一帧并希望输出该帧中的汽车数量。因此,一个帧可能包含多辆汽车,比如 5 辆。如果您将整个帧作为分类器的输入,它可能会响应“汽车”,即使设置在概念上可能有点偏差。您无法使用这种方法可靠地检索汽车数量。

相反,建议尝试使用滑动窗口方法。这意味着,例如,您遍历帧的每个像素并将像素周围的区域(称为子窗口感兴趣区域)作为输入分类器。假设一个固定的scale,子窗口的大小可以是 150x50px 以及你的训练数据。您可能会在训练数据中固定汽车的比例,但在真实世界的视频中,汽车的尺寸会有所不同。为了找到不同比例的汽车,假设它是训练数据的两倍,典型的方法是缩放图像(比如使用 2 倍)并重复滑动窗口方法。

通过对所有相关尺度重复此操作,您最终会得到一个算法,该算法为每个像素位置和每个尺度提供分类器的结果。这意味着您有三个循环,或者换句话说,有三个维度(图像宽度、图像高度、比例)。最好将其理解为三维金字塔。 “为什么是金字塔?”你可能会问。因为每次缩放图像(比如 2),图像都会变小(/变大),下一个缩放是不同尺寸的图像(例如尺寸的一半)。

像素位置表示汽车的位置,比例尺表示汽车的大小。现在,如果你有一个 N 类分类器,这个金字塔中的每个槽都将包含一个数字 (1,...,N) 来指示类别。如果你有一个二元分类器(有车/无车),那么你最终会得到包含 0 或 1 的每个槽。即使在这种简单的情况下,你也会想简单地计算 1 的数量并将计数输出为车的数量,你仍然会遇到同一辆车可能有多个响应的问题。因此,如果你有一个汽车检测器,它会给出 0 到 1 之间的连续响应,然后你可以在这个金字塔中找到最大值,那就更好了。每个最大值表示一辆汽车。这种检测已成功用于角点特征,您可以在所谓的尺度空间金字塔中检测感兴趣的角点。

总而言之,无论您是将问题简化为二元分类问题(“汽车”/“没有汽车”),还是坚持更困难的区分多个类别的任务(“汽车”/“动物”/“行人”/...),您仍然需要解决每一帧中的比例和位置问题。

关于c++ - 如何使用 SVM 从视频中检测对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18172371/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com