微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#/ EmguCV – 将上传的HttpPostedFileBase转换为Emgu.CV.Mat

我有一个MVC应用程序,其中一个控制器接收上传文件(图像)作为HttpPostedFileBase对象.

我正在尝试使用EmguCV处理图像,但是我很难将我的HttpPostedFileBase转换为EmguCV矩阵对象Emgu.CV.Mat(这只是cv :: Mat对象的C#实现).

Mat的构造函数如下所示:

public Mat(int rows,int cols,DepthType type,int channels,IntPtr data,int step);

但我不知道如何从我的起始HttpPostedFileBase对象中获取类型,数据和步骤.这可能吗?

我看到here,我可以将HttpPostedFileBase转换为Image对象(我认为它在System.Drawing命名空间中),这允许我查看高度和宽度.但是,如何使用此信息获取其余所需参数以发送Mat()构造函数

解决方法

根据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.
>频道,取决于图像的类型,但我认为你可以使用4来自ARGB.

对于其他2个参数,如果不需要优化部分,则可以使用Mat类的这个构造函数

public Mat(int rows,int channels)

如果您真的想使用优化版本,那么(继续):

> data,您可以传递Bitmap.GetHbitmap(),它将IntPtr返回给用户数据.
>一步,对于这个家伙,我会给你一个明智的猜测,如果每个像素你有4个通道,每个通道的范围从0到255(8位),8 * 4 = 32,所以对于每个单位的宽度你需要32位.假设这是正确的,每行有32 *宽度位,将其转换为字节((8 * 4)*宽度)/ 8 = 4 *宽度,这是通道数乘以图像宽度.

UPDATE

获取数据和步骤的其他方法是从BitmapData类,这样(摘自MSDN资源):

Bitmap bmp = new Bitmap(Image.FromStream(httpPostedFileBase.InputStream,true,true));

// Lock the bitmap's bits.  
Rectangle rect = new Rectangle(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,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.

原文地址:https://www.jb51.cc/csharp/243892.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐