gpt4 book ai didi

opencv - EmguCV - Mat.Data 数组在图像加载后始终为空

转载 作者:太空宇宙 更新时间:2023-11-03 21:13:43 25 4
gpt4 key购买 nike

当我尝试从文件中读取图像时,加载 Mat.Data 数组后始终为空。但是当我在调试期间查看 Mat 对象时,有一个字节数组,其中包含来自图像的所有数据。

Mat image1 = CvInvoke.Imread("minion.bmp", Emgu.CV.CvEnum.LoadImageType.AnyDepth);

你知道为什么吗?

最佳答案

我知道这个问题太老了,但我遇到了同样的问题,我怀疑答案就在 Emgu wiki 中.具体来说:

Accessing the pixels from Mat

Unlike the Image<,> class, where memory are pre-allocated and fixed, the memory of Mat can be automatically re-allocated by Open CV function calls. We cannot > pre-allocate managed memory and assume the same memory are used through the life time of the Mat object. As a result, Mat class do not contains a Data > property like the Image<,> class, where the pixels can be access through a managed array. To access the data of the Mat, there are a few possible choices. The easy way and safe way that cost an additional memory copy

The first option is to copy the Mat to an Image<,> object using the Mat.ToImage function. e.g.

Image<Bgr, Byte> img = mat.ToImage<Bgr, Byte>();

The pixel data can then be accessed using the Image<,>.Data property.

You can also convert the Mat to an Matrix<> object. Assuming the Mat contains 8-bit data,

Matrix<Byte> matrix = new Matrix<Byte>(mat.Rows, mat.Cols, mat.NumberOfChannels);
mat.CopyTo(matrix);

Note that you should create Matrix<> with a matching type to the Mat object. If the Mat contains 32-bit floating point value, you should replace Matrix in the above code with Matrix. The pixel data can then be accessed using the Matrix<>.Data property. The fastest way with no memory copy required. Be caution!!!

The second option is a little bit tricky, but will provide the best performance. This will usually require you to know the size of the Mat object before it is created. So you can allocate managed data array, and create the Mat object by forcing it to use the pinned managed memory. e.g.

//load your 3 channel bgr image here
Mat m1 = ...;

//3 channel bgr image data, if it is single channel, the size should be m1.Width * m1.Height

byte[] data = new byte[m1.Width * m1.Height * 3];`
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);`
using (Mat m2 = new Mat(m1.Size, DepthType.Cv8U, 3, handle.AddrOfPinnedObject(), m1.Width * 3))`
CvInvoke.BitwiseNot(m1, m2);`
handle.Free();

At this point the data array contains the pixel data of the inverted image. Note that if the Mat m2 was allocated with the wrong size, data[] array will contains all 0s, and no exception will be thrown. So be really careful when performing the above operations.

TL;DR:您不能按照您希望的方式使用 Data 对象(至少从 3.2 版开始)。您必须将其复制到另一个允许使用数据对象的对象。

关于opencv - EmguCV - Mat.Data 数组在图像加载后始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39371651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com