在OpenCV中将图像转换为CvMat以训练神经网络

时间:2014-05-14 17:55:09

标签: c# opencv bitmap neural-network opencvsharp

我正在编写一个使用OpenCv神经网络模块以及C#和OpenCvSharp库的程序。它必须识别用户的脸,所以为了训练网络,我需要一组样本。问题是如何将样本图像转换为适合训练的阵列。我得到的是200x200 BitMap图像,网络有40000个输入神经元,200个隐藏神经元和一个输出:

        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结构的理解,我在转换方面做错了。我的错误在哪里,有没有其他方法来转换位图?

1 个答案:

答案 0 :(得分: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;并不是一个好主意。

我确信你会让它正常运行,但请记住,目标是将每个图像展平为一行,这样你最终会得到10行和inp_layer_size列。

相关问题