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

前端之家收集整理的这篇文章主要介绍了C#/ EmguCV – 将上传的HttpPostedFileBase转换为Emgu.CV.Mat前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个MVC应用程序,其中一个控制器接收上传文件(图像)作为HttpPostedFileBase对象.

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

Mat的构造函数如下所示:

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

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

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

解决方法

根据Emgu规范,这些参数意味着:
  1. /// <param name="type">Mat element type
  2.  
  3. /// <param name="channels">Number of channels
  4.  
  5. /// <param name="data">
  6. /// Pointer to the user data. Matrix constructors that take data and step parameters do not
  7. /// allocate matrix data. Instead,they just initialize the matrix header that points to the
  8. /// specified data,which means that no data is copied. This operation is very efficient and
  9. /// can be used to process external data using OpenCV functions. The external data is not
  10. /// automatically deallocated,so you should take care of it.
  11.  
  12. /// <param name="step">
  13. /// Number of bytes each matrix row occupies.
  14. /// 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类的这个构造函数

  1. 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资源):

  1. Bitmap bmp = new Bitmap(Image.FromStream(httpPostedFileBase.InputStream,true,true));
  2.  
  3. // Lock the bitmap's bits.
  4. Rectangle rect = new Rectangle(0,bmp.Width,bmp.Height);
  5.  
  6. System.Drawing.Imaging.BitmapData bmpData =
  7. bmp.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat);
  8.  
  9. // data = scan0 is a pointer to our memory block.
  10. IntPtr data = bmpData.Scan0;
  11.  
  12. // step = stride = amount of bytes for a single line of the image
  13. int step = bmpData.Stride;
  14.  
  15. // So you can try to get you Mat instance like this:
  16. Mat mat = new Mat(bmp.Height,CvEnum.DepthType.Cv32F,4,data,step);
  17.  
  18. // Unlock the bits.
  19. bmp.UnlockBits(bmpData);

没有测试过这个解决方案,但你可以尝试一下.
我的答案是基于Emgu代码here.,Bitmap IntPtr here以及post,这也帮助我进一步了解了这一点.

我已经看到了其他方法,除非你真的需要调用那个完整的构造函数,我会尝试这种方法,看起来更干净:

  1. HttpPostedFileBase file //your file must be available is this context.
  2.  
  3. if (file.ContentLength > 0)
  4. {
  5. string filename = Path.GetFileName(file.FileName);
  6.  
  7. // your so wanted Mat!
  8. Mat img = imread(filename,CV_LOAD_IMAGE_COLOR);
  9. }

注意

OpenCV documentation中有很棒的教程.只需看一下核心模块的可用教程.特别是这个one.

猜你在找的C#相关文章