Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV access element from Mat

Tags:

c++

opencv

I am attempting to learn OpenCV, and being a hard-head, I am trying to run the following algorithm:

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

Now, being the hard-headed individual, I am interested to see what cur_features is holding... I expected a 400x2 cv::Mat but instead I got a 400x1 cv::Mat

No biggy, I think maybe its a direct index. However, for the LIFE of me I CANNOT extract a value from cur_features.at(0) and print it out.

What am I doing wrong? I have seen the goodFeaturesToTrack_Demo.cpp. Some things to note on that demo that differ for mine. I tried the following calls given that example:

 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.

Could anyone direct me to some documentation that explains how to achieve my goal? The goodFeaturesToTrack tells you it returns an OutputArray which is a vector of corners, but nowhere does it describe what the type of those corners are. Where in the documentation would I look for this answer in case I get it with other methods?


Edit: Also, whats the Point of Mat::type(). I cannot find where the returned value can be explained... I'm looking for an enumeration in the documentation but having trouble finding it.

 std::cout << current_image.type() << std::endl; //This returns 0
 std::cout << cur_features.type() << std::endl; //This returns 13
like image 728
Constantin Avatar asked Jun 08 '12 23:06

Constantin


3 Answers

As a suggestion, try to initialize matrices with dimensions and type

 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

To get a value of a 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

And a handy debug technique for Visual Studio that helped me a lot

  • 1- Right click cur_features when debugging.
  • 2- QuickWatch
  • 3- Write this:

    (float*)cur_features.data,400

  • 4- You will see all the values of the array

like image 172
Jav_Rock Avatar answered Nov 16 '22 18:11

Jav_Rock


It turns out that even though my goodFeaturesToTrack returns a 400x1, I was doing it on a black image and thus no corners. This caused

 cur_features.data == NULL

Interesting situation where the C code seems to be easier and more user friendly than the C++ code.

like image 34
Constantin Avatar answered Nov 16 '22 19:11

Constantin


It says here: http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html

That you should give it a vector<Point2f> as the output array.

It is declared as such in the goodFeaturesToTrack_Demo.cpp in my local copy of OpenCV:

  vector<Point2f> corners;
  ...
  /// Apply corner detection
  goodFeaturesToTrack( src_gray, 
               corners,
               maxCorners,
               qualityLevel,
               minDistance,
               Mat(),
               blockSize,
               useHarrisDetector,
               k );

UPDATE: The link I gave above uses a template OutputArray argument for corners. The docs at http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html for the 2.1 version of the library do state vector<Point2f>

like image 2
Pablo Avatar answered Nov 16 '22 18:11

Pablo