gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 21:22:25 24 4
gpt4 key购买 nike

我有一个 MVC 应用程序,其中我的一个 Controller 接收上传的文件(图像)作为 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 中获取typedatastep > 对象。这可能吗?

我看到 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.
  • typeCvEnum.DepthType类型,也就是图像的深度,可以通过CvEnum.DepthType.Cv32F 表示 32 位深度图像,其他可能的值的形式为 CvEnum.DepthType.Cv{x}{t},其中 {x} 是集合 {8,16, 32,64} 和 {t} 可以是 S 表示 SingleF 表示 Float

  • channels,取决于图像的类型,但我认为您可以使用 ARGB 中的 4

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

public Mat(int rows, int cols, DepthType type, int channels)

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

  • data,你可以通过 Bitmap.GetHbitmap() 返回一个 IntPtr 给用户数据。

  • step,对于这个人,我会给你一个有根据的猜测,如果每个像素有 4 个 channel ,并且每个 channel 的范围从 0 到 255(8 位),8*4 = 32,所以对于单位的每个宽度,你需要 32 位。假设这是正确的,每一行都有 32*width 位,将其转换为字节 ((8*4)*width)/8 = 4*width,这是 channel 数,乘以图像宽度。

更新

获取数据步骤的其他方法来自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 ., 位图 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 .

关于C#/EmguCV - 将上传的 HttpPostedFileBase 转换为 Emgu.CV.Mat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24050813/

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