使用numpy高效地将16位图像数据转换为8位进行显示,并进行强度缩放

我经常将16位灰度图像数据转换为8位图像数据,以便

显示。调整最小和最大显示几乎总是有用的

强调图像中“有趣”部分的强度。

下面的代码大致实现了我想要的功能,但它既丑陋又低效,而且

生成图像数据的多个中间副本。

import numpy

image_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 np

import 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

回到顶部