首页 > 解决方案 > 我如何在 Python 中读取图像并用定义的像素顺序重写它

问题描述

我目前正在尝试找到一种方法:

  1. 使用 Python 读取图像文件

  2. 将所有像素值读取为HSV

  3. H首先按,然后按S和对这个值数组进行排序V

  4. 使用 numpy 从这个新制作的 Array 制作图像。

如果有人能指出我正确的方向,我将非常感激。

编辑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

非常感谢您到目前为止的答案!

标记代码实际上做了它应该做的事情,如果我将转换为 HSV 的话。附上一个例子。

排序后的 RGB 值 [3]:https ://i.stack.imgur.com/WWiY1.jpg

标签: pythonnumpypython-imaging-library

解决方案


这是一些希望能满足您要求的代码:

#!/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')

推荐阅读