1

I have a question about this peace of code.

...............
 cv::Mat image;
 image = cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR);
   if (image.empty()) {
   std::cerr << "Couldn't open file: " << filename << std::endl;
   exit(1);
 }

 cv::cvtColor(image, imageRGBA, CV_BGR2RGBA);


 imageGrey.create(image.rows, image.cols, CV_8UC1);

 *inputImage = (uchar4 *)imageRGBA.ptr<unsigned char>(0);
 *greyImage  = imageGrey.ptr<unsigned char>(0);

As I understand we create a openCV mat object. Read the image into it. But why we use filename.c_str()? instead of just filename? And why we convert from BGR to RGBA? cv::cvtColor(image, imageRGBA, CV_BGR2RGBA); I read in the documentation that imread reads the image as RGB not BGR. The most confusing for we is this part:

  *inputImage = (uchar4 *)imageRGBA.ptr<unsigned char>(0);
  *greyImage  = imageGrey.ptr<unsigned char>(0);

What's happening here? why we need all this casts? I know this is a lot of question, but I really want to know whats happening here.)

3
  • 1
    ...and where do you have this code snippet from? Commented May 9, 2013 at 22:18
  • 1
    from here: udacity.com/course/cs344. This code is included in a project as a reference. I want to understand it,I dont have any experience in openCV. Commented May 9, 2013 at 22:23
  • 1
    this isn't really related to cuda at all is it? Commented May 9, 2013 at 23:19

1 Answer 1

5
  1. imread takes a const char* as first argument and you cannot pass a std::string directly to it
  2. OpenCV stores matrices as BGR. So also imread adheres to this channel order (documentation might be misleading, don't confuse image format read (RGB) versus internal representation (BGR)). Based on your cuda tag I guess somebody wants to pass the image data to the GPU. GPUs typically work with RGBA format. It is not only about BGR<->RGB but also about having four channels in the interleaved format.
  3. The Mat::ptr() is templated (it is not casting!) because Mat hides the datatype from you. The code is risky, as it just assumes imread would create a Mat_<uchar> and so this is the right type to access. It would be better to start with a cv::Mat_<uchar> in the first place, then use Mat_<T>::operator[] to get a pointer to the first row etc.
  4. I don't know what comes next in your code but there might be a bug if the stride (step) is not considered.
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, that clear things. Now I have 2 additional questions. Because,I'm more focused on C I don't know C++ templates. Is *inputImage = (uchar4 *)imageRGBA.ptr<unsigned char>(0); returning a pointer to something(I assume to the mat object)? And what do you mean my an additional step? next comes memory allocation on the cuda device.
You get a pointer to the first element of the matrix. And even if you don't understand templates, I'm sure you can read and understand the OpenCV documentation at docs.opencv.org
But why I connot pass a std::string to it? Documentation gives the following prototype C++: Mat imread(const string& filename, int flags=1 ), I tried passing std::string into it on my local machine and it perfectly worked.
OpenCV API recently improved on that and your example was probably written for older versions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.