Fill Mat from 2D vector

asked 2017-04-26 10:14:37 -0600

I have some code that pulls the pixel values from a mat (image from videocapture):

for (int k = 0; k < rows; k++) {
    for (int l = 0; l < cols; l++) {

        data[k][l] =  (double)frame.at<uchar>(k, l);

        }             
    }

After some transformations the data is written to file. I am trying to reconstruct the original image using these lines:

  cv::Mat frame(idwt.size(), idwt[0].size(), CV_8UC3);//CV_8UC3 8bit unsigned int 3 channels

for (int k = 0; k < idwt.size(); k++) {
    for (int l = 0; l < idwt[k].size(); l++) {

          frame.at<uchar>(k, l) = (unsigned char)std::round(idwt[k][l]); 
        //See ibb.co/j4AzO5
    }
}

Where the data is in idwt, declared as :

 std::vector<std::vector<double>> idwt(row, std::vector<double>(col));

I've inspected the original mat data, the transformed data and the reconstructed data and there is no error but I get a partial reconstructed image. (I have some links to related questions but not enough karma now to post). I cannot fathom why this fails in this way, I've read the docs and nothing seems like a solution to this.

edit retag flag offensive close merge delete

Comments

originally frame is uchar :

data[k][l] =  (double)frame.at<uchar>(k, l);

it should be then cv::Mat frame(idwt.size(), idwt[0].size(), CV_8UC1) (instead of cv::Mat frame(idwt.size(), idwt[0].size(), CV_8UC3))

LBerger gravatar imageLBerger ( 2017-04-26 10:22:30 -0600 )edit

But this is a 24 bit 3 channel image, if I substitute your change I get a grayscale image that stretches out the partially reconstructed area. ibb. co/jYZPak

yungtrizzle gravatar imageyungtrizzle ( 2017-04-26 10:34:12 -0600 )edit

i think, you have a uchar <--> Vec3b mismatch here

frame has 3 channels, your idwt vector onlya single one. also, you must not access frame as frame.at<uchar>(y,x)but as frame.at<Vec3b>y,x) , but then again, your idwt cannot hold 3 channels

berak gravatar imageberak ( 2017-04-26 10:56:41 -0600 )edit

Both data and idwt are 2d vectors, so you're saying my vectors needs to be bigger than 2d to hold 3 channels of data? How you would declare such a vector?

yungtrizzle gravatar imageyungtrizzle ( 2017-04-26 11:11:29 -0600 )edit
1

we probably need to know the reason of having that vector in the 1st place ?

but the main problem is clear, no ? frame has 3 numbers per pixel, iwdt only a single one.

(yes, that would be 3d, if you want so)

berak gravatar imageberak ( 2017-04-26 11:14:40 -0600 )edit

I'm doing a wavelet transform on the data which requires at most a 2d vector to compute the coefficients, I cannot pass a vector<vec3b> which would be the most convenient situation, I would still somehow need to create a vector<vector<double>>

yungtrizzle gravatar imageyungtrizzle ( 2017-04-26 11:20:22 -0600 )edit

it sounds more, like you simply should transform frame to 1 single channel, grayscale image, before copying to idwt

then, again, there's a scaling issue (which range do you need to be your vector in ? [0..1] ? currently you have [0..255]

berak gravatar imageberak ( 2017-04-26 11:25:40 -0600 )edit

Transforming to single channel will lose color data which is not acceptable in this scenario. In terms of range, there is no limitation, although I would like to think that [0,1] would be better since floating point data is expected.

yungtrizzle gravatar imageyungtrizzle ( 2017-04-26 11:45:22 -0600 )edit