0

How can I convert vector<Point2d> to Mat.

     Mat newImg = Mat(ImagePoints);
     imwrite("E:/softwares/1.8.0.71/bin/newImg.png", newImg); 

This is not working since imWrite() will only accept channel 1 or 3 or 4 and the Image Points are 2 channel.

I am using OpenCV version 3.

SDD123
  • 53
  • 1
  • 12
  • 1
    so what do you expect and/or why do you want to imwrite? – Micka Jul 20 '16 at 20:51
  • I want to save the image to disk. Is there any other way to do this? – SDD123 Jul 21 '16 at 06:47
  • have a look at cv::FileStorage – Micka Jul 21 '16 at 07:05
  • But it will only save the data as XML/YAML. I want to save the image to disk. – SDD123 Jul 21 '16 at 07:22
  • but it is no image but 2d point coordinates (instead of color pixels). So again: What result do you expect? An image that looks like what? In the end: Afaik oprnCV cant save 64 bit channel values – Micka Jul 21 '16 at 07:25
  • I have tried this. Mat depthImage = cv::Mat(height, width, CV_16UC3); int i = 0; for (int h = 0; h < depthImage.rows; h++) { for (int w = 0; w < depthImage.cols; w++) { depthImage.at(h, w)[0] = imagePoints[i].x ; depthImage.at(h, w)[1] = imagePoints[i].y; depthImage.at(h, w)[2] = 1; i++; } } This is giving me an image but in 24 bit format. – SDD123 Jul 21 '16 at 07:40
  • since point positions can be negative you must use CV_16SC3 and then access by `depthImage.at` (Vec3s is 3 short values which each are each 16 bit). – Micka Jul 21 '16 at 07:45
  • Not sure whether openCV can save 16 bit signed values to png. – Micka Jul 21 '16 at 07:45
  • Yes. That works. But since it is 16 bit each, the resulting image is 48 bits. I tried to convert it into 16 bit using this. Mat u16; depthImage.convertTo(u16, CV_16S); But no luck. It is being converted to 24 bits with 8 bits each for each channel – SDD123 Jul 21 '16 at 07:50
  • My real problem is this [link](http://answers.opencv.org/question/98725/3d-clod-point-to-2d-image/) – SDD123 Jul 21 '16 at 07:51
  • I still dont get why you want to save an image. Btw: A depth image typically does not hold 3d or 2d point positions but only the distance from the scene to the camera looking through that pixel. So maybe you are not doing the right thing, if you want a depth image (typically single channel) as a result! – Micka Jul 21 '16 at 07:54
  • What I am trying to save is not the depth image. But the 2D projection of a 3D point cloud. – SDD123 Jul 21 '16 at 08:28
  • do you keep negative point locations (points that don't hit the image plane within the image range)? – Micka Jul 21 '16 at 08:32
  • what's the dimension of the resulting image? You have N points which are projected, but what's the dimension of the image you want to save? 1xN? Nx1? LxM where L+M=N? – Micka Jul 21 '16 at 12:36
  • I am able to save the 2D projection of the point Cloud. Thanks a lot for all the help. – SDD123 Jul 22 '16 at 06:48
  • If I want to save only the depth image, Can i just copy the depth info as follows. **newdepthimage.at(u,v) = Z ** Z is the z coordinate in the 3D cloud point – SDD123 Jul 22 '16 at 06:49
  • What type is ** depth **? – Micka Jul 22 '16 at 06:53
  • 16 bit png depth image. I dont undestand the question.. – SDD123 Jul 22 '16 at 11:22
  • signed (positive and negative values) or unsigned (only positive)? – Micka Jul 22 '16 at 11:24
  • depth value is in float. – SDD123 Jul 22 '16 at 11:32
  • so it is 32 bit. you have to decide whether it is enough for you to round the value to lower or nearest integer or whether you want to limit/scale/range the float space to 16 bit integer range. In addition if you have only positive (float) values you can switch to char16u_t to increase the possibe range/precision – Micka Jul 22 '16 at 11:35
  • I am using char16_t to save the image, but getting a dark image. I tried multiplying it by 255. But no luck – SDD123 Jul 22 '16 at 11:38
  • what's the type of the Mat? char16_t would be CV_16SC1 (not CV_16UC1). in addition, value -32768 is black and 32767 is white for signed while 0 is black and 65535 is white for unsigned. – Micka Jul 22 '16 at 11:52
  • I was using CV_16UC1 so far. Now it is working. But the image is too dark. :( – SDD123 Jul 22 '16 at 11:57
  • can you increase the scale factor? And did you change to `newdepthimage.at(u,v) = factor*Z` ? – Micka Jul 22 '16 at 12:02
  • yes. I have increased the scale factor as well. The thing i do not understand is, My depth value is in float. Why is it not working when i created a Mat float image and used to copy data. – SDD123 Jul 22 '16 at 12:04
  • because float is 32 bit but your matrix entries are 16 bit. If you create a float (32FC1) mat you can save them, but imwrite will convert them to 8 bit (and maybe scale them). Do you need the images just for visualization or do you need to reuse them (e.g.don't lose information)? Can you create a new question and post your code? – Micka Jul 22 '16 at 12:08
  • I dont want to lose the information. And yes. I will create a new post with the code. – SDD123 Jul 22 '16 at 12:10
  • so the image "being too dark" isn't really a problem if the values are ok?!? – Micka Jul 22 '16 at 12:11
  • I want to visualize the image as well. :) – SDD123 Jul 22 '16 at 12:12
  • maybe you should use differently scaled images for both purposes... – Micka Jul 22 '16 at 12:14
  • hmm. Ok. Thanks a lot for all the help. :) :) – SDD123 Jul 22 '16 at 12:19

1 Answers1

1

Here is the answer:

Dont worry about the type casting. Using integers in double. But this is just to give the gist of the solution.

std::vector< cv::Point2d> points;

for(int i =0; i < 10; i++)
{
    points.push_back(cv::Point2d(i,i));
}

cv::Mat_<cv::Point2d> matrix(points);

std::cout<<matrix.at<cv::Point2d>(1);

But if you want to save this Mat then use XML. Imwrite wont write the Mat.

Anubhav Rohatgi
  • 458
  • 1
  • 6
  • 16