Fill Mat from 2D vector
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.
originally frame is uchar :
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))
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
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 asframe.at<Vec3b>y,x)
, but then again, your idwt cannot hold 3 channelsBoth 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?
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)
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>>
it sounds more, like you simply should transform
frame
to 1 single channel, grayscale image, before copying to idwtthen, again, there's a scaling issue (which range do you need to be your vector in ? [0..1] ? currently you have [0..255]
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.