根据 Emgu 规范,这些参数的含义是:
/// <param name="type">Mat element type
/// <param name="channels">Number of channels
/// <param name="data">
/// Pointer to the user data. Matrix constructors that take data and step parameters do not
/// allocate matrix data. Instead, they just initialize the matrix header that points to the
/// specified data, which means that no data is copied. This operation is very efficient and
/// can be used to process external data using OpenCV functions. The external data is not
/// automatically deallocated, so you should take care of it.
/// <param name="step">
/// Number of bytes each matrix row occupies.
/// The value should include the padding bytes at the end of each row, if any.
type是CvEnum.DepthType的类型,是图像的深度,你可以传递CvEnum.DepthType.Cv32F,代表32位深度的图像,其他可能的值是CvEnum.DepthType.Cv{x}{t}的形式,其中{x} 是集合 {8,16,32,64} 的任何值,{t} 可以是 Sfor Single 或 F for Float。
channels,取决于图像的类型,但我认为您可以使用来自 ARGB 的 4。
对于其他2个参数,如果不需要优化部分,可以直接使用Mat类的这个构造函数:
public Mat(int rows, int cols, DepthType type, int channels)
如果你真的要使用优化版,那么(续):
data,您可以通过 Bitmap.GetHbitmap() 将 IntPtr 返回给用户数据。
step,对于这家伙,我给你一个有根据的猜测,如果对于每个像素你有 4 个通道,并且每个通道的范围从 0 到 255(8 位),8*4 = 32,那么对于每个单元宽度都需要 32 位。假设这是正确的,每一行都有32*width 位,将其转换为字节((8*4)*width)/8 = 4*width,即通道数乘以图像宽度。
更新
获取data 和step 的其他方法是来自BitmapData 类,如下所示(摘自MSDN 资源):
Bitmap bmp = new Bitmap(Image.FromStream(httpPostedFileBase.InputStream, true, true));
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// data = scan0 is a pointer to our memory block.
IntPtr data = bmpData.Scan0;
// step = stride = amount of bytes for a single line of the image
int step = bmpData.Stride;
// So you can try to get you Mat instance like this:
Mat mat = new Mat(bmp.Height, bmp.Width, CvEnum.DepthType.Cv32F, 4, data, step);
// Unlock the bits.
bmp.UnlockBits(bmpData);
尚未测试此解决方案,但您可以尝试一下。
我的回答是基于 Emgu 代码 here.、Bitmap IntPtr here 以及这个 post,这也有助于我进一步了解这一点。
我也看到了其他方法,除非你真的需要调用完整的构造函数,否则我会尝试这种方法,看起来更干净:
HttpPostedFileBase file //your file must be available is this context.
if (file.ContentLength > 0)
{
string filename = Path.GetFileName(file.FileName);
// your so wanted Mat!
Mat img = imread(filename, CV_LOAD_IMAGE_COLOR);
}
注意
OpenCV documentation 中有很棒的教程。只需查看核心模块的可用教程即可。特别是这个one。