Ask Your Question

cv::Mat imread to unsigned short*?

asked 2017-10-10 09:55:48 -0600

antithing gravatar image

I am trying to replace the following function with opencv: (from:

  uint64_t loadDepthFromPath(std::string filepath, pangolin::Image<unsigned short> & depth)

        pangolin::TypedImage depthRaw = pangolin::LoadImage(filepath, pangolin::ImageFileTypePng);

        pangolin::Image<unsigned short> depthRaw16((unsigned short*)depthRaw.ptr, depthRaw.w, depthRaw.h, depthRaw.w * sizeof(unsigned short));

        for (unsigned int i = 0; i < 480; i++)
            for (unsigned int j = 0; j < 640; j++)
                depth.RowPtr(i)[j] = depthRaw16(j, i) / 5;

        uint64_t time = getCurrTime();
        return time;

This returns a pangolin::Image<unsigned short>, that is then passed to a function:


where depth.ptr is unsigned short *

I am trying to remove pangolin from this, and use opencv instead.

So I load the same image:

     std::string frame1 = "rgbd_dataset_freiburg1_desk/depth/1305031453.374112.png";

Mat img1;
img1 = imread(frame1, 0);

convert it to unsigned short:

    cv::Mat mat_ushort1(img1.cols,img1.rows, CV_16UC1);
img1.convertTo(mat_ushort1, CV_16UC1);

Then use the pointer to the data to pass to the function:

initModel((unsigned short*);

The problem is, I see a very different result when I use this method. Where am i going wrong here? How can I replicate the pangolin function with openCv?

thank you.

edit retag flag offensive close merge delete


  • make a quick check, if the original images are already 16u:

    img1 = imread(frame1, -1); cout << img1.type();

    (this will import the images "as they are on disk", while now, you're forcing it into 8bit)

    if the answer is 2, you can skip the convertTo (else you're losing precision, importing as 8u, and converting that)

berak gravatar imageberak ( 2017-10-10 10:09:29 -0600 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2017-10-10 10:14:53 -0600

antithing gravatar image

updated 2017-10-10 10:35:48 -0600

Thanks! The answer was 2. I have switched to imread(frame1, -1) and initModel((unsigned short*);`, And once i add the scaling that is evident in the pangolin function, it looks identical. Thank you very much for your help!

edit flag offensive delete link more


H, it has been a few years. I am doing exactly the same thing. Could you tell me what is the scale and where I should add it ?? Thanks so much!!

kyle gravatar imagekyle ( 2019-09-29 11:10:11 -0600 )edit

answered 2019-09-29 11:38:37 -0600

kyle gravatar image

For people who may be interested in the question in the future. I believe you all want to use the ICPCUDA code. If you want to get the same result as using pangolin after replacing it by opencv you need

1: Use cv::Mat firstRaw = cv::imread(first_path , -1); to read image
2: divided the image value by 5(original code has a scale 5). Something like

void loadDepthOpencv(cv::Mat &firstRaw, std::string path) {

  for (unsigned int i = 0; i < firstRaw.rows; i++) {
    for (unsigned int j = 0; j < firstRaw.cols; j++) {
      firstRaw.ptr<ushort>(i)[j] = firstRaw.ptr<ushort>(i)[j]/5;


3: Give the scaled data to ICP model

  icpOdom.initICPModel((unsigned short*);
  icpOdom.initICP((unsigned short*);//same work flow as the first one
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2017-10-10 09:55:48 -0600

Seen: 2,663 times

Last updated: Oct 10 '17