使用SVM对SUV和轿车进行分类

我正在尝试使用OpenCV实现一个SVM来对轿车和SUV的图像进行分类。我大量参考了这篇文章:使用OpenCV和SVM处理图像

我有29张轿车和SUV的训练图像,并且我将每张图像拉伸成一行非常长的数据,因此我的训练矩阵大小为29x图像面积。下图显示训练矩阵全部显示为白色,我不确定这是否正确,这可能影响了我的结果。

这可能是由于训练矩阵是浮点类型造成的。如果将训练矩阵改为CV_8UC1类型,我可以清楚地看到每张图像在训练矩阵中展开,但svm->train函数不接受这种类型的训练矩阵。

我使用labels_mat作为监督学习的实现版本。1表示SUV,-1表示轿车。在下图中,当我尝试使用SVM模型预测SUV时,我得到的值约为-800000000000。不管我做什么(更改参数,使用全白测试图像、全黑测试图像,将标签改为仅1或-1),我总是得到同样的-80000000000值。现在,任何负结果可能仅表示-1(轿车),但我无法确定,因为它从未改变。如果有人对此有见解,将不胜感激

这是我的代码、结果和全白训练矩阵。结果图像

int num_train_images = 29;      //29张图像将用于训练SVM
int image_area = 150 * 200;     
Mat training_mat(num_train_images, image_area, CV_32FC1);   //创建一个29行30000列的矩阵... 29张150x200的图像将每张图像放入一行                                                            //将29张2D图像转换为每张图像一行非常长的数据
for (int file_count = 1; file_count < (num_train_images + 1); file_count++) {    
    ss << name << file_count << type;       //'Vehicle_1.jpg' ... 'Vehicle_2.jpg' ... 等等 ...
    string filename = ss.str();    
    ss.str("");    
    Mat training_img = imread(filename, 0);     //从文件夹中读取训练图像    
    int ii = 0;                                 //扫描每列    
    for (int i = 0; i < training_img.rows; i++)     
    {        
        for (int j = 0; j < training_img.cols; j++)        
        {            
            training_mat.at<float>(file_count - 1, ii) = training_img.at<uchar>(i, j);  //用读取的图像填充训练矩阵            
            ii++;         
        }    
    }
}
imshow("Training Mat", training_mat);
waitKey(0);
//标签用于SVM的监督学习部分。如果是1,则是SUV测试图像。-1表示轿车。
int labels[29] = { 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 };
//将标签放入29行1列的矩阵中。
Mat labels_mat(num_train_images, 1, CV_32S);
cout << "开始训练..." << endl;
//设置SVM参数(对这些值不太确定)
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::RBF);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
svm->setGamma(1);
svm->setDegree(3);
cout << "参数已设置..." << endl;
svm->train(training_mat, ROW_SAMPLE, labels_mat);
cout << "结束训练" << endl;
waitKey(0);
Mat test_image(1, image_area, CV_32FC1);        //创建一个1 x 1200的矩阵来存放测试图像。
Mat SUV_image = imread("SUV_1.jpg", 0);         //读取文件文件夹
int jj = 0;
for (int i = 0; i < SUV_image.rows; i++)
{    
    for (int j = 0; j < SUV_image.cols; j++)    
    {        
        test_image.at<float>(0, jj) = SUV_image.at<uchar>(i, j);    //填充训练矩阵        
        jj++;    
    }
}
//如果是SUV,应该返回1;如果是轿车,应该返回-1
float result = svm->predict(test_image);
if (result < 0)    
    cout << "轿车" << endl;
else    
    cout << "SUV" << endl;
cout << "结果: " << result << endl;
namedWindow("Test Image", CV_WINDOW_NORMAL);
imshow("Test Image", SUV_image);
waitKey(0);

回答:

参考这篇文章来解决我遇到的问题。使用HOG特征和SVM对车辆进行分类

在这篇文章中,我使用HOG特征而不是图像的普通像素值。训练矩阵不再是白色的,分类器工作得很好。此外,输出结果是1或-1。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注