使用numpy高效地将16位图像数据转换为8位进行显示,并进行强度缩放
我经常将16位灰度图像数据转换为8位图像数据,以便
显示。调整最小和最大显示几乎总是有用的
强调图像中“有趣”部分的强度。
下面的代码大致实现了我想要的功能,但它既丑陋又低效,而且
生成图像数据的多个中间副本。
import numpyimage_data = numpy.random.randint( #Realistic images would be much larger
low=100, high=14000, size=(1, 5, 5)).astype(numpy.uint16)
display_min = 1000
display_max = 10000.0
print(image_data)
threshold_image = ((image_data.astype(float) - display_min) *
(image_data > display_min))
print(threshold_image)
scaled_image = (threshold_image * (255. / (display_max - display_min)))
scaled_image[scaled_image > 255] = 255
print(scaled_image)
display_this_image = scaled_image.astype(numpy.uint8)
print(display_this_image)
回答:
你要做的是半色调你的
形象。
其他人提出的方法效果很好,但它们重复了很多次一次又一次的昂贵计算。因为在“uint16”中
大多数65536个不同的值,使用查找表(LUT)可以简化很多事情。既然LUT很小,你就不用担心那么多
关于就地操作,或者不创建布尔数组。以下代码重用Bi-Rico的函数来创建LUT:
import numpy as npimport timeit
rows, cols = 768, 1024
image = np.random.randint(100, 14000,
size=(1, rows, cols)).astype(np.uint16)
display_min = 1000
display_max = 10000
def display(image, display_min, display_max): # copied from Bi Rico
# Here I set copy=True in order to ensure the original image is not
# modified. If you don't mind modifying the original image, you can
# set copy=False or skip this step.
image = np.array(image, copy=True)
image.clip(display_min, display_max, out=image)
image -= display_min
np.floor_divide(image, (display_max - display_min + 1) / 256,
out=image, casting='unsafe')
return image.astype(np.uint8)
def lut_display(image, display_min, display_max) :
lut = np.arange(2**16, dtype='uint16')
lut = display(lut, display_min, display_max)
return np.take(lut, image)
>>> np.all(display(image, display_min, display_max) ==
lut_display(image, display_min, display_max))
True
>>> timeit.timeit('display(image, display_min, display_max)',
'from __main__ import display, image, display_min, display_max',
number=10)
0.304813282062
>>> timeit.timeit('lut_display(image, display_min, display_max)',
'from __main__ import lut_display, image, display_min, display_max',
number=10)
0.0591987428298
So there is a x5 speed-up, which is not a bad thing, I guess…
以上是 使用numpy高效地将16位图像数据转换为8位进行显示,并进行强度缩放 的全部内容, 来源链接: utcz.com/qa/414282.html