python - 我如何在 Python 中读取图像并用定义的像素顺序重写它
问题描述
我目前正在尝试找到一种方法:
使用 Python 读取图像文件
将所有像素值读取为
HSV
值H
首先按,然后按S
和对这个值数组进行排序V
使用 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
解决方案
这是一些希望能满足您要求的代码:
#!/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')
推荐阅读
- python - Pandas Dataframe + Flask,只请求一行
- c++ - 我正在尝试在 cpp 中获取当前日期和时间,但无法理解这些行
- node.js - React / Next,使用passport.js的Express应用程序无需注册即可登录帐户?
- gradle - 所有存储库中的 Gradle 依赖项更新
- c++ - 如果 MPI 程序中的一个进程比其他进程执行得慢怎么办?
- java - 方法的 Java 接口类型声明
- c++ - 分段错误(核心转储) - 二维数组
- python - 我在 numpy 中实现的多通道 1d 卷积有什么问题(与 tensorflow 相比)
- vue.js - 如何在 Vue CLI 中修改 e2e 测试的位置?
- c# - 如何存储从 HTTPPost web api 方法获取的设备令牌