将 byte[] 转换为 Emgu/OpenCV 图片
Convert a byte[] into an Emgu/OpenCV Image
我有一个表示灰度图像的字节数组,我想使用 Emgu 包装器在 C# 中与 openCV 一起使用。我想弄清楚如何在不先将其转换为 System.Drawing.Bitmap
.
的情况下将其转换为 Emu.CV.Image
到目前为止,Image
的 this 构造函数看起来很有希望。看起来它需要像素行、列,然后是包含我的数据的数组来构建图像。但是,它希望它们采用一种奇怪的格式,我正在为如何正确构造 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,所以我试图在对象创建、内存分配等方面尽可能高效。
就我个人而言,我会按照这些思路做一些事情:
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];
出于性能方面的考虑,您可能希望:
- 把它变成一个不安全的块(应该是微不足道的)
- 只分配你的字节[]一次(除非你的图像大小改变)
Emu.Cv.Image class 定义为
public class Image<TColor, TDepth> : CvArray<TDepth>, ...
TColor
此图像的颜色类型(Gray、Bgr、Bgra、Hsv、Hls、Lab、Luv、Xyz、Ycc、Rgb 或 Rbga)
深度
此图像的深度(Byte、SByte、Single、double、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);
另一种解决方案是仅使用图像的宽度和高度来创建 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 对象并在每一帧更改字节。
我有一个表示灰度图像的字节数组,我想使用 Emgu 包装器在 C# 中与 openCV 一起使用。我想弄清楚如何在不先将其转换为 System.Drawing.Bitmap
.
Emu.CV.Image
到目前为止,Image
的 this 构造函数看起来很有希望。看起来它需要像素行、列,然后是包含我的数据的数组来构建图像。但是,它希望它们采用一种奇怪的格式,我正在为如何正确构造 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,所以我试图在对象创建、内存分配等方面尽可能高效。
就我个人而言,我会按照这些思路做一些事情:
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];
出于性能方面的考虑,您可能希望:
- 把它变成一个不安全的块(应该是微不足道的)
- 只分配你的字节[]一次(除非你的图像大小改变)
Emu.Cv.Image class 定义为
public class Image<TColor, TDepth> : CvArray<TDepth>, ...
TColor
此图像的颜色类型(Gray、Bgr、Bgra、Hsv、Hls、Lab、Luv、Xyz、Ycc、Rgb 或 Rbga)
深度
此图像的深度(Byte、SByte、Single、double、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);
另一种解决方案是仅使用图像的宽度和高度来创建 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 对象并在每一帧更改字节。