uint8_t转换(cpp)上的分段错误

时间:2018-06-05 11:27:16

标签: c++ opencv segmentation-fault uint8t

我已经面对这个问题好几天了!

我必须使用这种结构实现一个用于图像存储的接口:

typedef struct Image
{
    uint16_t image_width;
    uint16_t image_height;
    uint16_t image_depth;
    uint8_t data;
    Label description;
} Image;

在我的c ++函数中,我需要cv :: Mat类型的图像。所以我必须在uchar类型中转换uint8_t类型(因为cv :: Mat使用uchar类型存储数据),反之亦然。我尝试了很多方法,但每当我尝试以任何方式访问转换后的Mat图像时,我都会遇到分段错误。

看看我的代码:

Image face;
Mat input;
Mat output;

input = imread( argv[i], 1 );
/*data = static_cast<uint8_t>(reinterpret_cast<uchar>(*input.data)); 
this is an alternative way found online, 
but it gives the same result. 
So I replaced it with the following line*/
uint8_t data = *input.data;
image_width = input.cols;
image_height = input.rows;
image_depth = input.channels();

face.data = data;
face.image_depth = image_depth;
face.image_height = image_height;
face.image_width = image_width;


output = Mat(face.image_height, face.image_width, CV_8UC3);
output.data = &face.data;

//both the following gives segmentation fault
imshow("Face", output);
cout << output << endl; //it starts printing the matrix, but it stops after a while with the seg fault

//but the following, the Mat before the convertion, does not
imshow("Face", input);

EDIT。 我需要做的是实现Inteface

using Multiface = std::vector<Image>;

class Interface {
public:
    Interface();
    virtual ReturnStatus createTemplate(
    const Multiface &faces,
    TemplateRole role,
    std::vector<uint8_t> &templ,
    std::vector<EyePair> &eyeCoordinates,
    std::vector<double> &quality) 
};

因此,在通过imread读取图像后,我需要将它传递给Image类型的向量中的createTemplate,然后在createTemplate中创建一个Mat对象。 我编写了前面的代码来检查转换是否可行。

问题是与Image结构相同的图片和广告作为Mat,在它们之间进行一种转换。

2 个答案:

答案 0 :(得分:1)

cv::Mat::data是一个指针。它指向数据的第一个元素。

通过使用*input.data,您可以获得指针指向的内容,即数据的第一个元素。它等于input.data[0]

因此,在赋值data = *input.data之后,变量data仅包含第一个数据元素的值,而不是指向实际数据。因此,当您稍后执行face.data = data时,您会face.data“指出某个地方完全错误。

如果您希望face.data也指向实际数据,为什么不简单地执行

face.data = input.data;
face.image_depth = input.channels();
face.image_height = input.rows;
face.image_width = input.cols;

此外,&face.data是指向的指针。你应该使用普通的output.data = face.data;

答案 1 :(得分:0)

首先,定义哪个类拥有图像数据:cv::Mat,您的struct Image或两者。

在最后一种情况下,您需要在Image中分配内存,然后将数据从cv::Mat显式复制到Image,并在对象销毁时解除分配。

如果图像数据归cv::Mat所有,那么请考虑此类为它们分配内存并在所有对它的引用被破坏后释放。否则,您可以悬挂指向不存在的数据的指针。

了解reference counting。 OpenCV的矩阵不会一直复制数据,它们会计算引用。

cv::Mat也可以handle non-contiguous regions

如果您的struct Image拥有数据,那么一切都取决于您。

我建议将cv::Mat放入struct Image

struct Image {
     cv::Mat image;
     // other members
}

是的,uint8_t data;中的struct Image必须是指针:uint8_t* data;

你应该为它分配和释放内存。