我已经面临这个问题好几天了!
我必须实现一个具有此结构的接口来存储图像:
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);
编辑。 我需要做的是实现接口
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,然后在createTemplate中从中创建Mat对象。 我编写了前面的代码来检查是否可以转换。
问题是要有与图像结构相同的图片和与 Mat 的广告相同的图片,使它们成为一种转换。
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;
首先,定义哪个类拥有图像数据: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;
您应该为其分配和释放内存。