将 14 位灰度图像(保存在 long[] 中)复制到图片框
Posted
技术标签:
【中文标题】将 14 位灰度图像(保存在 long[] 中)复制到图片框【英文标题】:Copying a 14bit grayscale image (saved in long[]) to a pictureBox 【发布时间】:2010-05-17 09:41:33 【问题描述】:我的相机给了我 14 位灰度图像,但 API 的函数返回一个 long* 到图像数据。 (所以我假设每个像素有 4 个字节)
我的应用程序是用 C++/CLI 编写的,pictureBox 是 .NET 类型的。
我目前正在使用BitmapData.LockBits()
机制来获取对图像数据的指针访问,并使用memcpy(bmpData.Scan0.ToPointer(), imageData, sizeof(long)*height*width)
将图像数据复制到位图。
目前,唯一有效的 PixelFormat 是 32 位 RGB,并且图像显示为带有轮廓的蓝色阴影。
尝试将位图初始化为 16bppGrayscale 不起作用。 理想情况下,我希望将数组从 long 转换为 word 并使用 16 位格式(希望 14 位数据能够正确显示),但我不确定这是否有效。 另外,我不想遍历图像数据,所以找到最小/最大值然后直方图拉伸到 [0..255] 对我来说不是一个选项(显示必须尽可能高效)
谢谢
【问题讨论】:
【参考方案1】:是的,它看起来很蓝,高强度像素的一些绿色阴影。你有一个像素格式不匹配,32bppRgb 有一个蓝色字节,一个绿色字节,一个红色字节和一个未使用字节。直接复制灰度图会设置蓝色字节,最多6位绿色。
16bppGrayScale 会很棒,如果只有 GDI+ 实际支持它。问题是没有主流视频适配器处理这种格式。您需要将像素值转换为 RGB 三元组。为了让它看起来是灰色的,你需要将蓝色、绿色和红色字节设置为相同的值。这将是一个有损转换,因为您需要将 14 位压缩为 8 位。这并不重要,人眼还不足以区分 16,384 个不同的灰度级。假设相机为高亮度像素生成 16383 的像素值,只需将像素值右移 6。 24bppRgb 或 32bppRgb 像素格式都可以使用,后者会更快,因为它适合 int 并且您不必大步向前。
请注意,假彩色图像也是可能的。您可以任意将 14 位灰度值映射到颜色。最快的方法是使用 int[16384] 映射表。您在表格中添加的内容完全取决于您,常见的映射是深红色表示低强度值,紫色表示高强度值。
这对于图像显示来说已经足够了。但是,如果您进行任何图像处理,那么您可能希望利用相机的分辨率。您需要远离位图。查看像 LeadTools 这样的图形库供应商。
【讨论】:
我在 14 位阵列上做 IP,我只需要同时显示相机图像,这样我就知道系统还活着并且工作正常。明智的实施-根据您的建议(两个选项),我仍然需要遍历整个图像..对吗?对于选项 A,我将 SR 提高 6,然后将此值复制到 R & G,对于第二个,我必须在图像上执行映射。 是的,需要映射每个单独的像素。 也许我只能更改位图中的调色板?关于库,我有 IPP,但真的不知道它的任何功能是否可以帮助我。 索引像素格式也是一个问题,直到 GDI+ 1.10 版(Vista 及更高版本)才得到很好的支持。 8bpp 仍然需要您映射每个像素。是的,IPP 绝对应该提供帮助,利用 CPU 矢量处理指令。一次四个像素。小心对齐问题。不过,图形库的成本与您的时间不匹配。 好的,谢谢,明天我会检查所有选项。以上是关于将 14 位灰度图像(保存在 long[] 中)复制到图片框的主要内容,如果未能解决你的问题,请参考以下文章
opencv如何将lena.jpg的灰度值读取出来并在计算机上保存下来
如何使用 matplotlib/numpy 将数组保存为灰度图像?
如何使用 IPP 将 8 位灰度图像转换为 NV12(有限范围)色彩空间