读取图像并用最接近的颜色近似和重建每个像素?

0 投票
2 回答
780 浏览
提问于 2025-04-16 16:35

我在找一种方法,可以从一张图片中获取像素,然后在另一个程序中找到最接近的颜色(我可以把它编译到“另一个程序”的源代码里;如果不需要注入源代码就能兼容,那就太好了),然后用这个颜色填充到正确的像素上。简单来说,就是一个脚本/代码/可执行文件,接收一张图片文件,然后用最接近的颜色重新创建每个像素。我说的这个程序是《粉末玩具》(The Powder Toy,网址是powdertoy.co.uk)。如果你知道这个程序,我是出于私人目的和概念验证在用它,因为“公共存档”里不能有CGI。那里的一个用户JoJoBond被允许这样做,因为他/她是第一个做到的。

2 个回答

1

也许可以使用 scipy.cluster.vq.vq 来对图像进行量化处理:

import numpy as np
import scipy.cluster.vq as vq
import Image
import random

img = Image.open('cartoon.png').convert('RGB')
arr = np.asarray(img)
shape_orig = arr.shape

# make arr a 2D array
arr = arr.reshape(-1,3)

# create an array of all the colors in the image
palette=np.unique(arr.ravel().view([('r',np.uint8),('g',np.uint8),('b',np.uint8)]))
# randomly select 50 colors from the palette
palette=palette[random.sample(range(len(palette)),50)]

# make palette a 2D array
palette=palette.view('uint8').reshape(-1,3)

# Quantize arr to the closet color in palette
code,dist=vq.vq(arr,palette)
arr_quantized=palette[code]

# make arr_quantized have the same shape as arr
arr_quantized=arr_quantized.reshape(shape_orig)
img_new=Image.fromarray(arr_quantized)
img_new.save('/tmp/cartoon_quantized.png')

以 cartoon.png 为例:

这里输入图片描述

上面的代码会生成 cartoon_quantized.png:

这里输入图片描述

注意:我对如何定义接近的颜色并不是很了解。

上面的代码使用 vq.vq 来选择调色板中与给定图像颜色最接近的颜色,具体是通过计算颜色之间的欧几里得距离来实现的。其实我不太确定,甚至有点怀疑,使用欧几里得距离来处理 RGB 颜色值是否是定义接近颜色的最佳方法。

你可能想要选择一种不同于 RGB 的颜色系统,甚至可能需要使用不同于欧几里得距离的度量方式。可惜的是,我不确定如果需要不同的度量方式,是否还能使用 vq.vq...

1

你可以使用Python图像库来加载一张图片,并提取出每个像素的颜色值:

import Image

img = Image.open('random.png')
width, height = img.size
pixels = img.getdata()
print 'pixels:'
for i, px in enumerate(img.getdata()):

    # decide whether to replace this pixel

    # call out to external program to translate color value
    r, g, b = px
    npx = (b, g, r)

    # replace pixel with new color value        
    y = i / width
    x = i % width
    img.putpixel((x, y), npx)

    print px, npx

输出结果:

pixels:
(58, 0, 0) (0, 0, 58)
(0, 0, 0) (0, 0, 0)
(0, 0, 4) (4, 0, 0)
(0, 0, 0) (0, 0, 0)
(0, 0, 0) (0, 0, 0)
(0, 245, 0) (0, 245, 0)
(0, 0, 0) (0, 0, 0)
(0, 0, 0) (0, 0, 0)
(14, 0, 0) (0, 0, 14)
...

撰写回答