使用具有 HOG 特征的 SVM 对车辆进行分类
Using SVM with HOG Features to Classify Vehicles
我的目标是使用 SVM 和 HOG 特征对 SUV 和轿车进行分类。
首先,我读取了 86 张训练图像,计算了每张图像的 HOG 特征,并将它们放入一个大小为 86xdescriptorSize 的训练垫中,名为 HOGFeat_train。
Mat HOGFeat_train(num_train_images, derSize, CV_32FC1); //86xdescriptor size training Mat
for (int file_count = 1; file_count < (num_train_images + 1); file_count++)
{
ss << name << file_count << type; //'Vehicle_1.jpg' ... 'Vehicle_2.jpg' ... etc ...
string filename = ss.str();
ss.str("");
Mat training_img = imread(filename, 0); //Reads the training images from the folder
HOGDescriptor hog_train;
vector<float> descriptors_train;
vector<Point> locations_train;
hog_train.compute(training_img, descriptors_train, Size(16, 16), Size(0, 0), locations_train); //not sure about these values
for (int i = 0; i < descriptors_train.size(); i++)
HOGFeat_train.at<float>(file_count-1, i) = descriptors_train.at(i);
}
接下来,我为 SVM 的监督学习部分创建了一个包含 86 个标签的 labels_mat(我知道这种方式不切实际且耗时,稍后我会修复)。 1 表示 SUV,-1 表示轿车。不确定这些 SVM 参数,但我尝试了不同的品种和值,但所有结果都是相同的。
float labels[86] = { 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1};
Mat labels_mat(num_train_images, 1, CV_32S);
cout << "Beginning Training..." << endl;
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
//svm->setDegree(3);
//svm->setGamma(2);
//svm->setC(.5);
cout << "Parameters Set..." << endl;
svm->train(HOGFeat_train, ROW_SAMPLE, labels_mat);
cout << "Training Successful" << endl;
接下来,我以与训练图像相同的方式读取 10 个测试图像,并再次计算 HOG 特征。在计算出 HOG 特征后,它们被放入 1 行 x descriptorSized HOGFeat_test Mat 中,然后我使用 svm->predict 那个 HOGFeat_test Mat 应该 return 的值为 -1 到表示轿车或 1 表示 SUV。
Mat HOGFeat_test(1, derSize, CV_32FC1); //Creates a 1 x descriptorSize Mat to house the HoG features from the test image
for (int file_count = 1; file_count < (num_test_images + 1); file_count++)
{
ss2 << name2 << file_count << type2; //'Test_1.jpg' ... 'Test_2.jpg' ... etc ...
string filename2 = ss2.str();
ss2.str("");
Mat test_image = imread(filename2, 0); //Read the file folder
HOGDescriptor hog_test;
vector<float> descriptors_test;
vector<Point> locations_test;
hog_test.compute(test_image, descriptors_test, Size(16, 16), Size(0, 0), locations_test);
for (int i = 0; i < descriptors_test.size(); i++)
HOGFeat_test.at<float>(0, i) = descriptors_test.at(i);
namedWindow("Test Image", CV_WINDOW_NORMAL);
imshow("Test Image", test_image);
//Should return a 1 if its an SUV, or a -1 if its a sedan
float result = svm->predict(HOGFeat_test);
if (result <= 0)
cout << "Sedan" << endl;
else
cout << "SUV" << endl;
cout << "Result: " << result << endl;
下图显示了结果、测试图像和 HOGFeat_train 垫子,以防对任何人有用。无论我使用什么值、参数或图像,结果 (Sedan, -8.412e08) 总是相同的。结果不是 -1 或 1,而是 -800000000000,我假设负值对应于 -1,但最重要的是我想知道为什么结果没有改变。有没有人对此有任何见解?谢谢。
编辑-------------------------------------
我删除了浮动标签中的所有标签[86],并将其保留为浮动标签[86]; //{1、1、-1 等...}
这表明 SVM 结果没有差异,仍然能够成功训练。这告诉我我的标签没有通过 svm->train 函数或其他东西。我会继续调查。
所以这只是我对自己犯的一个愚蠢的错误。我用 float labels[86] 替换了标签;基本上我只是删除了 SVM 的监督学习部分,但我得到了完全相同的结果。检查后我发现我没有将标签填入 labels_mat!!!!!!
因此,执行以下操作可得到清晰的解决方案。此外,结果变为 1 和 -1 而不是 -8.412e-8。
垫子 labels_mat(num_train_images, 1, CV_32S, 标签);
我的目标是使用 SVM 和 HOG 特征对 SUV 和轿车进行分类。
首先,我读取了 86 张训练图像,计算了每张图像的 HOG 特征,并将它们放入一个大小为 86xdescriptorSize 的训练垫中,名为 HOGFeat_train。
Mat HOGFeat_train(num_train_images, derSize, CV_32FC1); //86xdescriptor size training Mat
for (int file_count = 1; file_count < (num_train_images + 1); file_count++)
{
ss << name << file_count << type; //'Vehicle_1.jpg' ... 'Vehicle_2.jpg' ... etc ...
string filename = ss.str();
ss.str("");
Mat training_img = imread(filename, 0); //Reads the training images from the folder
HOGDescriptor hog_train;
vector<float> descriptors_train;
vector<Point> locations_train;
hog_train.compute(training_img, descriptors_train, Size(16, 16), Size(0, 0), locations_train); //not sure about these values
for (int i = 0; i < descriptors_train.size(); i++)
HOGFeat_train.at<float>(file_count-1, i) = descriptors_train.at(i);
}
接下来,我为 SVM 的监督学习部分创建了一个包含 86 个标签的 labels_mat(我知道这种方式不切实际且耗时,稍后我会修复)。 1 表示 SUV,-1 表示轿车。不确定这些 SVM 参数,但我尝试了不同的品种和值,但所有结果都是相同的。
float labels[86] = { 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1};
Mat labels_mat(num_train_images, 1, CV_32S);
cout << "Beginning Training..." << endl;
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
//svm->setDegree(3);
//svm->setGamma(2);
//svm->setC(.5);
cout << "Parameters Set..." << endl;
svm->train(HOGFeat_train, ROW_SAMPLE, labels_mat);
cout << "Training Successful" << endl;
接下来,我以与训练图像相同的方式读取 10 个测试图像,并再次计算 HOG 特征。在计算出 HOG 特征后,它们被放入 1 行 x descriptorSized HOGFeat_test Mat 中,然后我使用 svm->predict 那个 HOGFeat_test Mat 应该 return 的值为 -1 到表示轿车或 1 表示 SUV。
Mat HOGFeat_test(1, derSize, CV_32FC1); //Creates a 1 x descriptorSize Mat to house the HoG features from the test image
for (int file_count = 1; file_count < (num_test_images + 1); file_count++)
{
ss2 << name2 << file_count << type2; //'Test_1.jpg' ... 'Test_2.jpg' ... etc ...
string filename2 = ss2.str();
ss2.str("");
Mat test_image = imread(filename2, 0); //Read the file folder
HOGDescriptor hog_test;
vector<float> descriptors_test;
vector<Point> locations_test;
hog_test.compute(test_image, descriptors_test, Size(16, 16), Size(0, 0), locations_test);
for (int i = 0; i < descriptors_test.size(); i++)
HOGFeat_test.at<float>(0, i) = descriptors_test.at(i);
namedWindow("Test Image", CV_WINDOW_NORMAL);
imshow("Test Image", test_image);
//Should return a 1 if its an SUV, or a -1 if its a sedan
float result = svm->predict(HOGFeat_test);
if (result <= 0)
cout << "Sedan" << endl;
else
cout << "SUV" << endl;
cout << "Result: " << result << endl;
下图显示了结果、测试图像和 HOGFeat_train 垫子,以防对任何人有用。无论我使用什么值、参数或图像,结果 (Sedan, -8.412e08) 总是相同的。结果不是 -1 或 1,而是 -800000000000,我假设负值对应于 -1,但最重要的是我想知道为什么结果没有改变。有没有人对此有任何见解?谢谢。
编辑-------------------------------------
我删除了浮动标签中的所有标签[86],并将其保留为浮动标签[86]; //{1、1、-1 等...}
这表明 SVM 结果没有差异,仍然能够成功训练。这告诉我我的标签没有通过 svm->train 函数或其他东西。我会继续调查。
所以这只是我对自己犯的一个愚蠢的错误。我用 float labels[86] 替换了标签;基本上我只是删除了 SVM 的监督学习部分,但我得到了完全相同的结果。检查后我发现我没有将标签填入 labels_mat!!!!!!
因此,执行以下操作可得到清晰的解决方案。此外,结果变为 1 和 -1 而不是 -8.412e-8。
垫子 labels_mat(num_train_images, 1, CV_32S, 标签);