C# 如何从OpenCV图像中获取BitMapInfo标头?

C# 如何从OpenCV图像中获取BitMapInfo标头?,c#,winapi,bitmap,marshalling,emgucv,C#,Winapi,Bitmap,Marshalling,Emgucv,我必须使用第三方原生API,它将指向结构的指针和指向位图数据的指针作为参数 静态图像加载(IntPtr-bi、IntPtr-img、字符串名) 从中指定的位图图像构造图像表示形式 记忆。双指针指向BitMapInfo侦听器,后跟 可选颜色表。颜色表的存在取决于颜色 图像类型。字节指针必须指向位图数据,如所述 通过位图信息 如何获取指向以C#表示指定大小的未压缩24位RGB位图的结构的指针? 我已经从这里下载了BitMapInfo Header结构C#decaration: 实际上,我正在使用Em

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

静态图像加载(IntPtr-bi、IntPtr-img、字符串名)

从中指定的位图图像构造图像表示形式 记忆。双指针指向BitMapInfo侦听器,后跟 可选颜色表。颜色表的存在取决于颜色 图像类型。字节指针必须指向位图数据,如所述 通过位图信息

如何获取指向以C#表示指定大小的未压缩24位RGB位图的结构的指针?

我已经从这里下载了BitMapInfo Header结构C#decaration:

实际上,我正在使用EmguCV图像类,我试图从中获取描述图像的BitMapInfo对象

var image=newimage(@“myImage.bmp”);
//1. 创建BitMapInfo头实例
var BitMapInfo头=新的BitMapInfo头
{
biSize=(uint)Marshal.SizeOf(typeof(BitMapInfo头)),//40
biWidth=image.Width,//4096
biHeight=image.Height,//4096
双翼飞机=1,
biBitCount=24,
biCompression=BitmapCompressionMode.BI_RGB,
biSizeImage=(uint)image.Bytes.Length,
};
//2. 获取指向数据的指针
IntPtr-ptrData;
固定(字节*pData=image.Data)
ptrData=(IntPtr)pData;
//3. 获取指向BitMapInfo标头的指针:
int-iSizeOfBih=Marshal.SizeOf(typeof(BitMapInfo头));
IntPtr ptrBih=Marshal.AllocHGlobal(iSizeOfBih);
结构总司令(波黑、波黑、假);
已修复(字节*pData=image.Bytes)
{
var frImage=Bmp.load(pBitmapInfoHeader,(IntPtr)pData,“Frame”);
var faces=faceTracker.processFrame(frImage);
}
虽然编译和运行时没有异常,但它无法正确加载映像(我无法处理,因为以后使用facetracker时会出现这种情况。当我使用另一种方法从文件加载映像时,facetracker工作正常)


我做错了什么?

从评论中重述

有关如何填充
BitMapInfo头的大部分信息,请参见

需要纠正的几点:
biSize
应使用
BitMapInfo头的大小填充。此字段位于此处是因为结构可以是更完整的版本,如
BITMAPV5HEADER
,因此如果设置得不正确,它可能会工作,但显然不推荐使用。
biCompression
应设置为
biu RGB
<代码>BI_位字段
未记录为对24位模式有效。
如果图像是自上而下的,
biHeight
应该设置为负数,这可能是像您这样的内存表示的情况。否则,图像可能会被倒置加载。
biSizeImage
似乎设置正确,但由于允许在
BI_RGB
模式下用0填充,因此可以防止出现错误。
此外,所有固定指针的使用(使用
fixed
)都应在
fixed
范围内完成。如果在外部使用,则无法保证阵列不会移动到其他位置


关于维度,
Image
类似乎使用了行填充,也就是说,如果行的宽度不是4字节的倍数,则使用额外的字节填充行。
bitmapinfo-header
描述的位图也应该具有此属性,因此
load
可能适用于所有维度,但如果
load
实际上不支持行填充,则可能需要将图像复制到具有精确维度的数组中。另一种解决方案是在任何地方使用32位模式(也可能提高性能)。

尝试使用
BitmapCompressionMode。BI_RGB
biSize
不是图像的大小。您所说的“未正确加载图像”是什么意思?这一点都没有帮助。似乎
Image
实际上是行填充的,所以大小无关紧要。另一点,您对
ptrData
的所有使用都应该在
fixed
范围内。另外,尝试使用
biHeight=-image.Height
。为什么不阅读链接到的文档?
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);
}