Как я могу объединить три 2D-массива, которые содержат значения оттенка, насыщенности и интенсивности в своих соответствующих массивах и отображать это как изображение? - PullRequest
0 голосов
/ 06 января 2019

Я новичок в обработке изображений и Python. Как вы можете видеть из моего кода, мне удалось преобразовать мое изображение RGB в HSI, используя различные формулы, которые я нашел.

Я сохранил значения оттенка, насыщенности и интенсивности в трех разных массивах. Это также в коде ниже. Как я могу объединить эти три массива и отобразить объединенное изображение как изображение?

import math 
from PIL import Image
img = Image.open("D:\\Texture analysis\\trees-clolorful-aerial-view-wallpaper.jpg")

rgb_img = img.convert('RGB')

row, col = img.size

print(row, col)

i = j = 0

satValue = 0 
inValue = 0 
hueValue = 0

squareValue = 0

hueArray = [[0 for x in range(row)] for y in range(col)]
satArray = [[0 for x in range(row)] for y in range(col)] 
inArray = [[0 for x in range(row)] for y in range(col)]

division = 0 
denominator = 0 
numerator = 0 
radAngle = 0 
degAngle = 0 
product = 0 
sqr = 0 
count = 0 
uCount = 0

while i < row:
    j = 0
    while j < col:
        red, green, blue = rgb_img.getpixel((i, j))

        hRed = sRed = iRed = red
        hGreen = sGreen = iGreen = green
        hBlue = sBlue = iBlue = blue

# =========================Saturation Calculation==============================
        if sRed == 0 and sGreen == 0 and sBlue == 0:
            satValue = 0
            satArray[i][j] = 0
        else:
            if (sRed < sGreen) and (sRed < sBlue):
                satValue = 1 - (((3) * (sRed)) / (sRed + sGreen + sBlue))
                satArray[i][j] = satValue
    #            print(satValue)
            elif (sGreen < sRed) and (sGreen < sBlue):
                satValue = 1 - (((3) * (sGreen)) / (sRed + sGreen + sBlue))
                satArray[i][j] = satValue
    #            print(satValue)
            else:
                satValue = 1 - (((3) * (sBlue)) / (sRed + sGreen + sBlue))
                satArray[i][j] = satValue
    #            print(satValue)
# =============================================================================

# ==========================Intensity Calculation==============================
        inValue = (iRed + iGreen + iBlue) / 3
        inArray[i][j] = inValue
        count += 1
        print(inValue, count)
# =============================================================================    

# =============================Hue Calculation=================================
        product = (hRed - hBlue) * (hGreen - hBlue)

        sqr = (hRed - hGreen) * (hRed - hGreen)
        denominator = math.sqrt(sqr + product)

        if denominator != 0:
            numerator = ((hRed - hGreen) + (hRed - hBlue)) / 2
            division = numerator / denominator

            radAngle = math.acos(division)
            degAngle = math.degrees(radAngle)

            if hBlue <= hGreen:
                hueValue = degAngle
                hueArray[i][j] = hueValue
            elif hBlue > hGreen:
                hueValue = 360 - degAngle
                hueArray[i][j] = hueValue
        elif denominator == 0:
            hueValue = 0
            hueArray[i][j] = hueValue
        #print(hueValue, count)
# =============================================================================

        j += 1
    i += 1 print(i, j)

PS. В будущем вы также увидите много моего любительского кода: D

1 Ответ

0 голосов
/ 07 января 2019

Теперь я вижу, что происходит, я снова за компьютером. Вы, наверное, пробовали это:

#!/usr/bin/env python3

from PIL import Image

img    = Image.open('start.png')
hsvimg = img.convert('HSV')
hsvimg.save('result.png')

И если вы это сделаете, вы получите сообщение об ошибке:

OSError: cannot write mode HSV as PNG

потому что PNG-изображения всегда находятся в цветовом пространстве sRGB, поэтому корректно отказывается записывать ваше HSV-изображение. Дело в том, что преобразование цветового пространства действительно сработало, а значения на изображении - это те значения HSV, которые вам нужны. Вы можете проверить это с помощью:

img.getpixel((X,Y))

и

hsvimg.getpixel((X,Y))

, где X и Y - любые произвольные координаты, которые вам нравятся. Вы увидите, что последний всегда является правильным представлением HSV цвета RGB первого.

Я не уверен, что вы пытаетесь делать в целом, поэтому я не могу по-настоящему посоветовать, но одну вещь, которую вы могли бы сделать, это "лежать сквозь зубы" и сказать PIL / Pillow, что изображение RGB, хотя вы знаете, что это HSV. Так что если вы делаете:

hsvimg = img.convert('HSV')
hsvimg.mode='RGB'               # Tell PIL image is RGB
hsvimg.save('result.png')

оно сохранит изображение, но оно, как и все другие зрители, покажет ваш оттенок синим, насыщенность зеленым и значение голубым.

Я предполагаю, что у вас есть другая обработка, и это только промежуточный аспект вашей обработки, так что, вероятно, это не будет иметь значения, и вы, вероятно, сможете продолжить и выполнить свою обработку и преобразовать обратно в конце и сохранить в файл PNG sRGB без необходимости врать.


Отвечая на ваш актуальный вопрос, вы можете разделить и объединить такие каналы с помощью PIL / Pillow:

# Split and recombine with PIL
r,g,b  = img.split()
merged = Image.merge(mode='RGB',bands=(r,g,b)))

Или, если вы предпочитаете Numpy, который часто быстрее:

# Open image as Numpy array
img = np.array(Image.open('start.png'))
# Split into 3 channels/arrays/bands
r = img[:, :, 0]
g = img[:, :, 1]
b = img[:, :, 2]
# Recombine to single image
merged = np.dstack((r, g, b))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...