我正在尝试使用图像进行分类(下一步将基于特征进行分类,但现在只想尝试一下是否正确)
这是我的代码。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main(){
Mat image[2];
image[0]= imread("image.jpg",0);
image[1]= imread("wrongimage.jpg",0);
Mat rotated = imread("image.jpg",0);
image[0] = image[0].reshape(0, 1); //SINGLE LINE
image[1] = image[1].reshape(0, 1); //SINGLE LINE
// image[0].convertTo(image[0], CV_32FC1); //CONVERT TO 32FC1
// image[1].convertTo(image[1], CV_32FC1); //CONVERT TO 32FC1
Mat new_image(2,1,CV_32FC1,image); //CONVERT TO 32FC1
float labels[2] = {1.0, -1.0};
Mat labelsmat(2,1,CV_32FC1,labels); //correct labels 1
labelsmat.convertTo(labelsmat, CV_32FC1);
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.gamma = 3;
params.degree = 3;
CvSVM svm;
svm.train(new_image, labelsmat, Mat(),Mat(),params);
// svm.train(training_mat2, labelsmat, Mat(),Mat(),params);
// svm.train(training_mat2, labelsmat, Mat(), Mat(), params);
svm.save("svm.xml"); // saving
svm.load("svm.xml"); // loading
rotated = rotated.reshape(0,1);
rotated.convertTo(rotated, CV_32FC1);
svm.predict(rotated);
}
由于使用OpenCV SVM的训练图像缺乏文档记录,我尝试通过阅读使用OpenCV和SVM处理图像以及http://docs.opencv.org/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html来管理一些东西。
不知何故,我成功地训练了我的图像,但我认为这个训练XML文件不正确,因为我没有指出哪个图像是正确的(1)或错误的(-1)。
当我尝试使用已经训练好的图像进行预测时,它给我一个错误。
OpenCV错误:输入参数的大小不匹配(样本大小与训练所用的不同)在cvPreparePredictData中, 文件/tmp/opencv-DXLLi8/opencv-2.4.9/modules/ml/src/inner_functions.cpp, 行1114 libc++abi.dylib:以未捕获的异常类型终止 cv :: Exception: /tmp/opencv-DXLLi8/opencv-2.4.9/modules/ml/src/inner_functions.cpp:1114: 错误:(-209)样本大小与训练所用的不同,在函数cvPreparePredictData中
这里也有SVM生成的XML。
<?xml version="1.0"?>
<opencv_storage>
<my_svm type_id="opencv-ml-svm">
<svm_type>C_SVC</svm_type>
<kernel><type>LINEAR</type></kernel>
<C>1.</C>
<term_criteria><epsilon>1.1920928955078125e-07</epsilon>
<iterations>1000</iterations></term_criteria>
<var_all>1</var_all>
<var_count>1</var_count>
<class_count>2</class_count>
<class_labels type_id="opencv-matrix">
<rows>1</rows>
<cols>2</cols>
<dt>i</dt>
<data>
-1 1</data></class_labels>
<sv_total>1</sv_total>
<support_vectors>
<_>
-1.56709105e-02</_></support_vectors>
<decision_functions>
<_>
<sv_count>1</sv_count>
<rho>-1.</rho>
<alpha>
1.</alpha>
<index>
0</index></_></decision_functions></my_svm>
</opencv_storage>
更新
我已经按照guneykayim的建议更改了代码,但现在我遇到了EXC_BAD_ACCESS (code=1 address=...) 错误。下面是我的更新后的代码。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main(){
Mat image[2];
image[0]= imread("image.jpg",0);
image[1]= imread("wrongimage.jpg",0);
Mat rotated = imread("image.jpg",0);
image[0] = image[0].reshape(0, 1); //SINGLE LINE
image[1] = image[1].reshape(0, 1); //SINGLE LINE
// int size = sizeof(image)/sizeof(Mat);
// image[0].convertTo(image[0], CV_32FC1); //CONVERT TO 32FC1
// image[1].convertTo(image[1], CV_32FC1); //CONVERT TO 32FC1
Mat new_image(2,341318,CV_32FC1,image); //CONVERT TO 32FC1
float labels[2] = {1.0, -1.0};
Mat labelsmat(2,1,CV_32FC1,labels); //correct labels 1
labelsmat.convertTo(labelsmat, CV_32FC1);
cout<<image[0].size()<<endl;
cout<<new_image.size()<<endl;
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.gamma = 3;
params.degree = 3;
CvSVM svm;
svm.train_auto(new_image, labelsmat,Mat(),Mat(),params);
// svm.train_(new_image, labelsmat, Mat(),Mat(),params);
// svm.train(training_mat2, labelsmat, Mat(),Mat(),params);
// svm.train(training_mat2, labelsmat, Mat(), Mat(), params);
svm.save("svm.xml"); // saving
svm.load("svm.xml"); // loading
rotated = rotated.reshape(0,1);
rotated.convertTo(rotated, CV_32FC1);
cout<<svm.predict(rotated)<<endl;
}
我的图片尺寸是:[170569 x 1],而新图片的尺寸是 [341318 x 2]
。
new_image
。请确保你正在正确地创建它。为什么要注释掉图像类型转换代码?请更新你的问题并附上新代码,不要分享这样的链接。最好在原始问题的底部发布更新后的代码。 - guneykayimcv::Mat
类型有关。如果你没有看到一个正确的图像,那么你的问题肯定是在创建new_image
变量时出现了问题。 - guneykayimnew_image
是否正确生成。正确的大小并不意味着它被正确创建。 - guneykayim