我对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));
答案 0 :(得分:2)
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
的0.5 MB内存。要么以段错误结束,要么确实很难发现错误(以防您覆盖其他数据结构使用的某些内存)。
更新:我还错过了另一个问题(感谢@Micka抓住了这个问题)。 cv::Mat
constructor的参数顺序为行,列,数据类型。似乎您切换了宽度和高度,尽管由于您输入的图像看起来是正方形(即width == height
),所以没关系。
分配第二个Mat
的正确方法是
Mat image = Mat(height, width, CV_8UC3);