在C ++中使用Heap存储cv :: Mat实例

时间:2017-04-18 14:37:22

标签: c++ opencv pointers

这不仅是与OpenCV相关的问题,也是一般的C ++问题。

我想在方法中加载一个图像,并使用指针将它存储在堆上。

以下是我目前正在使用的方法的代码:

int load_offline_image(std::string src, unsigned char* buffer, int* width, int* height, int* len) {
    if (offline_image) {
        delete offline_image;
    }
    offline_image = new cv::Mat(cv::imread(src, cv::IMREAD_GRAYSCALE));
    if (offline_image->data == 0){
        return ERROR;
    }
    int numRow = offline_image->rows;
    int numCol = offline_image->cols;
    *len = numCol*numRow*offline_image->elemSize1();
    *width = offline_image->size().width;
    *height = offline_image->size().height;
    buffer = offline_image->data;
    return OK;
}

方法中的一切都很好。但是当我尝试从外部访问buffer变量时,它是Null。我确定这个问题与指针offline_image指向一个cv::Mat实例的事实有关,该实例只存在于堆栈上,并且在执行load_offline_image之后它的地址丢失了完了。

BTW:offline_image是一个全局变量。

在C ++中实现此功能的正确方法是什么,以便为cv::Mat实例分配堆空间?

1 个答案:

答案 0 :(得分:1)

你可能想要的是这样的:

if(j == jmax-1){
    i++;
    j = 0;
    break; //exit the inner loop
}else{
    j++;
}

这样做的原因是 - 您想要更改int load_offline_image(std::string src, unsigned char** buffer, int* width, int* height, int* len) { ... *buffer = offline_image->data; .... } 指向的地址。使用buffer更改地址,但更改仅限于调用方法。您需要unsigned char* buffer才能将更改保留在方法之外。

另外,我建议您考虑步幅宽度 - 可能与图像宽度不同。您可以查询unsigned char**来解决这个问题。

另一方面,这不是使用offline_image.isContinuous()的合适方式。此外,还不清楚是谁责任清除cv::Mat指向的内存。这是一种更清洁的方法:

buffer

这解耦了这两个函数,让它们分别管理它们的内存。