我有两个单色图像作为从相机中取出的byte []。我想组合这些图像并将组合图像写入可写位图。
使用openCV,我从字节数组创建Mat
个对象(类型为CV_8UC1
)(绿色为greenMat
,红色通道图像为redMat
)通过Cv2.Merge
Mat mergedMat = new Mat(greenMat.Height, greenMat.Width, MatType.CV_8UC3);
Mat emptyMat = Mat.Zeros(greenMat.Height, greenMat.Width, MatType.CV_8UC1);
Cv2.Merge(new[]
{
redMat, greenMat, emptyMat
}, mergedMat);
mergedMat.ToBytes()现在返回一个大小为2175338的缓冲区。为什么这么大?如果将2448x2048大小合并为一个三通道矩阵(CV_8UC3),则将三个单通道矩阵(CV_8UC1)合并为一个大小为15040512的缓冲区,或者我在这里遗漏了什么?
我想通过将合并后的图片写入现有的WriteableBitmap
来显示,该内容通过
ImageSource = new WriteableBitmap(
width, //of the green image
height, //of the green image
96, //dpiX: does not affect image as far as I tested
96, //dpiY
PixelFormats.Rgb24, //since the combined image is a three channel color image
null); //no bitmap palette needed for used PixelFormat
这个初始化是否正确?我对这里的PixelFormat
不确定。 dpiX
和dpiY
值似乎也没有效果。它们的用途是什么?
我现在无法正常工作的棘手部分是将图像数据写入WriteableBitmap
。
使用以下代码获取的字节数组
合并图像并使用WriteableBitmap
s' WritePixels方法,用
根据ImageSources' PixelFormat,产生一个
System.ArgumentException: 'Buffer size is not sufficient.'
var mergedBuffer = mergedMat.ToBytes();
var bytesPerPixel = (PixelFormats.Rgb24.BitsPerPixel + 7) / 8;
var stride = bytesPerPixel * width;
((WriteableBitmap)ImageSource).WritePixels(
new Int32Rect(0, 0, width, height),
mergedBuffer,
stride,
0)
编辑:步幅是根据this answer计算出来的,虽然这里不需要固定的PixelFormat
。
为什么缓冲区太小?我做了初始化WriteableBitmap
正确的宽度和高度PixelFormats.Rgb24
。我
正确计算我的步幅?
感谢@Micka在评论中提出的建议,我意识到mergedMat.ToBytes
方法似乎没有按照我的意思去做。相反,我尝试使用mergedMat.Data
指针,如下所示:
var mergedBufferSize = (int)(mergedMat.Total() * mergedMat.Channels());
byte[] mergedBuffer = new byte[mergedBufferSize];
System.Runtime.InteropServices.Marshal.Copy(
mergedMat.Data,
mergedBuffer,
0,
mergedBufferSize);
这一切都很好。