每行的大小不必与图像大小相等。这取决于你有什么功能。使用平均值进行图像分类是不够的。想想看图片时如何对物体进行分类。您不计算平均值,但您可能会查看大脑处理背景中的轮廓、连接区域,有时甚至是单个像素值。
所以要获得更多功能,我有一个建议给你。计算特征提取部分的每一列的平均值。这可能会更有用。
对于另一个特征提取,您可以使用 PCA。通常,您可以连续提供所有像素值来训练 SVM,但即使对于 200*200 的图像,这也会产生 40.000 个特征,哇,这么多。您需要在不丢失太多信息的情况下减少此特征维度,这意味着保留可接受的方差百分比。所以 PCA 用于此,减少特征空间维度并以可接受的速率保持方差。
我将尝试向您展示如何使用 PCA 减少特征空间。首先,您需要获取图像,而不是将图像逐行滚动到 Mat 变量:
读取 csv:
void read_csv(const string& filename, vector& images, vector& labels, char separator = ';')
{
std::ifstream 文件(filename.c_str(), ifstream::in);
如果(!文件)
{
string error_message = "没有给出有效的输入文件,请检查给定的文件名。";
CV_Error(1, error_message);
}
字符串行、路径、类标签;
而(getline(文件,行))
{
串流线(线);
getline(线条,路径,分隔符);
getline(线条,类标签);
if(!path.empty() && !classlabel.empty())
{
Mat im = imread(path, 0);
images.push_back(im);
标签.push_back(atoi(classlabel.c_str()));
}
}
}
逐行滚动图像:
Mat rollVectortoMat(const vector<Mat> &data) // data is vector of Mat images
{
Mat dst(static_cast<int>(data.size()), data[0].rows*data[0].cols, CV_32FC1);
for(unsigned int i = 0; i < data.size(); i++)
{
Mat image_row = data[i].clone().reshape(1,1);
Mat row_i = dst.row(i);
image_row.convertTo(row_i,CV_32FC1, 1/255.);
}
return dst;
}
主要的
int main()
{
PCA pca;
vector<Mat> images_train;
vector<Mat> images_test;
vector<int> labels_train;
vector<int> labels_test;
read_csv("train1k.txt",images_train,labels_train);
read_csv("test1k.txt",images_test,labels_test);
Mat rawTrainData = rollVectortoMat(images_train);
Mat rawTestData = rollVectortoMat(images_test);
Mat trainLabels = getLabels(labels_train);
Mat testLabels = getLabels(labels_test);
int pca_size = 500;
Mat trainData(rawTrainData.rows, pca_size,rawTrainData.type());
Mat testData(rawTestData.rows,pca_size,rawTestData.type());
pca(rawTrainData,Mat(),CV_PCA_DATA_AS_ROW,pca_size);
for(int i = 0; i < rawTrainData.rows ; i++)
pca.project(rawTrainData.row(i),trainData.row(i));
for(int i = 0; i < rawTestData.rows ; i++)
pca.project(rawTestData.row(i),testData.row(i));
}
总而言之,您阅读了一个类似于 image_path;label 的 csv 文件。比您将图像逐行滚动到 Mat 变量。您应用 pca 以减少到 500 功能。我应用这些 PCA 缩减来将 200*200 图像(40000 个特征)减少到 500 个特征大小。比我应用 MLP 来分类这个。这个 testData 和 trainData 变量也可以与 SVM 一起使用。您还可以在我的 SO 帖子中查看如何使用 MLP 对其进行训练:
OpenCV 神经网络 Sigmoid 输出