理解为什么它不能使用 memcpy 正确复制
Understanding why it doesn't copy correctly using memcpy
我对 C++ 中的 OpenCV 4.1.0 和 memcpy 有一些误解。问题是为什么图像放大了很多?
我读了这样一张图片:
Mat img = imread("lena512.bmp", 1); // Black and White Image
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", img);
在此之后我有 2 个字节的数组:
int inputSize = width * height * channels;
byte* pixels = new byte[width * height * channels];
byte* out = new byte[width * height * channels];
我将 img 复制到像素数组:
memcpy(pixels, img.data, inputSize * sizeof(byte));
然后我想检查检索图像是否与输入相同:
Mat image = Mat(width, height , CV_8U);
memcpy(image.data, out, inputSize * sizeof(byte));
Mat img = imread("lena512.bmp", 1); // Black and White Image
这就是问题所在,评论是谎言,通过使用幻数而不是命名常量,您无法轻易分辨出情况是这样的。 1
在此上下文中表示 IMREAD_COLOR
——即图像始终被读取为 3 通道 BGR 图像。
但是,在使用 memcpy
和原始指针进行恶作剧之后,您可以按以下方式创建新的 Mat
:
Mat image = Mat(width, height , CV_8U);
请注意 CV_8U
等同于 CV_8UC1
。因此,您创建一个单通道(灰度)Mat
,但给它 3 通道数据。
因此产生垃圾是次要的问题。更严重的问题是,您复制的数据是目标像素缓冲区可以容纳的数据的 3 倍——基本上,您破坏了不属于 Mat
的半兆字节内存。这可能以段错误结束,或者一些很难找到的错误(以防您覆盖其他数据结构使用的一些内存)。
更新: 我还漏掉了另一个问题(感谢@Micka 发现了这个问题)。 cv::Mat
constructor 的参数顺序是行、列、数据类型。看起来你切换了宽度和高度,尽管因为你的输入图像看起来是正方形的(即 width == height
),所以这并不重要。
分配第二个 Mat
的正确方法是
Mat image = Mat(height, width, CV_8UC3);
我对 C++ 中的 OpenCV 4.1.0 和 memcpy 有一些误解。问题是为什么图像放大了很多? 我读了这样一张图片:
Mat img = imread("lena512.bmp", 1); // Black and White Image
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", img);
在此之后我有 2 个字节的数组:
int inputSize = width * height * channels;
byte* pixels = new byte[width * height * channels];
byte* out = new byte[width * height * channels];
我将 img 复制到像素数组:
memcpy(pixels, img.data, inputSize * sizeof(byte));
然后我想检查检索图像是否与输入相同:
Mat image = Mat(width, height , CV_8U);
memcpy(image.data, out, inputSize * sizeof(byte));
Mat img = imread("lena512.bmp", 1); // Black and White Image
这就是问题所在,评论是谎言,通过使用幻数而不是命名常量,您无法轻易分辨出情况是这样的。 1
在此上下文中表示 IMREAD_COLOR
——即图像始终被读取为 3 通道 BGR 图像。
但是,在使用 memcpy
和原始指针进行恶作剧之后,您可以按以下方式创建新的 Mat
:
Mat image = Mat(width, height , CV_8U);
请注意 CV_8U
等同于 CV_8UC1
。因此,您创建一个单通道(灰度)Mat
,但给它 3 通道数据。
因此产生垃圾是次要的问题。更严重的问题是,您复制的数据是目标像素缓冲区可以容纳的数据的 3 倍——基本上,您破坏了不属于 Mat
的半兆字节内存。这可能以段错误结束,或者一些很难找到的错误(以防您覆盖其他数据结构使用的一些内存)。
更新: 我还漏掉了另一个问题(感谢@Micka 发现了这个问题)。 cv::Mat
constructor 的参数顺序是行、列、数据类型。看起来你切换了宽度和高度,尽管因为你的输入图像看起来是正方形的(即 width == height
),所以这并不重要。
分配第二个 Mat
的正确方法是
Mat image = Mat(height, width, CV_8UC3);