如何从 OpenCV 图像中获取 BITMAPINFOHEADER?
How to get BITMAPINFOHEADER from OpenCV image?
我必须使用第 3 方本机 API,它将指向 BITMAPINFOHEADER 结构的指针和指向位图数据的指针作为参数。
static Image load ( IntPtr bi, IntPtr img, string name )
constructs a image representation from the specified bitmap image in
memory. The bi pointer points to a BITMAPINFOHEARER followed by an
optional color table. The existence of a colortable depends on the
image type. The Byte pointer has to point to bitmap data as described
by the bitmap information.
如何在 C# 中获取指向表示具有指定大小的未压缩 24 位 RGB 位图的结构的指针?
我已经从这里下载了 BITMAPINFOHEADER 结构 C# 声明:http://www.pinvoke.net/default.aspx/Structures/BITMAPINFOHEADER.html
我实际上正在使用 EmguCV 图像 class,我试图从 Image<Rgb, byte>
.
中获取描述图像的 BITMAPINFOHEARER
var image = new Image<Rgb, byte>(@"myImage.bmp");
//1. create BITMAPINFOHEADER instance
var bitmapInfoHeader = new BITMAPINFOHEADER
{
biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)), //40
biWidth = image.Width, //4096
biHeight = image.Height, //4096
biPlanes = 1,
biBitCount =24,
biCompression = BitmapCompressionMode.BI_RGB,
biSizeImage = (uint)image.Bytes.Length,
};
//2. get pointer to the data
IntPtr ptrData;
fixed (byte* pData = image.Data)
ptrData = (IntPtr)pData;
//3. get pointer to the BitmapInfoHeader:
int iSizeOfBih = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
IntPtr ptrBih = Marshal.AllocHGlobal(iSizeOfBih);
Marshal.StructureToPtr(bih, ptrBih, false);
fixed (byte* pData = image.Bytes)
{
var frImage = Bmp.load(pBitmapInfoHeader, (IntPtr)pData, "Frame");
var faces = faceTracker.processFrame(frImage);
}
虽然编译和运行没有异常,但它没有正确加载图像(我无法处理稍后使用 facetracker.When 我使用另一种方法从 facetracker 工作的文件加载图像)
我做错了什么?
评论回顾
关于如何填写 BITMAPINFOHEADER
的大部分信息都可以在 msdn documentation 上找到。
需要更正的几点:
biSize
应该填写 BITMAPINFOHEADER
的大小。这个字段在这里是因为结构可以是更完整的版本,如BITMAPV5HEADER
,所以如果设置不正确,它可能会起作用,但显然不推荐。
biCompression
应设置为 BI_RGB
。 BI_BITFIELDS
未记录为对 24 位模式有效。
biHeight
如果图像是自上而下的,则应设置为负数,这很可能是内存表示的情况,就像您的情况一样。否则,图片可能会上下颠倒加载。
biSizeImage
貌似设置正确,但由于在BI_RGB
模式下是允许填0的,这样可以防止出错。
此外,固定指针(使用 fixed
)的所有使用都应在 fixed
范围内完成。如果在外面使用,不能保证数组不会被移动到别处。
关于尺寸,Image
class 似乎使用了行填充,即,如果行的宽度不是 4 字节的倍数,则用额外的字节填充行。 BITMAPINFOHEADER
描述的位图也应该有这个 属性,所以 load
可能适用于所有维度,但如果 load
实际上不支持行填充,它可能需要将图像复制到具有精确尺寸的数组。另一种解决方案是在任何地方都使用 32 位模式(并且它也可能会提高性能)。
我必须使用第 3 方本机 API,它将指向 BITMAPINFOHEADER 结构的指针和指向位图数据的指针作为参数。
static Image load ( IntPtr bi, IntPtr img, string name )
constructs a image representation from the specified bitmap image in memory. The bi pointer points to a BITMAPINFOHEARER followed by an optional color table. The existence of a colortable depends on the image type. The Byte pointer has to point to bitmap data as described by the bitmap information.
如何在 C# 中获取指向表示具有指定大小的未压缩 24 位 RGB 位图的结构的指针?
我已经从这里下载了 BITMAPINFOHEADER 结构 C# 声明:http://www.pinvoke.net/default.aspx/Structures/BITMAPINFOHEADER.html
我实际上正在使用 EmguCV 图像 class,我试图从 Image<Rgb, byte>
.
var image = new Image<Rgb, byte>(@"myImage.bmp");
//1. create BITMAPINFOHEADER instance
var bitmapInfoHeader = new BITMAPINFOHEADER
{
biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)), //40
biWidth = image.Width, //4096
biHeight = image.Height, //4096
biPlanes = 1,
biBitCount =24,
biCompression = BitmapCompressionMode.BI_RGB,
biSizeImage = (uint)image.Bytes.Length,
};
//2. get pointer to the data
IntPtr ptrData;
fixed (byte* pData = image.Data)
ptrData = (IntPtr)pData;
//3. get pointer to the BitmapInfoHeader:
int iSizeOfBih = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
IntPtr ptrBih = Marshal.AllocHGlobal(iSizeOfBih);
Marshal.StructureToPtr(bih, ptrBih, false);
fixed (byte* pData = image.Bytes)
{
var frImage = Bmp.load(pBitmapInfoHeader, (IntPtr)pData, "Frame");
var faces = faceTracker.processFrame(frImage);
}
虽然编译和运行没有异常,但它没有正确加载图像(我无法处理稍后使用 facetracker.When 我使用另一种方法从 facetracker 工作的文件加载图像)
我做错了什么?
评论回顾
关于如何填写 BITMAPINFOHEADER
的大部分信息都可以在 msdn documentation 上找到。
需要更正的几点:
biSize
应该填写 BITMAPINFOHEADER
的大小。这个字段在这里是因为结构可以是更完整的版本,如BITMAPV5HEADER
,所以如果设置不正确,它可能会起作用,但显然不推荐。
biCompression
应设置为 BI_RGB
。 BI_BITFIELDS
未记录为对 24 位模式有效。
biHeight
如果图像是自上而下的,则应设置为负数,这很可能是内存表示的情况,就像您的情况一样。否则,图片可能会上下颠倒加载。
biSizeImage
貌似设置正确,但由于在BI_RGB
模式下是允许填0的,这样可以防止出错。
此外,固定指针(使用 fixed
)的所有使用都应在 fixed
范围内完成。如果在外面使用,不能保证数组不会被移动到别处。
关于尺寸,Image
class 似乎使用了行填充,即,如果行的宽度不是 4 字节的倍数,则用额外的字节填充行。 BITMAPINFOHEADER
描述的位图也应该有这个 属性,所以 load
可能适用于所有维度,但如果 load
实际上不支持行填充,它可能需要将图像复制到具有精确尺寸的数组。另一种解决方案是在任何地方都使用 32 位模式(并且它也可能会提高性能)。