我有一个MVC应用程序,其中一个控制器接收上传的文件(图像)作为HttpPostedFileBase对象.
我正在尝试使用处理图像EmguCV,但是我很难将我转换HttpPostedFileBase为EmguCV矩阵对象Emgu.CV.Mat(这只是C#一个cv::Mat对象的实现).
有一个构造函数Mat,看起来像:
public Mat(int rows, int cols, DepthType type, int channels, IntPtr data, int step);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何获得type,data以及step从我开始HttpPostedFileBase的对象.这可能吗?
我在这里看到,我可以将一个对象转换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.
Run Code Online (Sandbox Code Playgroud)
type是类型CvEnum.DepthType,它是图像的深度,你可以传递CvEnum.DepthType.Cv32F它代表32位深度图像,其他可能的值是形式CvEnum.DepthType.Cv{x}{t},其中{x}是集合的任何值{8,16,32,64}和{t}可以是Sfor Single或Ffor Float.
channels,取决于图像的类型,但我认为你可以使用4ARGB.
对于其他2个参数,如果您不需要优化部分,则可以使用Mat该类的构造函数:
public Mat(int rows, int cols, DepthType type, int channels)
Run Code Online (Sandbox Code Playgroud)
如果您真的想使用优化版本,那么(继续):
data,您可以传递Bitmap.GetHbitmap(),它将IntPtr返回给用户数据.
step对于这个家伙,我会给你一个明智的猜测,如果每个像素你有4个通道,每个通道的范围从0到255(8位)8*4 = 32,那么对于每个单位宽度你需要32位.假设这是正确的,每行都有32*width位,将其转换为字节((8*4)*width)/8 = 4*width,即通道数乘以图像宽度.
UPDATE
获取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);
Run Code Online (Sandbox Code Playgroud)
没有测试过这个解决方案,但你可以尝试一下.我的答案是基于这里的Emgu代码.,Bitmap IntPtr 在这里以及这篇文章也帮助我对此有了进一步的了解.
我已经看到了其他方法,除非你真的需要调用那个完整的构造函数,我会尝试这种方法,看起来更干净:
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);
}
Run Code Online (Sandbox Code Playgroud)
注意
OpenCV文档中有很棒的教程.只需查看核心模块的可用教程.特别是这一个.
| 归档时间: |
|
| 查看次数: |
4115 次 |
| 最近记录: |