cv::resize will change the dst Mat::data buf address unexpectedly.

asked 2018-12-06 00:35:04 -0600

JillWang gravatar image

updated 2018-12-06 01:16:32 -0600

berak gravatar image

include <stdio.h>

#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
usng namespace std;
using namespace cv;


int main(int argc, char **argv)
{
    char* data = (char*)malloc(100*100); 
    Mat img = imread("./a.jpg");
    Mat newImg = cv::Mat(100, 100,  CV_8SC3, (void*)data); //transfer the data buf to Mat instance newImg
    printf("data addr:%#x newImage.data:%#x\n", data, newImg.data);  //newImg.data addr equeals to data addr

    cv::resize(img, newImg, newImg.size(), 0, 0, cv::INTER_LINEAR);
    printf("newImg.data ater resize:%#x\n", newImg.data);//newImage.data changed by cv::resize

    free(data);
    img.release(); 
    return 1;
}

Result running this code:

data addr:0xa49a8360 newImage.data:0xa49a8360
newImg.data ater resize:0xa49b1cc0

Perhaps opencl API clSetKernelArg will be called and then moved the data buf, and will cause an extra mem allocate and memcpy consumption.

And there will be a memory leak of this code detected by valgrind.

edit retag flag offensive close merge delete

Comments

opencv version / os / compiler used here ?

img has both a different type (CV_8UC3) and a probably also a different size, so the reallocation is quite reasonable.

also note, that newImg never allocated any memory on it's own before (it's using a "borrowed" pointer)

berak gravatar imageberak ( 2018-12-06 01:13:46 -0600 )edit

Thanks a lot.

opencv: 3.1.0 os: Debian GNU/Linux 9 compiler: g++ (Debin 6.3.0)

Consider the performance, I just want to pre-allocate the memory for newImg.data, and then use this buf for every single input image when resizing, this will avoid reallocation and memcpy, and then save quite a lot memory access time. Do I have the approach to do so right now?

JillWang gravatar imageJillWang ( 2018-12-06 01:58:51 -0600 )edit

this will avoid reallocation and memcpy, and then save quite a lot memory access time

i'm not so sure about this.

also, the assumption, that malloc/free are used from opencv might not hold.

IF at all, you should use: Mat newImg = cv::Mat(100, 100, CV_8UC3);

(let it allocate it's own mem, don't use manual management /malloc / free, and use the correct type in the 1st place)

berak gravatar imageberak ( 2018-12-06 02:09:41 -0600 )edit

Mat newImg = cv::Mat(100, 100, CV_8UC3); this will allocate mem for one single img, it will malloc/free 10 times for 10 image. I mean, actually, the input image stream can reuse the same mem, and we just need malloc/free once.

JillWang gravatar imageJillWang ( 2018-12-06 02:29:01 -0600 )edit