Ask Your Question
0

Create a vector of Mat from a three dimensional vector

asked 2018-07-02 09:09:27 -0600

robro gravatar image

updated 2018-07-02 09:49:25 -0600

berak gravatar image

Hello,

I have a vector of the type

std::vector< std::vector< std::vector  <uint16_t> > >

and data is stored in the following order: vector[col][channel][row].

I would like to create a vector of the type std::vector<cv::Mat> in which a grayscale image of each channel is stored. Also, the Mat vector should point to the original data.

The original vector changes dynamically as new columns are appended and so the Mat vector should grow as well.

What is the best way to create, fill and extend the Mat vector?

Thank you very much!

edit retag flag offensive close merge delete

Comments

"the Mat vector should point to the original data." -- this will not be possible.

vector[col][channel][row] -- this really looks weird. what kind of data would be stored in this way ?

berak gravatar imageberak ( 2018-07-02 09:47:56 -0600 )edit
1

This is a hyperspectral cube coming from BIL format (http://desktop.arcgis.com/en/arcmap/1...) and a line scan. So a buffer always delivers new lines. I could store it in any other way as well. It should just be possible to easily access every data point, so all three dimensions. The current way of storage is in the way the data is created. Any other good suggestions? Thanks

robro gravatar imagerobro ( 2018-07-02 10:09:50 -0600 )edit

so, it is the 1st of the 3 described formats there ?

berak gravatar imageberak ( 2018-07-02 10:17:40 -0600 )edit

Yes and I always get a buffer with one image line.

robro gravatar imagerobro ( 2018-07-02 10:30:40 -0600 )edit

ok, however, can it be, you're confusing rows and cols ?

For example, given a three-band image, all three bands of data are written for row 1, all three bands of data are written for row 2, and so on, until the total number of rows in the image is reached.

this would mean, rows are appended, not columns. it also would mean, your format is:

 vector[row][channel][col]

right ? (you append to the last / inner index)

berak gravatar imageberak ( 2018-07-02 11:04:36 -0600 )edit
1

Sorry, I was not clear enough. The original format is uchar* buffer for eyery image line. From this buffer I need to cast two uchar to a 16 bit variable using shift operators. The vector was introduced by me for easier data access. Whether rows or cols are appended is at matter of the definition of the image direction.

robro gravatar imagerobro ( 2018-07-02 11:12:23 -0600 )edit

yea, just a matter of indexing, then.

berak gravatar imageberak ( 2018-07-02 11:27:58 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-07-02 11:27:15 -0600

berak gravatar image

updated 2018-07-02 12:16:51 -0600

well assuming vector[row][channel][col] it would be like:

std::vector< std::vector< std::vector  <uint16_t> > > BIL;

vector<Mat> chans(3); // 3 mat's with seperate channels, initially empty (!)
for (int r=0; r<nrows; r++) {
    for (int c=0; c<nchannels; c++) {
        // vectors can be converted, but they're originally vertical.
        Mat row = Mat(BIL[r][c]).reshape(1,1); 
        chans[c].push_back(row); // append a per-channel line
    }
}

note, that this needs to copy all of of your data. opencv's Mat's need consecutive memory, not row-pointers.

edit:

here's a somewhat less intuitive, but slightly more effective version, avoiding the reallocations:

vector<Mat> chans(3); 
for (int c=0; c<nchannels; c++) { // loops reordered !
    int ncols = BIL[0][0].size();
    chans[c].create(nrows, ncols, CV_16U); // allocate mem for a whole channel.
    for (int r=0; r<nrows; r++) {
        // vectors can be converted, but they're originally vertical.
        Mat row = Mat(BIL[r][c]).reshape(1,1); // now horizontal
        row.copyTo(chans[c].row(r)); 
    }
}
edit flag offensive delete link more

Comments

Thanks! One last question... How can Mat's memory be consecutive if the end dimensions (rows, cols) are not known at the beginning and data (rows or cols) is appened all the time?

robro gravatar imagerobro ( 2018-07-02 11:44:22 -0600 )edit
1

tbh, this is reallocating all of it per push_back() call. (similar to what a vector deos)

berak gravatar imageberak ( 2018-07-02 11:48:14 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-07-02 09:09:27 -0600

Seen: 624 times

Last updated: Jul 02 '18