6

In OpenCV it's common to access a pixel in a Mat object like so:

float b = A.at<float>(4,5);

The problem is, if you don't know the type of data apriori, you're stuck. Is there a way of writing generic function headers that accept a Mat with template type T? I'd like to build functions for linear algebra calculations, and I don't want to have an if clause separating double and float. Something like:

 void func(Mat <T> a) { 
     a.at<T>(3,4) = ...

Is this possible in OpenCV?

nbubis
  • 2,304
  • 5
  • 31
  • 46

3 Answers3

3

It appears one more way to do this would be to use the Mat_ object instead of Mat:

template<typename T>
void func(Mat_ <T> a) {
   cout << a(0,0) << endl;
}

If you want to pass a Mat to func, you must specify the type:

Mat a;
func(Mat_<float>(a)); 

If you use a differnt type than the original Mat type, OpenCV will preform the conversion for you.

nbubis
  • 2,304
  • 5
  • 31
  • 46
1

This is possible simply by templating your function :

template<typename T>
void func(Mat a) { 
    a.at<T>(3,4) = ...

But note that you have no easy way to constraint the type T to be only double or float, and your algorithm won't probably work on other types, but it may not be an actual problem.

Also note the drawbacks of using templates : What are the disadvantages of using templates?

Community
  • 1
  • 1
zakinster
  • 10,508
  • 1
  • 41
  • 52
  • This code doesn't compile - have you tried this or were you just guessing? – nbubis Apr 12 '13 at 08:40
  • I wasn't guessing but I have to admit that I didn't try to compile it sorry, there were a typo inside the function. – zakinster Apr 12 '13 at 08:49
  • Well actually I didn't pay much attention to the Mat class of openCV, i thought it was the Mat class that was templated as your code suggests but it's actually only the method, so the typo is the other way around. The last edit should compiles toward the openCV Mat class. – zakinster Apr 12 '13 at 08:57
1

OpenCV 2 Cookbook page 40 claims that it's impossible. Also, regarding Mat_:

" Using the at method of the cv::Mat class can sometimes be cumbersome because the returned type must be specified as a template argument for each call. In cases where the matrix type is known, it is possible to use the cv::Mat_ class which is a template subclass of cv::Mat.

cv::Mat_<uchar> im2= image; // im2 refers to image 
im2(50,100)= 0; //access to row 50 and column 100 

Since the type of the cv::Mat_ elements is declared when the variable is created, the operator() method knows at compile-time which type to return."

EDIT: Use Mat.type()

Mat image=imread("image.bmp");
cout<<image.type();

Console output:

16

Wiki: The method returns the matrix element type, an id, compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array etc.

LovaBill
  • 5,107
  • 1
  • 24
  • 32