Ask Your Question
0

What's the most efficient way to transfer from array to cv::Mat? [closed]

asked 2016-02-02 11:15:37 -0600

aripod gravatar image

updated 2016-02-02 11:18:59 -0600

Hello,

I have images being streamed and I get them in my code in an array uint8_t *_buffer. It's a 1280x1024 long array and I'm doing this ugly and ultra slow

    cv::Mat MasterFrame(MasterCamera->data(self)->height,MasterCamera->data(self)->width,CV_8UC3);
    for (int x=0;x<MasterCamera->data(self)->width;x++)
    {
        for (int y=0;y<MasterCamera->data(self)->height;y++)
        {
            MasterFrame.at<cv::Vec3b>(y,x)=cv::Vec3b(MasterCamera->data(self)->data._buffer[y*(MasterCamera->data(self)->width*cameratype)+x*cameratype+2],
                                               MasterCamera->data(self)->data._buffer[y*(MasterCamera->data(self)->width*cameratype)+x*cameratype+1],
                                               MasterCamera->data(self)->data._buffer[y*(MasterCamera->data(self)->width*cameratype)+x*cameratype+0]);      
        }
    }

Where I have previously read height and width (1280 and 1024 respectably), and cameratype=3 as it is an RGB camera.

How could I use cv::Mat more efficiently? Can I use memmove for example? I would need the most efficient and fastest way to transfer/copy from the array to the cv::Mat.

Thanks for the help.

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by aripod
close date 2016-02-03 03:14:15.655697

2 answers

Sort by ยป oldest newest most voted
2

answered 2016-02-02 12:31:17 -0600

matman gravatar image

The most efficient way is to pass the _buffer pointer to a cv::Mat (link). But beware that you now work with the _buffer data.

The other way is to create a cv::Mat and copy the data to it using memcpy or something. Or you create temporarily a cv::Mat from the _buffer pointer and do a deep copy with cv::Mat::clone() to another one.

The link shows you a lot of possibilities how to construct a cv::Mat.

edit flag offensive delete link more

Comments

I tried MasterFrame = Mat(MasterCamera->data(self)->height,MasterCamera->data(self)->width,CV_8UC3, MasterCamera->data(self)->data._buffer); as it does not copy date from one place to another, but I didn't improve the FPS as I thought it would..... I have implemented it right, haven't I?

aripod gravatar imagearipod ( 2016-02-03 02:06:08 -0600 )edit

I measured it and it's quite fast. I have a slow function elsewhere..... Thanks for the answer.

aripod gravatar imagearipod ( 2016-02-03 03:14:04 -0600 )edit
2

answered 2016-02-02 12:29:22 -0600

Guyygarty gravatar image

updated 2016-02-02 12:31:59 -0600

I would recommend:

MasterFrame=Mat(Height,Width,CV_8UC3,[pointer to data buffer],[you MAY need to specify stride implicitly]).clone();

It is much faster than cycling through the elements.

If you can arrange for the data to not be overwritten (or go out of scope) until you are done with it, for example by saving consecutive images to different buffers, you can omit the .clone() and then it would be even faster as the data is never actually copied.

pay attention that the order of channels may not be what you expect if the camera returns RGB, as OpenCV expects BGR by default.

guy

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-02-02 11:15:37 -0600

Seen: 6,578 times

Last updated: Feb 02 '16