Emgu.CV 如何从字节数组读取和保存图像?
Emgu.CV How to read and save image from and to byte array?
我正在学习Emgu.CV,我已经成功运行这个例子,我更喜欢从字节数组中读取图像而不是直接从文件中读取图像,而且我更喜欢将结果保存到字节数组而不是直接保存到文件..
任何人都可以提供帮助?
非常感谢
var _img = CvInvoke.Imread(_jpg); // HOW TO READ FROM BYTE ARRAY
var _fd = new Emgu.CV.CascadeClassifier(_face_classifier);
var _img_gray = new UMat();
CvInvoke.CvtColor(_img, _img_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
foreach (Rectangle _face in _fd.DetectMultiScale(_img_gray, 1.1, 10, new System.Drawing.Size(20,20)))
{
CvInvoke.Rectangle(_img, _face, new Emgu.CV.Structure.MCvScalar(255, 255, 255));
}
_img.Save("result.jpg"); // SAVE TO BYTE ARRAY
我了解到您的问题实际上有两个方面:将图像转换为 byte[]
,并将 byte[]
保存到文件。我将首先解决更简单的问题和后者:
正在将 byte[]
保存到文件
using(FileStream fs = new FileStream("OutputFile.dat",FileMode.OpenOrCreate))
{
BinaryWriter bs = new BinaryWriter(fs);
bs.Write(byteBuffer);
}
正在从文件中加载 byte[]
byte[] byteBuffer;
using (FileStream fs = new FileStream("InputFile.dat", FileMode.OpenOrCreate))
{
BinaryReader br = new BinaryReader(fs);
// Where 0xF0000 is calculated as Image Width x Height x Bit Depth
byteBuffer = br.ReadBytes(0xF0000);
}
现在开始第二部分;我假设您熟悉像素格式以及 byte[,,]
(或任何其他深度)的真实图像结构如何序列化为单一维度 byte[]
。如果没有请问。
从 byte[]
创建一个 Image
在下面的示例中,byte[]
是创建的而不是像上面那样加载的,byte[]
的来源是无关紧要的,只要它是已知图像维度和深度的正确序列化即可.
int width = 640; // Image Width
int height = 512; // Image Height
int stride = 640 * 3; // Image Stide - Bytes per Row (3 bytes per pixel)
// Create data for an Image 512x640 RGB - 983,040 Bytes
byte[] sourceImgData = new byte[0xF0000];
// Pin the imgData in memory and create an IntPtr to it's location
GCHandle pinnedArray = GCHandle.Alloc(sourceImgData, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// Create an image from the imgData
Image<Rgb, byte> img = new Image<Rgb, byte>(width, height, stride, pointer);
// Free the memory
pinnedArray.Free();
将 Image
转换为 byte[]
// Convert the source Image to Bitmap
Bitmap bitmap = sourceImage.ToBitmap();
// Create a BitmapData object from the resulting Bitmap, locking the backing data in memory
BitmapData bitmapData = bitmap.LockBits(
new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
// Create an output byte array
byte[] destImgData = new byte[bitmapData.Stride * bitmap.Height];
// Copy the byte array to the destination imgData
Marshal.Copy(bitmapData.Scan0,
destImgData,
0,
destImgData.Length);
// Free the memory
bitmap.UnlockBits(bitmapData);
我正在学习Emgu.CV,我已经成功运行这个例子,我更喜欢从字节数组中读取图像而不是直接从文件中读取图像,而且我更喜欢将结果保存到字节数组而不是直接保存到文件..
任何人都可以提供帮助?
非常感谢
var _img = CvInvoke.Imread(_jpg); // HOW TO READ FROM BYTE ARRAY
var _fd = new Emgu.CV.CascadeClassifier(_face_classifier);
var _img_gray = new UMat();
CvInvoke.CvtColor(_img, _img_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
foreach (Rectangle _face in _fd.DetectMultiScale(_img_gray, 1.1, 10, new System.Drawing.Size(20,20)))
{
CvInvoke.Rectangle(_img, _face, new Emgu.CV.Structure.MCvScalar(255, 255, 255));
}
_img.Save("result.jpg"); // SAVE TO BYTE ARRAY
我了解到您的问题实际上有两个方面:将图像转换为 byte[]
,并将 byte[]
保存到文件。我将首先解决更简单的问题和后者:
正在将 byte[]
保存到文件
using(FileStream fs = new FileStream("OutputFile.dat",FileMode.OpenOrCreate))
{
BinaryWriter bs = new BinaryWriter(fs);
bs.Write(byteBuffer);
}
正在从文件中加载 byte[]
byte[] byteBuffer;
using (FileStream fs = new FileStream("InputFile.dat", FileMode.OpenOrCreate))
{
BinaryReader br = new BinaryReader(fs);
// Where 0xF0000 is calculated as Image Width x Height x Bit Depth
byteBuffer = br.ReadBytes(0xF0000);
}
现在开始第二部分;我假设您熟悉像素格式以及 byte[,,]
(或任何其他深度)的真实图像结构如何序列化为单一维度 byte[]
。如果没有请问。
从 byte[]
创建一个 Image
在下面的示例中,byte[]
是创建的而不是像上面那样加载的,byte[]
的来源是无关紧要的,只要它是已知图像维度和深度的正确序列化即可.
int width = 640; // Image Width
int height = 512; // Image Height
int stride = 640 * 3; // Image Stide - Bytes per Row (3 bytes per pixel)
// Create data for an Image 512x640 RGB - 983,040 Bytes
byte[] sourceImgData = new byte[0xF0000];
// Pin the imgData in memory and create an IntPtr to it's location
GCHandle pinnedArray = GCHandle.Alloc(sourceImgData, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// Create an image from the imgData
Image<Rgb, byte> img = new Image<Rgb, byte>(width, height, stride, pointer);
// Free the memory
pinnedArray.Free();
将 Image
转换为 byte[]
// Convert the source Image to Bitmap
Bitmap bitmap = sourceImage.ToBitmap();
// Create a BitmapData object from the resulting Bitmap, locking the backing data in memory
BitmapData bitmapData = bitmap.LockBits(
new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
// Create an output byte array
byte[] destImgData = new byte[bitmapData.Stride * bitmap.Height];
// Copy the byte array to the destination imgData
Marshal.Copy(bitmapData.Scan0,
destImgData,
0,
destImgData.Length);
// Free the memory
bitmap.UnlockBits(bitmapData);