如何从OpenCV图像中获取BITMAPINFOHEADER?

时间:2015-09-28 07:36:40

标签: c# winapi bitmap marshalling emgucv

我必须使用第三方本机API,它将指向BITMAPINFOHEADER结构的指针和指向位图数据的指针作为参数。

  

static Image load ( IntPtr bi, IntPtr img, string name )

     

从中指定位图图像构造图像表示   记忆。 bi指针指向BITMAPINFOHEARER,后跟一个   可选颜色表。 colortable的存在取决于   图像类型。字节指针必须指向位图数据,如上所述   通过位图信息。

如何在C#中获取指向具有指定大小的未压缩24位RGB位图的结构指针?

我从这里下载了BITMAPINFOHEADER结构C#decalaration:http://www.pinvoke.net/default.aspx/Structures/BITMAPINFOHEADER.html

我实际上正在使用EmguCV图像类,我试图让BITMAPINFOHEARER描述来自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。当我使用另一种方法从facetracker工作的文件加载图像时)

我做错了什么?

1 个答案:

答案 0 :(得分:0)

回顾评论

有关如何填充BITMAPINFOHEADER的大部分信息都可以在msdn documentation找到。

应该纠正的一些要点:
biSize应填充BITMAPINFOHEADER的大小。此字段在这里是因为结构可以是更完整的版本,如BITMAPV5HEADER,因此如果设置不正确,它可能会起作用,但显然不建议这样做。
biCompression应设为BI_RGBBI_BITFIELDS未记录为24位模式有效 如果图像是自上而下的,则应将biHeight设置为负值,这可能就像您的情况中的内存表示一样。如果没有,图像可能会被颠倒加载 biSizeImage似乎设置正确,但由于允许在BI_RGB模式下将其填充为0,因此可以防止出错。
此外,固定指针(带fixed)的所有用法都应在fixed范围内完成。如果在室外使用,则无法保证阵列不会移动到其他位置。

关于维度,Image类似乎使用行填充,即,如果行的宽度不是4个字节的倍数,则用其他字节填充行。 BITMAPINFOHEADER描述的位图也应该具有此属性,因此可以期望load适用于所有维度,但如果load实际上不支持行填充,则可能需要复制图像到具有精确尺寸的数组。另一种解决方案是在任何地方使用32位模式(并且它也可以提高性能)。