1

C# および OpenCvSharp ライブラリと共に OpenCv ニューラル ネットワーク モジュールを使用するプログラムを作成しています。ユーザーの顔を認識しなければならないので、ネットワークをトレーニングするにはサンプルのセットが必要です。問題は、サンプル画像をトレーニングに適した配列に変換する方法です。私が持っているのは、200x200 の BitMap 画像と、40000 個の入力ニューロン、200 個の隠れニューロン、および 1 個の出力を持つネットワークです。

        CvMat layerSizes = Cv.CreateMat(3, 1, MatrixType.S32C1);
        layerSizes[0, 0] = 40000;
        layerSizes[1, 0] = 200;
        layerSizes[2, 0] = 1;
        Network = new CvANN_MLP(layerSizes,MLPActivationFunc.SigmoidSym,0.6,1);

それで、BitMap イメージを CvMat 配列に変換しようとしています。

private void getTrainingMat(int cell_count, CvMat trainMAt, CvMat responses)
    {
        CvMat res = Cv.CreateMat(cell_count, 10, MatrixType.F32C1);//10 is a number of samples
        responses = Cv.CreateMat(10, 1, MatrixType.F32C1);//array of supposed outputs
        int counter = 0;
        foreach (Bitmap b in trainSet)
        {
            IplImage img = BitmapConverter.ToIplImage(b);
            Mat imgMat = new Mat(img);
            for (int i=0;i<imgMat.Height;i++)
            {
                for (int j = 0; j < imgMat.Width; j++)
                {
                    int val =imgMat.Get<int>(i, j);
                    res[counter, 0] = imgMat.Get<int>(i, j);
                }
                responses[i, 0] = 1;
            }
            trainMAt = res;
        }
    }

そして、それを訓練しようとすると、次の例外があります。

入力トレーニング データは、トレーニング サンプルの数に等しい行数と 0 番目の (入力) レイヤーのサイズに等しい列数を持つ浮動小数点行列である必要があります。

トレーニング用コード:

        trainMAt = Cv.CreateMat(inp_layer_size, 10, MatrixType.F32C1);
        responses = Cv.CreateMat(inp_layer_size, 1, MatrixType.F32C1);
        getTrainingMat(inp_layer_size, trainMAt, responses);
        Network.Train(trainMAt, responses, new CvMat(),null, Parameters);

私は OpenCV を初めて使用し、CvMat 構造を理解していないため、変換に何か問題があったと思います。私のエラーはどこにあり、ビットマップを変換する他の方法はありますか?

4

1 に答える 1

0

行数がトレーニング サンプル数と等しい場合

10サンプルです。

0 番目の (入力) レイヤーのサイズに等しい列数

それが inp_layer_size です。

trainMAt = Cv.CreateMat(10, inp_layer_size, MatrixType.F32C1);
responses = Cv.CreateMat(10, 1, MatrixType.F32C1); // 10 labels for 10 samples

私は主に C++ を使用しているため、誤解があればご容赦ください。ただし、ピクセル ループをさらに調整する必要があります。

に割り当てると、内側のループが壊れているように見えますvalが、決して使用したり、カウンターをインクリメントしたりしないでください。

さらに、外側のループ trainMAt = res;ですべての画像に割り当てることは、あまり良い考えではないようです。

正しく操作できると確信していますが、目標は各画像を 1 つの行にフラット化することであるため、最終的には 10 行と 10 列になることに注意してくださいinp_layer_size

于 2014-05-14T18:14:00.423 に答える