各行のサイズは、画像サイズと同じである必要はありません。それはあなたが持っている機能によって異なります。画像分類に平均値を使用するだけでは十分ではありません。写真を見たときにオブジェクトをどのように分類するかを考えてみてください。平均値は計算しませんが、輪郭、接続された領域、場合によっては脳の処理の背景にある個々のピクセル値を調べます。
より多くの機能を得るために、私はあなたに提案があります。特徴抽出部分の各列の平均値を計算します。これはおそらくより便利です。
また、別の特徴抽出には、PCA を使用できます。通常、SVM をトレーニングするためにすべてのピクセル値を連続して与えることができますが、200*200 の画像であっても、これは 40.000 の特徴になります。多くの情報を失うことなく、この機能の次元を削減する必要があります。これは、分散の許容パーセンテージを保持することを意味します。したがって、これには PCA が使用され、特徴空間の次元が削減され、分散が許容範囲内に維持されます。
PCA を使用して特徴空間を削減する方法を紹介します。最初に、イメージを Mat 変数に行ごとにロールするよりも、イメージを取得する必要があります。
csv の読み取り:
void read_csv(const string& filename, vector& images, vector& labels, char separator = ';')
{
std::ifstream file(filename.c_str(), ifstream::in);
if (!ファイル)
{
string error_message = "有効な入力ファイルが指定されていません。指定されたファイル名を確認してください。";
CV_Error(1, error_message);
}
文字列行、パス、クラスラベル。
while (getline(ファイル、行))
{
stringstream liness(行);
getline(行、パス、区切り);
getline(ライン、クラスラベル);
if(!path.empty() && !classlabel.empty())
{
Mat im = imread(パス, 0);
images.push_back(im);
labels.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 redcution を適用して、200*200 画像 (40000 特徴) を 500 特徴サイズに縮小しました。これを分類するために MLP を適用しました。この testData 変数と trainData 変数は、SVM でも使用できます。また、SO の投稿で MLP を使用してトレーニングする方法を確認することもできます。
OpenCV ニューラル ネットワーク シグモイド出力