Ask Your Question
1

convert cv::Mat to vector<vector<uchar>> img;

asked 2020-01-08 02:21:34 -0600

dineshlama gravatar image

updated 2020-01-08 02:31:39 -0600

LBerger gravatar image

how do i efficiently convert cv::Mat to vector<vector<uchar>> img. right now i am trying beolove code:

vector<vector<Vec3b>> inputImg(OrigImg.cols,vector<Vec3b>(OrigImg.rows));
for(int i=0;i<OrigImg.cols;i++) {
  for(int j=0;j<OrigImg.rows;j++) {
    inputImg[i][j] = backgroundSubImg.at<cv::Vec3b>(j,i);
  }
}

Why i'm trying to do is since it looks like accessing each pixel in cv::Mat or scanning hole image is little bit slower by using backgroundSubImg.at<cv::vec3b>(j,i); i want to access the color values of this pixels only by its position. Right now my algorithm is accessing every pixel 6404608 times in each cycle.

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
2

answered 2020-01-08 09:46:27 -0600

exbigboss gravatar image

If your goal is speed, you shouldn't be making a copy. Nor should you be using non-contiguous allocations like a vector of vectors.

Instead, invert this problem. Create a storage vector up-front and then create cv::Mat on top of that.

You want a single flat contiguous allocation for cache coherency and you want to avoid the copy as well.

In essence, just do:

auto storage = std::vector<uchar>(480 * 640 * 3); // or however many channels you have
auto mat     = cv::Mat_<uchar>(480, 640, CV_8UC3, storage.data());
edit flag offensive delete link more
1

answered 2020-01-09 02:32:30 -0600

LBerger gravatar image

You can try :

    Mat a(6, 6, CV_8UC3, Scalar(1, 64, 192));
    vector<vector<uchar>> v(a.rows);
    for (int i = 0; i < a.rows; i++)
    {
        a.row(i).reshape(1,1).copyTo(v[i]);
    }
    for (int i = 0; i < a.rows; i++)
    {
        for (auto j : v[i])
            cout << int(j) << "\t";
        cout << "\n";
    }
edit flag offensive delete link more
0

answered 2020-01-08 16:04:58 -0600

sjhalayka gravatar image

Using a 2D vector like this is not as efficient as using a single vector<uchar> to hold all of the pixels, where the index is equal to size_t index = y*x_resolution+x; Here y and x are gotten from for loop iteration.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-01-08 02:21:34 -0600

Seen: 3,467 times

Last updated: Jan 09 '20