【发布时间】:2017-07-03 00:58:02
【问题描述】:
我想访问一个 16UC1 格式的 png 图像的每个单独像素值的值,我将其作为字节 [] 接收。
我对 C# 中的图像处理非常陌生,而且我已经被这个问题困扰了好几天了。
我可以通过以下方式使用“典型”bgr8 格式的 jpg/png 字节数组:
private static Bitmap getBitmap(byte[] array)
{
return new Bitmap(new MemoryStream(array));
}
我为 16UC1 格式尝试了很多东西。我得到的最远的是:
private Bitmap getBitmap(byte[] array)
{
var bitmap = new Bitmap(640,480,PixelFormat.Format16bppRgb555);
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555);
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, array, 0, array.Length);
bitmap.UnlockBits(bitmapData);
return bitmap;
}
这至少会返回一个位图,尽管它是全黑的。
尝试使用 PixelFormat.Format16bppGrayScale 而不是 PixelFormat.Format16bppRgb555 会给我一个“GDI+ 中的一般错误”。
当将字节数组写入文件时,例如由
File.WriteAllBytes(filename, array);
我可以使用 IrfanView 等图像查看器查看图像,但 Windows 照片查看器会失败。
不需要将文件作为位图读取。出于性能原因,我想避免文件操作。我只是想访问该图像的每个单独的 xy 像素。
更新: 我开始使用 Emgu.CV 并按照 Dan 的建议应用 imdecode。
private Bitmap getCompressedDepthBitmap(byte[] data)
{
Mat result = new Mat(new Size(640, 480), DepthType.Cv16U, 1);
CvInvoke.Imdecode(data,LoadImageType.AnyDepth, result);
return result.Bitmap;
}
这又给了我一个黑色的图像。 (通过 WriteAllBytes 保存字节数组,我看到了有用的内容。)我也试过了
Image<Gray, float> image = result.ToImage<Gray, float>();
image.Save(Path.Combine(localPath, "image.png"));
这也给了我一个黑色的图像。 我现在正计划以某种方式对 Mat 进行标准化,也许这会有所帮助...
感谢您的关注和支持!
【问题讨论】:
-
如果是
CV_16UC1(意思是1通道,即灰度),那你为什么要把位图做成RGB呢? -
嗨,丹,你的评论比你好!您的意思是将每个值增加三倍然后将字节数组解析为位图吗?我的图像是一个压缩的 png 文件。它的大小各不相同,远小于 640*480*2 字节。不知道哪个字节对应一个灰度值。
-
哦,还没解码?你需要使用
imdecode... -
你确定我必须明确解码吗?我问,因为其他(例如 bgr8)压缩的 png 和 jpg 数据可以直接作为位图读取。您建议使用哪个 opencv 包装器包?恩古?再次感谢!
-
你试过用Image.FromStream加载图片吗?
标签: c# opencv bitmap emgucv bitmapimage