Ошибка сегментации при преобразовании uint8_t (cpp) - PullRequest
0 голосов
/ 05 июня 2018

Я уже несколько дней сталкиваюсь с этой проблемой!

Мне необходимо реализовать интерфейс с этой структурой для хранения изображений:

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

В моей функции c ++ мне нужно изображениев типе cv :: Mat.Поэтому я должен преобразовать тип uint8_t в тип uchar (поскольку 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);

РЕДАКТИРОВАТЬ,Что мне нужно сделать, это реализовать 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, мне нужно передать его в createTemplate в векторе типа Image, а затем внутри createTemplate создать объект Mat изЭто.Я написал предыдущий код, чтобы проверить, возможно ли преобразование.

Проблема заключается в том, чтобы иметь ту же картинку, что и структура изображений, и рекламу, как Mat, что делает своего рода преобразование между ними.

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Сначала определите, какому классу принадлежат данные изображения: cv::Mat, ваш struct Image или оба.

В последнем случае вам необходимо выделить память в Image, затем явно скопировать данные из cv::Mat в Image и освободить их при уничтожении объекта.

Если данные изображенияпринадлежащий cv::Mat, затем примите во внимание, что этот класс выделяет им память и освобождает после того, как все ссылки на него уничтожены.В противном случае вы можете иметь висячие указатели на несуществующие данные.

Узнайте о подсчете ссылок .Матрицы OpenCV не копируют данные постоянно, они подсчитывают ссылки.

cv::Mat также может обрабатывать несмежные области .

Если ваши struct Image владеют данными, то все зависит от вас.

Я бы предложил добавить cv::Mat в ваш struct Image

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

И да, uint8_t data;от вашего struct Image должен быть указатель: uint8_t* data;

Вы должны выделить и освободить память для него.

0 голосов
/ 05 июня 2018

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;

...