【问题标题】:Unwieldy CvMat* in ANN using OpenCV使用 OpenCV 在 ANN 中使用笨拙的 CvMat*
【发布时间】:2015-01-03 20:42:15
【问题描述】:

我正在尝试使用 OpenCV 在 C++ 中训练神经网络。

我无法在 cv::Mat*(或 Mat*,如果使用命名空间 cv)与 CvMat* 之间进行转换,我将不胜感激。


让我详细说明:

我有两个 cv::Mat* 类型的数据结构。第一个是特征向量的集合,第二个是期望输出的集合。

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

(这些是特征向量长度 = 100 且输出状态 = 2 的 3000 个数据点)

这两个矩阵已经填充了正确维度的数据,并且在控制台上打印样本数据时似乎工作正常。

神经网络已被初始化为:

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

现在,人工神经网络的train方法是如下模板:

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

我尝试使用以下代码在 cv::Mat * 和 CvMat * 之间进行转换:

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

当我运行此代码时,我在控制台中收到以下错误消息:

**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**

我理解错误信息。但是,据我所知,我相信我并没有弄乱输入/输出层中的节点数量。

您能帮我了解一下出了什么问题吗?

【问题讨论】:

  • 我对旧的 C CvMat 用法不太熟悉,但请尝试将 type 设置为 CV_32FC1,尽管我认为它的处理方式相同。
  • @chappjc:试过了。不工作。
  • @RogerRowland:不完全是。这是stackoverflow.com/questions/11027574/… 中提供的答案的延续。该问题中提供的解决方案已在此处考虑。不过,它似乎不起作用。这构成了我问题的症结所在。所以...可能不是重复的。
  • 嗯,你的转换代码是错误的,因为你试图初始化一个你还没有创建的对象。我指出的骗局向您展示了进行这种转换的其他方法。如果您尝试接受答案中显示的简单作业,它有效吗?

标签: c++ opencv opencv-mat


【解决方案1】:

请尽量避免指向 cv::Mat 和 CvMat* 的指针。

幸运的是,有一个 overload to CvANN_MLP::train 将 cv::Mat 作为参数,因此请改用它:

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

【讨论】:

  • 像魅力一样工作!我没有注意到重载的方法。非常感谢。 :)
猜你喜欢
  • 1970-01-01
  • 2014-09-16
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2014-09-16
  • 2011-10-17
相关资源
最近更新 更多