简体   繁体   English

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

[英]Segmentation Fault on uint8_t convertion (cpp)

I've been facing this problem for days! 我已经面对这个问题好几天了!

I have to implement an Interface with this structure for image storing: 我必须使用此结构实现用于存储图像的接口:

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

In my c++ function, I need the image in cv::Mat type. 在我的c ++函数中,我需要cv :: Mat类型的图像。 So I have to convert the uint8_t type in uchar type (since cv::Mat stores the data with uchar type) and viceversa. 所以我必须将uint8_t类型转换为uchar类型(因为cv :: Mat使用uchar类型存储数据),反之亦然。 I tried in so many ways, but everytime I try to access in any way the Mat image after the convertion, I get a segmentation fault. 我尝试了很多方法,但是每次转换后尝试以任何方式访问Mat图像时,都会遇到分割错误。

Look at my code: 看我的代码:

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. 编辑。 What I need to do is implement the 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) 
};

So, after reading the image via imread, I need to pass it to createTemplate in a vector of Image type, and then inside createTemplate create a Mat object from it. 因此,在通过imread读取图像之后,我需要将其传递到Image类型的向量中的createTemplate中,然后在createTemplate内从中创建一个Mat对象。 I wrote the previous code to check if the conversion was possible. 我编写了前面的代码来检查是否可以进行转换。

The issue is to have the same picture as Image struct and ad as Mat, making a sort of conversion beetween them. 问题是要与Image结构和ad具有与Mat相同的图片,从而在它们之间进行某种转换。

cv::Mat::data is a pointer. cv::Mat::data是一个指针。 It points to the first element of the data. 它指向数据的第一个元素。

By using *input.data you get what the pointer is pointing to, the first element of the data. 通过使用*input.data您可以获得指针所指向的内容,即数据的第一个元素。 It is equal to input.data[0] . 它等于input.data[0]

So after the assignment data = *input.data , the variable data contains only the value of the first data-element, it doesn't point to the actual data. 因此,在赋值data = *input.data ,变量data仅包含第一个数据元素的值,而不指向实际数据。 Therefore when you later do face.data = data you make face.data "point" somewhere completely wrong. 因此,当您以后做face.data = data ,会使face.data “指向”完全错误的地方。

If you want face.data to also point to the actual data, why not simply do 如果您希望face.data也指向实际数据,为什么不简单地做

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

Furthermore, &face.data is a pointer to a pointer . 此外, &face.data是指向指针的指针 You should use plain output.data = face.data; 您应该使用普通的output.data = face.data;

First, define, what class owns image data: cv::Mat , your struct Image or both. 首先,定义什么类拥有图像数据: cv::Mat ,您的struct Image或两者。

In the last case you need to allocate memory in Image , then explicitly copy data from cv::Mat to Image , and deallocate it on object destruction. 在最后一种情况下,您需要在Image分配内存,然后将数据从cv::Mat显式复制到Image ,并在销毁对象时将其取消分配。

If image data are owned by cv::Mat , then take into account that this class allocates memory for them and releases after all references to it are destructed. 如果图像数据由cv::Mat拥有, cv::Mat考虑此类为它们分配了内存,并在销毁对它的所有引用之后将其释放。 Otherwise, you can have dangling pointers to data that doesn't exist. 否则,您可能会悬空指向不存在的数据的指针。

Learn about reference counting . 了解有关参考计数的信息 OpenCV's matrices don't copy data all the time, they count references. OpenCV的矩阵不会一直复制数据,它们会计算引用数。

cv::Mat can also handle non-contiguous regions . cv::Mat也可以处理 非连续区域

If your struct Image owns the data, then everything is up to you. 如果您的struct Image拥有数据,那么一切取决于您。

I would suggest to put cv::Mat in your struct Image 我建议将cv::Mat放在您的struct Image

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

And yes, uint8_t data; 是的, uint8_t data; from your struct Image must be a pointer: uint8_t* data; 来自struct Image必须是一个指针: uint8_t* data;

You should allocate and release memory for it. 您应该为其分配和释放内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM