Ask Your Question
0

How to flatten 2D matrix and then copy it to a specific column in another matrix

asked 2018-11-24 09:26:00 -0600

longlp gravatar image

updated 2018-11-24 09:35:33 -0600

berak gravatar image

For example, I have a 2D Matrix with 3-channels:

const auto img = imread("path.jpg", IMREAD_COLOR);
const auto ROWS = img.rows;
const auto COLS = img.cols;

And then i split it to vector to get 2D Matrix with 1-channel:

std::vector<Mat> channels{};
split(img, channels);

I want to store the channels as a Matrix of size [ROWS*COLS, 3] so i tried to do this. I thought it is supposed to flatten each Matrix in the channels above to Matrix of size [ROWS*COLS, 1], then copy it to the a specific column of in the result, but it was wrong:

Mat result(ROWS*COLS, 3, CV_32F);
auto i = 0;
for(const auto& channel : channels) {
    channel.reshape(0, ROWS*COLS).copyTo(result.col(i));
    ++i;
}

I used a naive way which give the correct result:

for (const auto& channel : channels) {
     for (auto y = 0; y < rows; ++y)
        for (auto x = 0; x < cols; ++x) {
            result.at<float>(y + x * rows, i) = channel.at<uchar>(y, x);
        }
    ++i;
}

What did i do wrong with the first solution?

edit retag flag offensive close merge delete

Comments

what are you trying to achieve, here ? goal ? context ? why do you need to reshape it ?

berak gravatar imageberak ( 2018-11-24 09:37:19 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-11-24 09:44:18 -0600

berak gravatar image

please NEVER abuse Mat::at for anything on the whole image.

if you wanted a 3 channel, single column Mat it would be a simple:

Mat res = img.reshape(3, img.total());

for 1 channel, and 3 colums it would be:

Mat res = img.reshape(1, img.total());

(imho, you're entirely overcomplicating this...)

edit flag offensive delete link more

Question Tools

Stats

Asked: 2018-11-24 09:26:00 -0600

Seen: 2,005 times

Last updated: Nov 24 '18