Question

I'm writing a program which uses OpenCv neural networks module along with C# and OpenCvSharp library. It must recognise the face of user, so in order to train the network, i need a set of samples. The problem is how to convert a sample image into array suitable for training. What i've got is 200x200 BitMap image, and network with 40000 input neurons, 200 hidden neurons and one output:

        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);

So then I'm trying to convert BitMap image into CvMat array:

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;
        }
    }

And then, when trying to train it, I've got this exception:

input training data should be a floating-point matrix withthe number of rows equal to the number of training samples and the number of columns equal to the size of 0-th (input) layer

Code for training:

        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);

I'm new to OpenCV and I think I did something wrong in converting because of lack of understanding CvMat structure. Where is my error and is there any other way of transforming the bitmap?

Was it helpful?

Solution

With the number of rows equal to the number of training samples

That's 10 samples.

and the number of columns equal to the size of 0-th (input) layer

That's inp_layer_size.

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

I primarily do C++, so forgive me if I'm misunderstanding, but your pixel loop will need adapting in addition.

Your inner loop looks broken, as you assign to val, but never use it, and also never increment your counter.

In addition, in your outer loop assigning trainMAt = res; for every image doesn't seem like a very good idea.

I am certain you will get it to operate correctly, just keep in mind the fact that the goal is to flatten each image into a single row, so you end up with 10 rows and inp_layer_size columns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top