1

如何让 .NET 位图和 OpenCV 图像指向同一块内存?我知道我可以从一个复制到另一个,但我希望它们只指向相同的像素。

使用 Emgu 的解决方案的奖励积分。

4

3 回答 3

5

以下只是一个理论,可能行不通,我对 opencv/emgucv 不是很有经验


两者System.Drawing.Bitmap都有Emgu.CV.Image构造函数scan0作为参数。您可以为图像分配内存并将此指针传递给该构造函数。可以通过var ptr = Marshal.AllocHGlobal(stride*height)(不要忘记释放 ofc)或通过分配足够大小的托管数组并获取其地址来分配内存。地址可以通过以下方式获取:

var array = new byte[stride*height];
var gch = GCHandle.Alloc(array, GCHandleType.Pinned);
var ptr = gch.AddrOfPinnedObject();

这也是“固定”数组,因此垃圾收集器不能移动它,地址也不会改变。

我们将使用这些构造函数:

Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0);
Image<Bgr, Byte>(int width, int height, int stride, IntPtr scan0);

widthheight论据是不言自明的。 format对于位图是PixelFormat.Format24bppRgb. stride是单行图像的字节数,它也必须对齐(是 4 的倍数)。你可以这样得到它:

var stride = (width * 3);
var align = stride % 4;
if(align != 0) stride += 4 - align;

并且scan0是指向我们的内存块的指针。

所以我建议在创建System.Drawing.BitmapEmgu.CV.Image使用这些构造函数之后会使用相同的内存块。如果不是,则意味着 opencv 或 Bitmap 或两者都复制提供的内存块和可能的解决方案(如果存在)绝对不值得努力。

于 2010-06-04T04:04:29.223 回答
2

Emgu.CV来源:

// Summary:
//     The Get property provide a more efficient way to convert Image<Gray, Byte>,
//     Image<Bgr, Byte> and Image<Bgra, Byte> into Bitmap such that the image data
//     is shared with Bitmap. If you change the pixel value on the Bitmap, you change
//     the pixel values on the Image object as well! For other types of image this
//     property has the same effect as ToBitmap() Take extra caution not to use
//     the Bitmap after the Image object is disposed The Set property convert the
//     bitmap to this Image type.
public Bitmap Bitmap { get; set; }

所以基本上,对于特定类型的图像,您可以使用.BitmapCV 图像的属性,然后直接指向 CV 图像数据。

例子:

string filename;
// ... point filename to your file of choice ...

Image<Bgr, byte> cvImg  = new Image<Bgr, byte>(filename);
Bitmap           netBmp = cvImg.Bitmap;
于 2011-01-05T13:28:32.583 回答
0

不确定这是否有帮助,但您可以使用 .Ptr 从 Emgu 图像中获取指针

例如 IntPtr ip= img1.Ptr;

于 2010-09-29T00:25:59.873 回答