簡體   English   中英

如何使用NumPy有效地給大型灰度圖像上色(在一組RGBA色點之間混合)

[英]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秒):

當前代碼對於512x512圖像足夠有效

但對於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM