В настоящее время я пытаюсь найти способ:
Прочитайте файл изображения с помощью Python
Прочитайте все значения пикселей как значения HSV
Упорядочить этот массив значений сначала по H
, затем по S
и V
Создайте изображение из этого недавно созданного массива с помощью 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
На самом деле я еще не пробовал OpenCV. Я попробую. Спасибо пока
насколько я понял, cv2.imread на самом деле не содержит информацию о пикселях, а скорее конкретную информацию cv2. Если я ошибаюсь, какая польза от использования cv2 вместо PIL для импорта изображения?
cv2.imread будет содержать информацию о пикселях изображения. Кроме того, вы можете конвертировать цветовые пространства с помощью cv2.cvtColor(). Обратите внимание, что CV2 читает изображения как BGR вместо RGB.
С какой целью это может быть? У вас есть образец ввода и соответствующее ожидаемое выходное изображение, пожалуйста?
Вот код, который, надеюсь, делает то, что вы хотите:
#!/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, чтобы сделать эту информацию визуально доступной. Однако ваш код дает изображение, которое не соответствует ожидаемому результату. Значения пикселей, похоже, работают неправильно. И так как мне не удалось получить правильный код, я не могу предоставить образец изображения. Попробую сделать полегче!
Вы можете попробовать изменить последнюю строку на Image.fromarray(res, mode='HSV').convert('RGB').save('result.png')
Это явно сработало как шарм. Я начну работать над кодом и изображениями. Спасибо, Марк!
Отлично - я рад, что это сработало для вас. Удачи с вашим проектом и помните, что вопросы (и ответы) бесплатны, так что возвращайтесь, если вы снова застряли.
Я обновил код для будущих читателей с исправлением.
Если вы работаете с массивами NumPy, проверяли ли вы OpenCV ? См. cv2.imread , cv2.cvtColor и cv2.imwrite.