将byte []转换为Emgu / OpenCV图像

时间:2015-03-19 20:06:31

标签: c# opencv kinect emgucv

我有一个表示灰度图像的字节数组,我想在C#中使用openCV,使用Emgu包装器。我试图找出如何将其转换为Emu.CV.Image而不先将其转换为System.Drawing.Bitmap

到目前为止,Image的{​​{3}}构造函数似乎很有希望。它看起来像像素行,列,然后数据与我的数据构建一个图像。但是,它希望它们处于一种奇怪的格式,我正在努力解决如何正确构造TDepth[,,] data参数。

这是我到目前为止所拥有的:

// This gets initialized in the constructor and filled in with greyscale image data elsewhere in the code:
byte[] depthPixelData

// Once my depthPixelData is processed, I'm trying to convert it to an Image and this is where I'm having issues
Image<Gray, Byte> depthImage = new Image<Gray, Byte>([depthBitmap.PixelHeight, depthBitmap.pixelWidth, depthPixelData]);

Visual Studio让我明白,只是传入一个数组不会削减它,但我不知道如何使用我的像素数据构建必需的TDepth[,,]对象以传递给Image构造函数。

此代码需要以~30fps运行,所以我试图通过对象创建,内存分配等尽可能高效。

3 个答案:

答案 0 :(得分:3)

另一种解决方案是仅使用图像的宽度和高度来创建EMGU.CV.Image。然后你可以做这样的事情:

byte[] depthPixelData = new byte[640*480]; // your data

Image<Gray, byte> depthImage = new Image<Gray, byte>(640, 480);

depthImage.Bytes = depthPixelData;

只要宽度和高度正确且宽度可被4整除(如何实现Emgu.CV.Image),就不会有问题。您甚至可以重用Emgu.CV.Image对象,如果不需要保存对象,只需更改每帧的字节数。

答案 1 :(得分:1)

我个人会按照这些方式做点什么:

byte[] depthPixelData = ...;

int imageWidth = ...;
int imageHeight = ...;
int channelCount = 1; // grayscale

byte[,,] depthPixelData3d = new byte[imageHeight, imageWidth, channelCount];

for(int line = 0, offset = 0; line < imageHeight; line++)
    for(int column = 0; column < imageWidth; column++, offset++)
        depthPixelData3d[line, column, 0] = depthPixelData[offset];

出于性能考虑,您可能希望:

  • 把它变成一个不安全的块(应该是微不足道的)
  • 仅分配您的字节[,,]一次(除非您的图像尺寸发生变化)

答案 2 :(得分:1)

Emu.Cv.Image类定义为

public class Image<TColor, TDepth> : CvArray<TDepth>, ...

TColor
此图像的颜色类型(灰色,Bgr,Bgra,Hsv,Hls,Lab,Luv,Xyz,Ycc,Rgb或Rbga) TDepth
此图像的深度(字节,SByte,单,双,UInt16,Int16或Int32)

此通用参数TDepth具有误导性。在您的情况下,TDepth[,,]表示byte[,,]

要将一个数组复制到另一个数组,可以使用Buffer.BlockCopy:

byte[, ,] imageData = new byte[depthBitmap.PixelHeight , depthBitmap.PixelWidth , colorChannels];
Buffer.BlockCopy(depthPixelData, 0, imageData, 0, imageData.Length);
Image<Gray, Byte> depthImage = new Image<Gray, Byte>(imageData);