用枕头像素化图像
Pixelate Image With Pillow
我正在做一个项目,我想拍一张彩色网格的照片作为输入(在这个例子中是用乐高积木制作的)和 return 一张小得多的修改后的照片。
这是一个示例输入:
下面是一张非常小的 8x8 图片,结果如下:
这是预期结果的放大版本::
到目前为止,这是我的代码:
它仅适用于黑白图像。
from PIL import Image
import re
black = [(110,110,110),(0,0,0)] #The highest value and the lowest RGB value for the color black
img = Image.open("input.jpg") #The input image
size = (8,8) #The dimensions of the output image
out = img.resize(size,resample=Image.LANCZOS) #Resize the image
for y in range(size[0]): #loop through every pixel
for x in range(size[1]):
if out.getpixel((x,y)) <= black[0] and out.getpixel((x,y)) >= black[1]: #check to see if the pixel is within the accepted black values
out.putpixel((x,y), (0,0,0)) #Give the current pixel true color
else:
#otherwise make the pixel black
out.putpixel((x,y), (255,255,255)) #Give the current pixel true color
"""Save the pixelated image"""
out.save("output.jpg")
我的代码 return 输出:
我的程序适用于黑白图像,但我需要帮助将其更改为适用于多种颜色(红色、橙色、黄色、浅绿色、深绿色、浅蓝色、深蓝色、紫色、黑色和白色) ).
提前致谢!
你做错了几件事。
首先,您的输出应该使用 PNG,而不是 JPG。 JPG 引入了如此多的伪像,以至于像您的输出这样的小图像完全退化了。
那么,你应该减少你的调色板。使用不含噪声的输入要容易得多。
首先,无聊的初始化:
from PIL import Image
import operator
from collections import defaultdict
import re
input_path = 'input.jpg'
output_path = 'output.png'
size = (4,4)
然后我们声明调色板 - 这应该包含所有可能的乐高积木的颜色。我从您的图像中采样了以下值,但您可以像在代码中那样使用黑白,或者您想要的任何颜色,只要它们与源图像中的颜色相似即可:
palette = [
(45, 50, 50), #black
(240, 68, 64), #red
(211, 223, 223), #white
(160, 161, 67), #green
(233, 129, 76), #orange
]
while len(palette) < 256:
palette.append((0, 0, 0))
下面的代码将为 PIL 声明调色板,因为 PIL 需要平面数组而不是元组数组:
flat_palette = reduce(lambda a, b: a+b, palette)
assert len(flat_palette) == 768
现在我们可以声明一个将保存调色板的图像。稍后我们将使用它来减少原始图像的颜色。
palette_img = Image.new('P', (1, 1), 0)
palette_img.putpalette(flat_palette)
在这里我们打开图像并对其进行量化。我们将其缩放到比需要大八倍的大小,因为我们稍后要对平均输出进行采样。
multiplier = 8
img = Image.open(input_path)
img = img.resize((size[0] * multiplier, size[1] * multiplier), Image.BICUBIC)
img = img.quantize(palette=palette_img) #reduce the palette
在此之后,我们的图像如下所示:
我们需要将其转换回 RGB,以便我们现在可以对像素进行采样:
img = img.convert('RGB')
现在我们要构建我们的最终图像。为此,我们将采样较大图像中每个正方形包含的每种调色板颜色的像素数。然后我们会选择最常出现的颜色。
out = Image.new('RGB', size)
for x in range(size[0]):
for y in range(size[1]):
#sample at get average color in the corresponding square
histogram = defaultdict(int)
for x2 in range(x * multiplier, (x + 1) * multiplier):
for y2 in range(y * multiplier, (y + 1) * multiplier):
histogram[img.getpixel((x2,y2))] += 1
color = max(histogram.iteritems(), key=operator.itemgetter(1))[0]
out.putpixel((x, y), color)
最后,我们保存输出:
out.save(output_path)
结果:
放大 1600%:
为了好玩,我用 ImageMagick 解决了这个问题——它也可以从 Python...
调用
首先,我创建了一个小的自定义调色板来匹配您的颜色 - 您的白色不是很白,您的绿色与 ImageMagick 的绿色想法不同,所以我使用十六进制代替颜色名称。
convert xc:black xc:red xc:"rgb(200,200,200)" xc:"rgb(168,228,23)" xc:orange +append palette.png
如果我将调色板放大,它看起来像这样:
然后我将您的图片缩小到 4x4,并将结果映射到自定义调色板,然后按比例放大,这样您就可以像这样看到它:
convert lego.jpg -resize 4x4! +dither -remap palette.png -scale 1600 result.png
这是结果
白色与原版中的 "white" 不符。
Pixelator 就可以了。这是一个基于 off 或 rr-
s answer 的包。它还为 AI 和 ML 应用程序带来了一些额外的好处。
在bash
pip install pixelator
在python
from pixelator import pixelator
palette = [
(45, 50, 50), #black
(240, 68, 64), #red
(211, 223, 223), #white
(160, 161, 67), #green
(233, 129, 76), #orange
]
sensitivity_multiplier = 10
size = (4,4)
output=pixelator(
in_path='./images/input.jpg',
palette=palette,
size=size,
sensitivity_multiplier=sensitivity_multiplier
)
output.resize_out_img().save_out_img(path='./images/output.jpg', overwrite=True)
我正在做一个项目,我想拍一张彩色网格的照片作为输入(在这个例子中是用乐高积木制作的)和 return 一张小得多的修改后的照片。
这是一个示例输入:
下面是一张非常小的 8x8 图片,结果如下:
这是预期结果的放大版本::
到目前为止,这是我的代码: 它仅适用于黑白图像。
from PIL import Image
import re
black = [(110,110,110),(0,0,0)] #The highest value and the lowest RGB value for the color black
img = Image.open("input.jpg") #The input image
size = (8,8) #The dimensions of the output image
out = img.resize(size,resample=Image.LANCZOS) #Resize the image
for y in range(size[0]): #loop through every pixel
for x in range(size[1]):
if out.getpixel((x,y)) <= black[0] and out.getpixel((x,y)) >= black[1]: #check to see if the pixel is within the accepted black values
out.putpixel((x,y), (0,0,0)) #Give the current pixel true color
else:
#otherwise make the pixel black
out.putpixel((x,y), (255,255,255)) #Give the current pixel true color
"""Save the pixelated image"""
out.save("output.jpg")
我的代码 return 输出:
我的程序适用于黑白图像,但我需要帮助将其更改为适用于多种颜色(红色、橙色、黄色、浅绿色、深绿色、浅蓝色、深蓝色、紫色、黑色和白色) ).
提前致谢!
你做错了几件事。
首先,您的输出应该使用 PNG,而不是 JPG。 JPG 引入了如此多的伪像,以至于像您的输出这样的小图像完全退化了。
那么,你应该减少你的调色板。使用不含噪声的输入要容易得多。
首先,无聊的初始化:
from PIL import Image
import operator
from collections import defaultdict
import re
input_path = 'input.jpg'
output_path = 'output.png'
size = (4,4)
然后我们声明调色板 - 这应该包含所有可能的乐高积木的颜色。我从您的图像中采样了以下值,但您可以像在代码中那样使用黑白,或者您想要的任何颜色,只要它们与源图像中的颜色相似即可:
palette = [
(45, 50, 50), #black
(240, 68, 64), #red
(211, 223, 223), #white
(160, 161, 67), #green
(233, 129, 76), #orange
]
while len(palette) < 256:
palette.append((0, 0, 0))
下面的代码将为 PIL 声明调色板,因为 PIL 需要平面数组而不是元组数组:
flat_palette = reduce(lambda a, b: a+b, palette)
assert len(flat_palette) == 768
现在我们可以声明一个将保存调色板的图像。稍后我们将使用它来减少原始图像的颜色。
palette_img = Image.new('P', (1, 1), 0)
palette_img.putpalette(flat_palette)
在这里我们打开图像并对其进行量化。我们将其缩放到比需要大八倍的大小,因为我们稍后要对平均输出进行采样。
multiplier = 8
img = Image.open(input_path)
img = img.resize((size[0] * multiplier, size[1] * multiplier), Image.BICUBIC)
img = img.quantize(palette=palette_img) #reduce the palette
在此之后,我们的图像如下所示:
我们需要将其转换回 RGB,以便我们现在可以对像素进行采样:
img = img.convert('RGB')
现在我们要构建我们的最终图像。为此,我们将采样较大图像中每个正方形包含的每种调色板颜色的像素数。然后我们会选择最常出现的颜色。
out = Image.new('RGB', size)
for x in range(size[0]):
for y in range(size[1]):
#sample at get average color in the corresponding square
histogram = defaultdict(int)
for x2 in range(x * multiplier, (x + 1) * multiplier):
for y2 in range(y * multiplier, (y + 1) * multiplier):
histogram[img.getpixel((x2,y2))] += 1
color = max(histogram.iteritems(), key=operator.itemgetter(1))[0]
out.putpixel((x, y), color)
最后,我们保存输出:
out.save(output_path)
结果:
放大 1600%:
为了好玩,我用 ImageMagick 解决了这个问题——它也可以从 Python...
调用首先,我创建了一个小的自定义调色板来匹配您的颜色 - 您的白色不是很白,您的绿色与 ImageMagick 的绿色想法不同,所以我使用十六进制代替颜色名称。
convert xc:black xc:red xc:"rgb(200,200,200)" xc:"rgb(168,228,23)" xc:orange +append palette.png
如果我将调色板放大,它看起来像这样:
然后我将您的图片缩小到 4x4,并将结果映射到自定义调色板,然后按比例放大,这样您就可以像这样看到它:
convert lego.jpg -resize 4x4! +dither -remap palette.png -scale 1600 result.png
这是结果
白色与原版中的 "white" 不符。
Pixelator 就可以了。这是一个基于 off 或 rr-
s answer 的包。它还为 AI 和 ML 应用程序带来了一些额外的好处。
在bash
pip install pixelator
在python
from pixelator import pixelator
palette = [
(45, 50, 50), #black
(240, 68, 64), #red
(211, 223, 223), #white
(160, 161, 67), #green
(233, 129, 76), #orange
]
sensitivity_multiplier = 10
size = (4,4)
output=pixelator(
in_path='./images/input.jpg',
palette=palette,
size=size,
sensitivity_multiplier=sensitivity_multiplier
)
output.resize_out_img().save_out_img(path='./images/output.jpg', overwrite=True)