[英]How to colourize (blending between a set of RGBA colour points) large grayscale images efficiently using NumPy
我做了一个配方来着色并为灰度图像添加一个Alpha通道。 这是我第一次尝试使用numpy。 它具有0.3兆像素测试图像的效率(在我的1.8GHz机器上仅需2.3秒):
但对于7兆像素的图像,它太慢了(每张图像更像一分钟)。 如何提高代码效率? 它为每个图像制作256 numpy蒙版,我想这可能不是最好的方法。
#!/usr/bin/env python3
from PIL import Image
import numpy
# a test image is loaded and converted to a numpy array
img = Image.open( 'lena.jpg' ).convert( 'RGBA' )
img = numpy.array( img )
# color point objects represent how pixels with a specific luminescence are to colourized
class ColorPoint():
def __init__( self, luminescence=0, red=0, green=0, blue=0, alpha=255 ):
self.luminescence = luminescence
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
# colour points are stored in a list, defining the colorization
color_points = []
color_points += [ ColorPoint( luminescence=0, red=255 ) ]
color_points += [ ColorPoint( luminescence=85, green=255 ) ]
color_points += [ ColorPoint( luminescence=170, blue=255 ) ]
color_points += [ ColorPoint( luminescence=255, alpha=0 ) ]
if color_points[0].luminescence!=0 or color_points[-1].luminescence!=255:
print( 'color points do not span full luminescence range!' )
sys.exit()
# red, green and blue, alpha values are read in from the numpy array
red, green, blue, alpha = img[:,:,0], img[:,:,1], img[:,:,2], img[:,:,3]
for luminescence in range( 256 ):
# the luminescence value is either equal to that of a colour point or falls inbetween two
cp = next((x for x in color_points if x.luminescence==luminescence), None)
if( cp ):
# the current luminescence value matches a color point exactly
new_red = cp.red
new_green = cp.green
new_blue = cp.blue
new_alpha = cp.alpha
else:
# find the color points which the the current luminescence value lies between
start_cp = next((x for x in reversed(color_points) if x.luminescence<luminescence), None)
end_cp = next((x for x in color_points if x.luminescence>luminescence), None)
# this factor represents the position between the two colour points
factor = ( luminescence - start_cp.luminescence ) / ( end_cp.luminescence - start_cp.luminescence )
# new RGBA values are set based on the two colour points and the position between the two
new_red = start_cp.red + (end_cp.red-start_cp.red)*factor
new_green = start_cp.green + (end_cp.green-start_cp.green)*factor
new_blue = start_cp.blue + (end_cp.blue-start_cp.blue)*factor
new_alpha = start_cp.alpha + (end_cp.alpha-start_cp.alpha)*factor
# a mask is created for the current luminescence value used to apply the new values
mask = ( red == luminescence ) & ( green == luminescence ) & ( blue == luminescence )
img[:,:,:4][mask] = [ new_red, new_green, new_blue, new_alpha ]
# convert back to PIL image and show
img = Image.fromarray( img )
img.show()
您应该能够使用插值例程之一,例如griddata
。 这是一个示例,其中我使用了一个随机查询表,该表与您代码中的color_points
相对应。
>>> from scipy.interpolate import griddata
>>> LUT = np.random.random_sample((256, 3))
>>> griddata(np.arange(256), LUT, image)
要在您的代码中使用它,您将需要使用灰度/发光值构建一个1d数组,并使用相应的rgb值构建另一个2d
数组。 这是griddata
的前两个参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.