Как я могу прочитать изображение в Python и переписать его с определенным порядком пикселей

В настоящее время я пытаюсь найти способ:

  1. Прочитайте файл изображения с помощью Python

  2. Прочитайте все значения пикселей как значения HSV

  3. Упорядочить этот массив значений сначала по H, затем по S и V

  4. Создайте изображение из этого недавно созданного массива с помощью numpy.

Если бы кто-нибудь мог указать мне в правильном направлении, я был бы очень благодарен.

Редактировать 1:

Я попробовал некоторый код, и он дает результат, но не тот, который ожидался. Я предполагаю, что np.sort сортирует кортежи в целом, а не по одному из столбцов. Может быть у кого-то есть идея, как это решить.

import glob
from PIL import Image, ImageDraw
import numpy as np
import os
import colorsys

#definition of HSL/HSV colorspace
def hsl(x):
        to_float = lambda x : x / 255.0
        (r, g, b) = map(to_float, x)
        h, s, l = colorsys.rgb_to_hsv(r,g,b)
        h = h if 0 < h else 1 # 0 -> 1
        return h, s, l


#get the image filenames
images = glob.glob("test/*.jpg")
print(images)


#output_folder generation
output_folder = 'test/out_new'
if not os.path.exists(output_folder):
    os.makedirs(output_folder)


#loop through all image filenames
for image in images:
    #load the current image
    im = Image.open(image) 
    
    #get a tuple of the x and y dimensions of the image
    width, height = im.size

    # creating empty img-array with same dimensions
    data = np.zeros((height, width, 3), dtype=np.uint8)
    #load the pixel info of image
    pix = im.load()
    width, height = im.size # get original size for processing

    img_filename = os.path.splitext(image)[0]+'_sorted.jpg'
    img_filename = os.path.split(img_filename)[1]
    img_filename = os.path.join(output_folder, img_filename)

        
    dataset = {}

    for x in range(width):
        for y in range(height):
            h = (pix[x,y][0])
            s = (pix[x,y][1])
            l = (pix[x,y][2])
            #make a unique id for this color to use as key
            uid = f'{h},{s},{l}'
        

            # use h,s,l pixel output for image. switched axis due to bug in 
            data[y][x] = [h, s, l]
            # uncomment for r,g,b pixel output for image
            #data[y][x] = [r, g, b]

            if not uid in dataset:
                dataset[uid] = 0
            #count one up for this key
            dataset[uid] += 1

         

    # sort pixel 
    data_sorted = np.sort(data, axis=0)
    # create image
    newimage = Image.fromarray(data_sorted)
    #newimage = Image.fromarray(data)
    # save image
    newimage.save(img_filename)

Редактировать 2: Предоставленный кодовый знак, к сожалению, не дает ожидаемого результата. Изображение, созданное кодом, должно содержать пиксели того же цвета, что и исходное изображение, но в отсортированном виде. Таким образом, каждый цвет оригинала должен быть виден. Я делаю все это, чтобы создать способ (квази) визуализации трех измерений массива H, S и V в двухмерном изображении.

Исходное изображение [1]: https://i.stack.imgur.com/hmiOE.jpg

Изображение, созданное кодом Marks [2]: https://i.stack.imgur.com/foHGC.jpg

Большое спасибо за ответы!

Код Marks на самом деле делает то, что должен делать, если я выполняю преобразование в HSV. Пример прилагается.

Отсортированные значения RGB [3]: https://i.stack.imgur.com/WWiY1.jpg

Если вы работаете с массивами NumPy, проверяли ли вы OpenCV ? См. cv2.imread , cv2.cvtColor и cv2.imwrite.

HansHirse 15.12.2020 12:27

На самом деле я еще не пробовал OpenCV. Я попробую. Спасибо пока

Soeren Sebastian Frell 15.12.2020 13:45

насколько я понял, cv2.imread на самом деле не содержит информацию о пикселях, а скорее конкретную информацию cv2. Если я ошибаюсь, какая польза от использования cv2 вместо PIL для импорта изображения?

Soeren Sebastian Frell 15.12.2020 20:57

cv2.imread будет содержать информацию о пикселях изображения. Кроме того, вы можете конвертировать цветовые пространства с помощью cv2.cvtColor(). Обратите внимание, что CV2 читает изображения как BGR вместо RGB.

nablag 15.12.2020 22:09

С какой целью это может быть? У вас есть образец ввода и соответствующее ожидаемое выходное изображение, пожалуйста?

Mark Setchell 16.12.2020 00:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
282
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот код, который, надеюсь, делает то, что вы хотите:

#!/usr/bin/env python3

import numpy as np
from PIL import Image

# Load image and convert to HSV
im = Image.open('image.png').convert('HSV')

# Convert to Numpy array and reshape to column vector of HSV pixels
pv = np.array(im).reshape(-1,3)

# Sort by H, S, V and convert back to original shape
res = pv[np.lexsort((pv[:,2], pv[:,1],pv[:,0]))]
res = res.reshape((im.height,im.width,3))

# Convert back to PIL Image, back to RGB and save
Image.fromarray(res, mode='HSV').convert('RGB').save('result.png')

Эй, Марк, большое спасибо за код. В настоящее время я работаю над проектом по архитектурной визуализации (фактические архитектурные образы зданий) и хотел бы попробовать способы объективации изображений. Одним из способов может быть сортировка пикселей изображения по их значениям H, S и V, чтобы сделать эту информацию визуально доступной. Однако ваш код дает изображение, которое не соответствует ожидаемому результату. Значения пикселей, похоже, работают неправильно. И так как мне не удалось получить правильный код, я не могу предоставить образец изображения. Попробую сделать полегче!

Soeren Sebastian Frell 17.12.2020 07:56

Вы можете попробовать изменить последнюю строку на Image.fromarray(res, mode='HSV').convert('RGB').save('result.png')

Mark Setchell 17.12.2020 08:56

Это явно сработало как шарм. Я начну работать над кодом и изображениями. Спасибо, Марк!

Soeren Sebastian Frell 17.12.2020 10:02

Отлично - я рад, что это сработало для вас. Удачи с вашим проектом и помните, что вопросы (и ответы) бесплатны, так что возвращайтесь, если вы снова застряли.

Mark Setchell 17.12.2020 10:07

Я обновил код для будущих читателей с исправлением.

Mark Setchell 17.12.2020 10:07

Другие вопросы по теме