c# – OpenCV从字节数组创建Mat
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – OpenCV从字节数组创建Mat,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2522字,纯文字阅读大概需要4分钟。
内容图文
![c# – OpenCV从字节数组创建Mat](/upload/InfoBanner/zyjiaocheng/698/758631fc4a584ea2984ecf1dce6c6c78.jpg)
在我的C dll中,我从字节数组创建Mat:
BYTE * ptrImageData; //Image data is in this array passed to this function
Mat newImg = Mat(nImageHeight, nImageWidth, CV_8UC3, ptrImageData);
使用一些灰色阴影而不是原始阴影创建图像.
这是从字节数组创建Mat的正确方法吗?
请参阅代码
ptrImageData从C#代码传递给C dll.
传递图像数据的C#代码
System.Drawing.Image srcImage //Has the image
MemoryStream ms = new MemoryStream();
Marshal.FreeHGlobal(ptrImageData);
srcImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imgArray = ms.ToArray();
ms.Dispose();
int size1 = Marshal.SizeOf(imgArray[0]) * imgArray.Length;
IntPtr ptrImageData = Marshal.AllocHGlobal(size1);
Marshal.Copy(imgArray, 0, ptrImageData, imgArray.Length);
//Calling C++ dll function
ProcessImage(ptrImageData, srcImage.Width, srcImage.Height);
Marshal.FreeHGlobal(ptrImageData);
解决方法:
C代码看起来没问题,因为这为所提供的图像数据创建了一个矩阵包装器,假设缓冲区采用传统的RGB8格式.请注意,此构造函数不会复制缓冲区,因此缓冲区必须在此Mat实例的持续时间内保持有效(或被复制).
Mat newImg = Mat(nImageHeight, nImageWidth, CV_8UC3, ptrImageData);
问题似乎在于你的C#代码.我不是C#开发人员,但我会尽力帮助.您正在创建一个内存流,并使用JPEG编解码器将图像的压缩版本写入缓冲区,就像它是一个文件一样.但这不是cv :: Mat所期望的数据格式,因此您基本上会看到垃圾(压缩数据被解释为未压缩).
给定一个System.Image.Drawing.Image实例,您可以直接创建一个包装器Bitmap对象(或者可以使用,因为它是一个简单的向下转换).然后你可以使用Bitmap.LockBits()方法获取指向底层图像数据的指针.
Bitmap bmp = new Bitmap(sourceImage);
// 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);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbBuffer = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbBuffer, 0, bytes);
// Do your OpenCV processing...
// ...
// Unlock the bits.
bmp.UnlockBits(bmpData);
然后你可以将rgbBuffer传递给OpenCV.
我不相信原始代码中的内存管理也是完全正确的,但无论如何,只要缓冲区所有权的范围在锁定和解锁方法调用内,上述操作就会起作用.如果图像数据要比此代码块更长,则必须复制缓冲区.
小心你的像素格式 – 你需要确保Image / Bitmap实例真的包含RGB8数据. OpenCV的cv :: Mat有各种标志,因此您可以使用各种内存中的图像格式.但请注意,这些与磁盘(通常是压缩)格式不同,例如PNG,TIFF等.
内容总结
以上是互联网集市为您收集整理的c# – OpenCV从字节数组创建Mat全部内容,希望文章能够帮你解决c# – OpenCV从字节数组创建Mat所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。