Efficiently accessing matrices

I’ve talked previous about matrices in 2D matrices with CvMat in OpenCV. I talked about accessing using the cvGet* and cvSet* functions. But in computer vision, you need to do things as efficiently as possible. And those functions increase the overhead. So here’s a super fast method of accessing data, using pointers. Don’t worry, it’s going to be easy!

Pointer math

The only thing you need to know is that the matrix elements are stored sequentially. And usually, you’d have two loops: the outer loop for the row, and a loop inside it for the column. And for each row and column, you can access the channel data.

Some code will clear up the idea:

for(int row=0;row<mat->rows;row++)
{
    const float* ptr = (const float*)(mat->data.ptr + row*mat->step);
    for(int col=0;col<mat->cols;col++)
    {
        float c1 = *ptr++;
        float c2 = *ptr++;
        float c3 = *ptr++;
        float c4 = *ptr++;
    }
}

You can see the outer row loop. Inside it is the column loop, col. And inside both, you access the channel data for a particular pixel (I assumed a 4 channel matrix, CV_32FC4).

Simple eh? And its efficient too!

One word of caution though. Note that I calculate ptr for every row. That’s because you can setup a “region of interest” in images. And this matrix might be a part of that. So you can’t say that rows are continuous in memory. However, individual elements of a particular row will always be continuous in memory.

Oh! You might want to check Memory layout of matrices of multi-dimensional objects. I’ve gone into detail about how matrices are stored in memory. And for one particular case, it’s drastically different. Make sure you check that article as well.

Done!

With that, I think you should be able to access your matrices much more efficiently! Got questions? Suggestions or criticism? Let me know! Leave a comment!

Issues? Suggestions? Visit the Github issue tracker for AI Shack

Back to top

One Comment

  1. donny
    Posted August 25, 2011 at 9:48 am | Permalink

    can help me with this?
    IplImage* image = cvLoadImage(“plat1.png”);
    IplImage* temp1 = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);
    cvCvtColor(image, temp1, CV_BGR2GRAY);
    int size = (image->height)*(image->width);
    int data_temp1[size];

    there are an error
    1. expected constant expression
    2. cannot allocate an array of constant size 0
    3. ‘data_temp1′ : unknown size

    why?

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>