私は OpenCV と C++ が初めてで、OpenCV 内でガウス混合モデルを使用して分類器を構築しようとしています。私はそれがどのように機能するかを理解し、それを機能させました...多分。私は今このようなものを得ました:
モデルをトレーニングして保存した直後にトレーニング サンプルを分類すると、必要な結果が得られます。しかし、read()を使用してトレーニング データを再分類すると、クラスターの 1 つが欠落しています。これは、同じ GMM モデルから異なるクラスター結果を得たことを意味します。必要なクラスターがなくなったため、今はわかりません。同じデータを使用してモデルを再トレーニングするまで、分類を再度再現することはできません。実行時にコードをチェックし、Vec2dの結果値を返されたpredict()が 1 に割り当てられることはありませんでした (3 つのクラスターを設定しました)。
たぶんバグがあるか、何か間違ったことをしましたか?
ps VS2013で2.4.8を使用しています
私のプログラムは次のようになります:
電車の部分
void GaussianMixtureModel::buildGMM(InputArray _src){
//use source to train GMM and save the model
Mat samples, input = _src.getMat();
createSamples(input, samples);
bool status = em_model.train(samples);
saveModel();
}
モデルの保存/読み込み
FileStorage fs(filename, FileStorage::READ);
if (fs.isOpened()) // if we have file with parameters, read them
{
const FileNode& fn = fs["StatModel.EM"];
em_model.read(fn);
fs.release();
}
FileStorage fs_save(filename, FileStorage::WRITE);
if (fs_save.isOpened()) // if we have file with parameters, read them
{
em_model.write(fs_save);
fs_save.release();
}
一部を予測する
vector<Mat> GaussianMixtureModel::classify(Mat input){
/// samples is a matrix of channels x N elements, each row is a set of feature
Mat samples;
createSamples(input, samples);
for (int k = 0; k < clusterN; k++){
masks[k] = Mat::zeros(input.size(), CV_8UC1);
}
int idx = 0;
for (int i = 0; i < input.rows; i++){
for (int j = 0; j < input.cols; j++){
//process the predicted probability
Mat probs(1, clusterN, CV_64FC1);
Vec2d response = em_model.predict(samples.row(idx++), probs);
int result = cvRound(response[1]);
for (int k = 0; k < clusterN; k++){
if (result == k){
// change to the k-th class's picture
masks[k].at<uchar>(i, j) = 255;
}
...
// something else
}
}
}
}