OpenCV从Mat中访问元素

5

我正在尝试学习OpenCV,作为一个固执己见的人,我正在尝试运行以下算法:

 cv::Mat cur_features;
 cv::goodFeaturesToTrack(current_image, cur_features, 400, 0.01, 0.01);

现在,作为一个固执己见的个体,我很想看看cur_features保存了什么...我期望得到一个400x2的cv::Mat,但实际上我得到的是一个400x1的cv::Mat

没关系,我认为可能是直接索引的问题。然而,我却无法从cur_features.at(0)中提取出一个值并将其打印出来。

我做错了什么?我已经看过goodFeaturesToTrack_Demo.cpp的示例。有一些与我的不同之处需要注意。鉴于该示例,我尝试了以下调用:

 std::cout << cur_features.size() << std::endl; // This throws a compile time error even though its in the example
 std::cout << cur_features.at<Point2f>(0).x << std::endl; //This throws a run time error.

请问有没有相关的文档能够指导我如何实现我的目标?goodFeaturesToTrack告诉你它返回一个OutputArray,其中包含角点的向量,但是它并没有描述这些角点的类型。如果我使用其他方法得到了这个结果,在文档中我应该查找哪个部分来寻找这个答案?
编辑:此外,Mat :: type()的作用是什么?我找不到可以解释返回值的地方...我在文档中寻找枚举类型时遇到了困难。
 std::cout << current_image.type() << std::endl; //This returns 0
 std::cout << cur_features.type() << std::endl; //This returns 13

1
关于类型枚举,请查看types_c.h,您会发现#define CV_8UC1 CV_MAKETYPE(CV_8U,1)等等。这就是type()返回的内容。 - Pablo
3个回答

5
作为建议,尝试使用指定的维数和类型来初始化矩阵。
 cv::Mat cur_features(400,1,CV_32_FC1); //400x1 32 bits, 1 channel
 cv::Mat cur_features2(400,1,CV_32_FC2); //400x1 32 bits, 2 channels

获取Mat的值
int pos = 0;
foat value = cur_features.at<float>(pos);
cv::Vec2f value2 = cur_features2.at<Vec2f>(pos); // for a two channel, CV_23F image

还有一种对我很有帮助的Visual Studio调试技巧

  • 1- 在调试时右键单击cur_features。
  • 2- 快速监视
  • 3- 输入以下内容:

    (float*)cur_features.data,400

  • 4- 您将看到数组的所有值


修正错误:通道数也会影响单个像素的数据类型,而不是32_FC1,而是CV_32_FC1。 - Barney Szabolcs

4
原来即使我的goodFeaturesToTrack返回了一个400x1的数组,我也是在黑色图像上执行的,因此没有角点。这导致了...
 cur_features.data == NULL

有趣的情况是,C代码似乎比C++代码更简单、更易于使用。


2
这里写着:http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html 在my local copy of OpenCV中的goodFeaturesToTrack_Demo.cpp中声明为vector<Point2f>,应该将其作为输出数组。
  vector<Point2f> corners;
  ...
  /// Apply corner detection
  goodFeaturesToTrack( src_gray, 
               corners,
               maxCorners,
               qualityLevel,
               minDistance,
               Mat(),
               blockSize,
               useHarrisDetector,
               k );

更新:我上面提供的链接使用模板OutputArray参数来表示角落。2.1版本的库在http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html文档中确实声明了vector<Point2f>

1
嗨,Pablo,谢谢你的回复。我在文档中找不到说明应该使用vector<Point2f>的地方。但是,我同意示例中注明了使用Point2f结构的std::vector。 - Constantin
std::vectorcv::vector 是相同的(方便的typedef,检查头文件)。不同的是 cv::Vec<N,_Tp> - Barney Szabolcs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接