C# 如何从OpenCV图像中获取BitMapInfo标头?
我必须使用第三方原生API,它将指向结构的指针和指向位图数据的指针作为参数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
静态图像加载(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);
}