我有一张城市的图像,颜色不连续(绿色=草地,黑色=建筑物,白色/黄色=道路)。使用Pillow,我将图片导入(Python)程序中,并将其转换为具有离散颜色值的Numpy数组(即,绿色像素变为1,黑色像素变为2,等等)。
我想降低图像的分辨率(出于计算目的),同时保留尽可能多的信息。但是,使用Pillow的resize()方法,颜色会偏离这些离散值。如何缩小图像的尺寸(最重要的是)保留离散的颜色,同时又要丢失尽可能少的信息(同样重要)?
以下是图片示例:https://i.imgur.com/6Tef55H.png
编辑:每个请求,一些代码:
from PIL import Image
import Numpy as np
picture = Image.open(some_image.png)
width, height = picture.size
pic_array = np.zeros(width,height)
# Turn the image into discrete values
for i in range(0,width):
for j in range(0,height):
red, green, blue = picture.getpixel((i,j))
if red == a and green == b and blue == c:
#An example of how discrete colors are converted to values
pic_array[i][j] = 1
缩放可以通过两种方式完成:
1)使用Pillow的调整大小库缩放原始图像,或者 2)使用以下方法重新缩放最终数组:
scaled_array = pic_array[0:width:5, 0:height,5]
就保留信息而言,选项1很好,但是丢失了离散值,而选项2则相反。
答案 0 :(得分:1)
我对此问题感兴趣,并写了一些代码来尝试一些想法-特别是@jasonharper在评论中建议的“模式”过滤器。因此,我对其进行了编程。
首先输入的图像不是4个定义明确的类,但实际上有6,504种不同的颜色,因此我使用 ImageMagick 制作了4种颜色的调色板,如下所示:
magick xc:black xc:white xc:yellow xc:green +append palette.png
此处放大了-实际上是4x1像素:
然后我将图像中的颜色映射到4种离散颜色的调色板:
magick map.png +dither -remap palette.png start.png
然后我尝试使用此代码来计算每个3x3窗口的中位数和众数:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
from scipy import stats
from skimage.util import view_as_blocks
# Open image and make into Numpy array
im = Image.open('start.png')
na = np.array(im)
# Make a view as 3x3 blocks - crop anything not a multiple of 3
block_shape=(3,3)
view = view_as_blocks(na[:747,:], block_shape)
flatView = view.reshape(view.shape[0], view.shape[1], -1) # now (249,303,9)
# Get median of each 3x3 block
resMedian = np.median(flatView, axis=2).astype(np.uint8)
Image.fromarray(resMedian*60).save('resMedian.png') # arbitrary scaling by 60 for contrast
# Get mode of each 3x3 block
resMode = stats.mode(flatView, axis=2)[0].reshape((249,303)).astype(np.uint8)
Image.fromarray(resMode*60).save('resMode.png') # arbitrary scaling by 60 for contrast
这是中值过滤器的结果:
这是“模式”过滤器的结果,确实更好,恕我直言:
以下是动画对比:
如果有人想获取代码并将其修改为尝试新的想法,请放心!