将 14 位灰度图像(保存在 long[] 中)复制到 pictureBox

发布于 2024-09-02 10:46:42 字数 522 浏览 1 评论 0原文

我的相机为我提供了 14 位灰度图像,但 API 的函数返回一个 long* 到图像数据。 (所以我假设每个像素 4 个字节)

我的应用程序是用 C++/CLI 编写的,pictureBox 是 .NET 类型。
我目前正在使用 BitmapData.LockBits() 机制来获取对图像数据的指针访问,并使用
memcpy(bmpData.Scan0.ToPointer(), imageData, sizeof(长)*高*宽)
将图像数据复制到位图。
目前,唯一可用的 PixelFormat 是 32 位 RGB,并且图像显示为带有轮廓的蓝色阴影。

尝试将位图初始化为 16bppGrayscale 不起作用。
理想情况下,我希望将数组从 long 转换为 word 并使用 16 位格式(希望 14 位数据能够正确显示),但我不确定这是否有效。 另外,我不想迭代图像数据,因此找到最小值/最大值然后将直方图拉伸到 [0..255] 对我来说不是一个选择(显示必须尽可能高效)

谢谢

My camera gives me 14bit grayscale images, but the API's function returns a long* to the image data. (so i'm assuming 4 bytes for each pixel)

My application is written in C++/CLI, and the pictureBox is of .NET type.
I am currently using the BitmapData.LockBits() mechanism to gain pointer access to the image data, and using
memcpy(bmpData.Scan0.ToPointer(), imageData, sizeof(long)*height*width)
to copy the image data to the Bitmap.
For now, the only PixelFormat that is working is 32bit RGB, and the image appears in shades of blue with contours.

Trying to initialize the Bitmap as 16bppGrayscale isn't working.
I would ideally want to cast the array from long to word and using a 16bit format (hoping the the 14bit data will be displayed properly) but I'm not sure if this works.
Also, I don't want to iterate over the image data, so finding the min/max and then histogram stretching to [0..255] isnt an option for me (the display must be as efficient as possible)

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青丝拂面 2024-09-09 10:46:42

是的,对于高强度像素来说,它看起来会很蓝,有一些绿色阴影。像素格式不匹配,32bppRgb 有一个字节表示蓝色,一个字节表示绿色,一个字节表示红色,还有一个未使用的字节。直接复制灰度图像会设置蓝色字节,最多6位绿色。

16bppGrayScale 会很棒,如果只有 GDI+ 真正支持的话。问题是没有主流视频适配器处理这种格式。您需要将像素值转换为 RGB 三元组。要使其看起来呈灰色,您需要将蓝色、绿色和红色字节设置为相同的值。这将是一个有损转换,因为您需要将 14 位压缩为 8 位。这并不重要,人眼还不足以区分 16,384 个不同的灰度级。只需将像素值右移 6,假设相机为高亮度像素生成的像素值为 16383。 24bppRgb 或 32bppRgb 像素格式都可以使用,后者会更快,因为它适合 int 并且您不必大步前进。

请注意,假彩色图像也是可能的。您可以任意将 14 位灰度值映射到颜色。最快的方法是使用 int[16384] 映射表。您在表格中粘贴的内容完全取决于您,常见的映射为深红色表示低强度值,紫色表示高强度值。

这对于图像显示来说已经足够了。但是,如果您进行任何图像处理,那么您可能会想要利用相机的分辨率。您需要远离位图。查看像 LeadTools 这样的图形库供应商。

Yes, that will look very blue, some shades of green for high intensity pixels. You've got a pixel format mismatch, 32bppRgb has one byte for blue, one for green, one for red and one unused byte. Copying the gray image directly will set the blue byte, up to 6 bits of green.

16bppGrayScale would be great, if only GDI+ actually supported it. The problem is that no main-stream video adapter handles this format. You'll need to translate the pixel values to a RGB triplet. To make it look gray, you'll need to set the blue, green and red bytes to the same value. That will be a lossy conversion since you need to squeeze 14 bits into 8 bits. That doesn't really matter, the human eye isn't nearly good enough to be able to distinguish 16,384 distinct gray levels. Simply right-shift the pixel value by 6, assuming the camera produces a pixel value of 16383 for high luminosity pixels. Either a 24bppRgb or 32bppRgb pixel format will work, the latter will be quicker since it fits an int and you don't have to monkey with stride.

Note that false-color images are possible too. You could arbitrarily map a 14 bit gray value to a color. Quickest way to do this is by using a int[16384] mapping table. What you stick in the table is entirely up to you, common mappings are deep red for low intensity, violet for high intensity values.

That's good enough for image display. However, if you do any image processing then you'll probably want to take advantage of the camera's resolution. You'll need to stay away from Bitmap. Check out a graphics library vendor like LeadTools.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文