如何在 Python openCV 中显示 16 位 4096 强度图像?

问题描述

我有以灰度 16 位 tiff 格式编码的图像.他们使用 16 位颜色深度的变体,其中最大强度为 4,096.

I have images encoded in grayscale 16-bit tiff format. They use a variant of 16-bit color depth where the max intensity is 4,096.

我相信 openCV 中的默认最大强度是 65,536,所以我的图像使用以下代码显示为黑色.

I believe the default max intensity in openCV is 65,536, so my image shows up as black using the following code.

import cv2

image = cv2.imread("test.tif", -1)

cv2.imshow('tiff', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(image)

我可以在matplotlib中使用vminvmax来配置颜色映射:

I can use vmin and vmax in matplotlib to configure the color mapping:

import cv2
import matplotlib.pyplot as plt 

image = cv2.imread("test.tif", -1)
plt.imshow(image, cmap="gray", vmin=0, vmax=4096)
plt.show()

显示图片的内容:

我要坚持使用openCV的原因是matplotlib不支持显示16位RGB图像.

The reason why I want to stick with openCV is matplotlib doesn't support displaying 16-bit RGB images.

cv2 的文档.imshow 并不是很有帮助.有没有办法在 Python openCV 中显示 16 位 4096 强度图像?

The documentation of cv2.imshow is not really helpful. Are there ways to display 16-bit 4096 intensity images in Python openCV?

测试图像 test.tif 可以找到 这里.

The testing image test.tif can be found here.


解决方案

你会想要使用 cv2.normalize() 在显示之前缩放图像.

You'll want to use cv2.normalize() to scale the image before displaying.

您可以设置图像的最小值/最大值,它会适当地缩放图像(通过将图像的最小值移动到 alpha 并将图像的最大值移动到 beta).假设你的 img 已经是 uint16:

You can set the min/max of the image and it will scale the image appropriately (by moving the min of the image to alpha and max of the image to beta). Supposing your img is already a uint16:

img_scaled = cv2.normalize(img, dst=None, alpha=0, beta=65535, norm_type=cv2.NORM_MINMAX)

然后就可以正常观看了.

And then you can view as normal.

默认情况下,cv2.normalize() 将生成与输入图像相同类型的图像,因此如果您想要一个无符号的 16 位结果,您的输入应该是 uint16.

By default, cv2.normalize() will result in an image the same type as your input image, so if you want an unsigned 16-bit result, your input should be uint16.

再次,请注意,这会线性拉伸您的图像范围 --- 如果您的图像从未真正达到 0 并且说最小值是 100,那么在您标准化之后,该最小值将是您设置的任何值 alpha 到.如果您不希望这样,正如其中一条评论所建议的那样,您可以简单地将您的图像乘以 16,因为它目前只上升到 4095.使用 * 16,它将上升到 65535.

Again, note that this linearly stretches your image range---if your image never actually hit 0 and say the lowest value was 100, after you normalize, that lowest value will be whatever you set alpha to. If you don't want that, as one of the comments suggests, you can simply multiply your image by 16, since it's currently only going up to 4095. With * 16, it will go up to 65535.

相关文章