0

I'm trying to use OpenCV to train a neural network in C++.

I can't convert between cv::Mat* (or Mat*, if namespace cv is used) to CvMat*, and I would appreciate some help with this.


Let me elaborate:

I've got two data structures of cv::Mat* type. The first is the set of feature vectors and the second is the set of expected output.

   cv::Mat *feat = new cv::Mat(3000, 100, CV_32F, featureData);
   cv::Mat *op = new cv::Mat(3000, 2, CV_32F, expectedOutput);

(These are 3000 data points of feature vector length = 100 and output state = 2)

These two matrices had been populated with data of correct dimensions and seem to be working fine when sample data were printed on the console.

The neural network has been initialized as:

   int layers_array[] = {100,200,2};    //hidden layer nodes = 200

   CvMat* layer = cvCreateMatHeader(1, 3, CV_32SC1); 
   cvInitMatHeader(layer, 1,3,CV_32SC1, layers_array);

   CvANN_MLP nnetwork;
   nnetwork.create(layer, CvANN_MLP::SIGMOID_SYM, SIGMOID_ALPHA, SIGMOID_BETA);

Now, the train method of ANN is of the following template:

   virtual int train( const CvMat* inputs, const CvMat* outputs,
                       const CvMat* sampleWeights, const CvMat* sampleIdx=0,
                       CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(),
                       int flags=0 );

I tried to convert between cv::Mat * and CvMat * using the following code:

   CvMat featMat,opMat;

   (&featMat)->cols = feat->cols;
   (&featMat)->rows = feat->rows;
   (&featMat)->type = CV_32F;
   (&featMat)->data.fl = (float *)feat->data;


   (&opMat)->cols = op->cols;
   (&opMat)->rows = op->rows;
   (&opMat)->type = CV_32F;
   (&opMat)->data.fl = (float *)op->data;

   //setting up the ANN training parameters

   int iterations = network.train(&featMat, &opMat, NULL, NULL, trainingParams);

When I run this code, I get the following error message in my console:

**OpenCV Error: Bad argument (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) in CvANN_MLP::prepare_to_train, file ..\..\OpenCV-2.3.0-win-src\OpenCV-2.3.0\modules\ml\src\ann_mlp.cpp, 
line 694**

I understand the error message. However, to the best of my knowledge, I believe I haven't made a mess of the number of nodes in the input/output layer.

Can you please help me understand what is going wrong?

metsburg
  • 2,021
  • 1
  • 20
  • 32
  • I'm not too familiar with the old C `CvMat` usage, but try setting `type` to `CV_32FC1` instead, although I think it's handled the same. – chappjc Nov 07 '14 at 07:03
  • @chappjc: tried. not working. – metsburg Nov 07 '14 at 08:01
  • possible duplicate of [convert cv::Mat to const CvMat\* or CvMat\*](http://stackoverflow.com/questions/11027574/convert-cvmat-to-const-cvmat-or-cvmat) – Roger Rowland Nov 07 '14 at 08:25
  • @RogerRowland: Not exactly. This is in continuation of the answer provided in http://stackoverflow.com/questions/11027574/convert-cvmat-to-const-cvmat-or-cvmat. The solution provided in that question has been considered here. Still, it doesn't seem to work. Which forms the crux of my question. So... possibly not a duplicate. – metsburg Nov 07 '14 at 08:49
  • 1
    Well, your conversion code is wrong because you are trying to initialise an object that you haven't created. The dupe I pointed to shows you other ways to do that conversion. If you try the simple assignment shown in the accepted answer, does it work? – Roger Rowland Nov 07 '14 at 08:52
  • Moreover, the error message I'm seeing maybe more due to an improper implementation of ANN and less due to the pointer dynamics of cv::Mat. Unless the root cause is determined, it can't be confirmed as a duplicate. – metsburg Nov 07 '14 at 08:52
  • Assignment is what I tried initially. It doesn't work. – metsburg Nov 07 '14 at 08:53

1 Answers1

2

please try to avoid pointers to cv::Mat as well as CvMat* in general.

luckily, there's an overload to CvANN_MLP::train that takes cv::Mat as args, so use that instead:

   cv::Mat feat = cv::Mat(3000, 100, CV_32F, featureData);
   cv::Mat op = cv::Mat(3000, 2, CV_32F, expectedOutput);

   int layers_array[] = {100,200,2};    //hidden layer nodes = 200
   cv::Mat layers = cv::Mat (3, 1, CV_32SC1, layers_array );

   CvANN_MLP nnetwork;
   nnetwork.create(layers, CvANN_MLP::SIGMOID_SYM, SIGMOID_ALPHA, SIGMOID_BETA);

   int iterations = nnetwork.train(feat, op, cv::Mat(), cv::Mat(), CvANN_MLP_TrainParams());
berak
  • 39,159
  • 9
  • 91
  • 89