Преобразование Numpy 3D-массива в 3 шестнадцатеричные строки R, G, B - PullRequest
0 голосов
/ 13 июля 2020

У меня есть большие списки, содержащие значения RGB для изображений. Я использую numpy для создания узоров и / или подушек для загрузки изображений и преобразования их в массивы 3D- numpy (int32). Теперь я хочу реструктурировать свой массив в шестнадцатеричные строки странным образом: три шестнадцатеричные строки для R, G, B в этой структуре: '0000FFFF', где первые 4 символа всегда должны быть нулевыми, затем 2 символа представляют пиксель n + 1 и последние 2 символа представляют пиксель n. Я уже сделал это с помощью кода, который занимает слишком много времени для больших изображений, и мне нужно некоторое улучшение. Что я получил на данный момент:

import numpy
import numpy.matlib
#from matplotlib.colors import rgb2hex
import time

def pairwise(iterable):
    """Create a paired-list from a list."""
    a = iter(iterable)
    return zip(a, a)

def test(imgSize=[480,640], brightness=[255,255,255]):
    
    #generate pattern
    startPattern = time.time()
    patternDescription = 'Stripe Test'
    pattern = numpy.zeros((imgSize[0], imgSize[1], 3))
    line = (numpy.r_[:imgSize[1]]%255)/255
    colorChR = numpy.matlib.repmat(line, imgSize[0], 1)
    colorChG = numpy.matlib.repmat(line, imgSize[0], 1)
    colorChB = numpy.matlib.repmat(line, imgSize[0], 1)
    colorChR[:, :] = 0
    colorChR[:, 0:60] = 1
    colorChG[:, :] = 0
    colorChG[:, 0:60] = 1
    colorChB[:, :] = 0
    colorChB[:, 0:60] = 1
    pattern[:, :, 0] = colorChR
    pattern[:, :, 1] = colorChG
    pattern[:, :, 2] = colorChB
    stopPattern = time.time()
    print('TIME: Pattern generation:  ' + str(round(stopPattern-startPattern,3)) + ' s. ')
    # first reshape
    startReshape = time.time()
    pattern[:, :, 0] = pattern[:, :, 0]*brightness[0] # red brightness multiplicator
    pattern[:, :, 1] = pattern[:, :, 1]*brightness[1] # green brightness multiplicator
    pattern[:, :, 2] = pattern[:, :, 2]*brightness[2] # blue brightness multiplicator
    
    img = pattern.astype(int)
    
    # IDEALLY I WANT TO CHANGE THE CODE ONLY FROM HERE ON


    # redValues = pattern[:,:,0].astype(int)
    # greenValues = pattern[:,:,1].astype(int)
    # blueValues = pattern[:,:,2].astype(int)
    
    
#     test = ("0000" + ("{:0>2X}" * len(redValues))).format(*tuple(redValues[::-1]))
    
#     numpy.set_printoptions(formatter={'int':hex})
    
#     #test = [ rgb2hex(img[i,:]) for i in range(img.shape[0]) ]
#     rgb2hex = lambda r,g,b: '%02X%02X%02X' %(r,g,b)
#     test = [ rgb2hex(*img[i,:]) for i in range(img.shape[0]) ]
# #    img = numpy.array2string(img, formatter = {'int':lambda img: hex(img)})
    imgReshape = numpy.reshape(img, (1, imgSize[0]*imgSize[1]*3)) #necessary?
    redValues = imgReshape[0][0::3] #red values (0, 3, 6, ..)
    greenValues = imgReshape[0][1::3] #green values (1, 4, 7, ..)
    blueValues = imgReshape[0][2::3] #blue values (2, 5, 8, ..)
    stopReshape = time.time()
    print('TIME: Reshape into colors: ' + str(round(stopReshape-startReshape,3)) + ' s. ')
    
    
    redString = ''
    greenString = ''
    blueString = ''
    outData = dict()
    startString = time.time()

    for i, j in pairwise(redValues):
        tempRed = "0000%02X%02X" % (int(j), int(i))
        redString += tempRed
        
    for i, j in pairwise(greenValues):
        tempGreen = "0000%02X%02X" % (int(j), int(i))
        greenString += tempGreen
        
    for i, j in pairwise(blueValues):
        tempBlue = "0000%02X%02X" % (int(j), int(i))
        blueString += tempBlue

    outData['red'] = redString
    outData['green'] = greenString
    outData['blue'] = blueString
    stopString = time.time()
    print('TIME: String formatting:   ' + str(round(stopString-startString, 3)) + ' s')
    print('DATATEST: First 200 red chars: ' + str(outData['red'][0:200]))
    print('DATATEST: First 200 green chars: ' + str(outData['green'][0:200]))
    print('DATATEST: First 200 blue chars: ' + str(outData['blue'][0:200]))
    #return outData

1 Ответ

1 голос
/ 13 июля 2020

Попробуйте вместо этого использовать массив numpy:

redValues = np.random.randint(0, 255, (10, 2))

red = np.array(redValues).reshape(-1, 2)
red_channel = (red[:, 1] << 8) + red[:, 0]

redString = ''.join(map(lambda val: f'0000{val:04x}', red_channel))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...