Ask Your Question

Return Mat_<float> data not uchar

asked 2018-03-28 13:23:27 -0500

jasonalh gravatar image

I'm refactoring some code from cimg to opencv. I have the following lines that should return Mat_<float>.data.

  // Get a pointer to the data.
  //  T* Data() { return; } <-cimg calls
  //  const T* Data() const { return; } <-cimg.calls
  T* Data() { return; }
  const T* Data() const { return; }

but I get a compile error:

error: cannot initialize return object of type 'float *' with an lvalue of type 'uchar *' (aka 'unsigned char *')
  T* Data() { return; }

Other part of the code:

      cv::Mat_<T> image_;
      image_ = cv::imread(filename.c_str(), CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);

From what I've read is of type uchar. But shouldn't data be float when I use Mat_<float>?

Thanks, Jason

edit retag flag offensive close merge delete


CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH -- that's one of the few situations with opencv, where you cannot estimate the type at compile time.

thus you cannot use "typed" template Mat's here.

reconsider your design.

berak gravatar imageberak ( 2018-03-28 13:28:41 -0500 )edit

Ok, then I should use cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR) But are you also saying that cv::Mat_<T> image_ will not be loaded as a float when imread is called?

jasonalh gravatar imagejasonalh ( 2018-03-28 13:45:57 -0500 )edit

cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR) would return CV_8UC3 data, uchar, not float.

again why do you insist on using Mat_<float> (or any templated version ?)

berak gravatar imageberak ( 2018-03-28 13:51:53 -0500 )edit

This is an older code base and the main class/object is built on templates.

// Templated on the number of channels.
template <typename T> class Image {
jasonalh gravatar imagejasonalh ( 2018-03-28 13:59:07 -0500 )edit

maybe that's a bad idea. cv::Mat is NOT a template class by default

berak gravatar imageberak ( 2018-03-28 14:04:10 -0500 )edit

Well that's unfortunate. Isn't that what cv::Mat_<T> is for? To handle template classes.

jasonalh gravatar imagejasonalh ( 2018-03-28 14:06:43 -0500 )edit

"Isn't that what cv::Mat_<T>is for?" sure.

again, in 90% of all cases you know the type offhand.

but you can't use templates, if the type changes / is determined at runtime

berak gravatar imageberak ( 2018-03-28 14:09:12 -0500 )edit

1 answer

Sort by » oldest newest most voted

answered 2018-03-29 05:52:11 -0500

rwong gravatar image

updated 2018-03-29 06:21:50 -0500

For most image file types, cv::imread returns an image whose channel precision is 8-bit unsigned (CV_8UC1, CV_8UC3, CV_8UC4).

Most image file types simply do not support the storage of floating-point data. It is either converted into 8-bit unsigned values, or it does something else unexpected.

Before giving a suggestion on how to persist (save/load) matrices of floating point values, please edit your question to provide more background information.

As berak says in the comment, there is a fundamental difference between "compile-time type" and "runtime type", in a statically-typed language such as C++. There are certain limitations we must live with C++, and there are many techniques for overcoming or working around them. However it will be too long to cover here.

To correctly check and convert type, use the following snippet:

cv::Mat matInputUnknownType = cv::imread("...");
int matType = matInputUnknownType.type();
if (matType == CV_8UC1)
    cv::Mat1b mat = matInputUnknownType;
   //  use it
if (matType == CV_8UC3)
    cv::Mat3b mat = matInputUnknownType;
   //  use it
if (matType == CV_8UC1)
    cv::Mat4b mat = matInputUnknownType;
   //  use it

If your code always expect CV_8UC3, you can use the following:

cv::Mat3b matInput;
cv::Mat matTemp = cv::imread("...");
switch (matTemp.type())
case CV_8UC1: cv::cvtColor(matTemp, matInput, CV_GRAY2BGR); break;
case CV_8UC3: matInput = matTemp; break;
case CV_8UC4: ...
default: dance();
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2018-03-28 13:23:27 -0500

Seen: 656 times

Last updated: Mar 29 '18