删除图像的抗锯齿

时间:2019-11-29 11:50:15

标签: python numpy image-processing python-imaging-library antialiasing

我想从图像中删除抗锯齿。此代码将从图像中获取4种主要颜色,将每个像素与4种主要颜色进行比较,然后分配最接近的颜色。

import numpy as np
from PIL import Image

image = Image.open('pattern_2.png')
image_nd = np.array(image)
image_colors = {}

for row in image_nd:
    for pxl in row:
        pxl = tuple(pxl)
        if not image_colors.get(pxl):
            image_colors[pxl] = 1
        else:
            image_colors[pxl] += 1

sorted_image_colors = sorted(image_colors, key=image_colors.get, reverse=True)
four_major_colors = sorted_image_colors[:4]


def closest(colors, color):
    colors = np.array(colors)
    color = np.array(color)
    distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))
    index_of_smallest = np.where(distances == np.amin(distances))
    smallest_distance = colors[index_of_smallest]
    return smallest_distance[0]


for y, row in enumerate(image_nd):
    for x, pxl in enumerate(row):
        image_nd[y, x] = closest(four_major_colors, image_nd[y, x])

aliased = Image.fromarray(image_nd)
aliased.save("pattern_2_al.png")

这是结果:
enter image description here

如您所见,颜色之间的边界并不完美。

这是我追求的结果:

enter image description here

(图片托管网站似乎压缩了图片,并且无法正确显示“混淆”图片)

1 个答案:

答案 0 :(得分:3)

这里的主要问题位于您的closest方法中:

def closest(colors, color):
    colors = np.array(colors)
    color = np.array(color)
    distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))

colorscolor都成为uint8类型的NumPy数组。现在,当减去uint8值时,您将不会得到负值,但是将发生整数下溢,从而导致值接近255。因此,然后计算出的distances是错误的,最终导致错误的颜色选择。

因此,最快的解决方法是将两个变量都转换为int32

def closest(colors, color):
    colors = np.array(colors).astype(np.int32)
    color = np.array(color).astype(np.int32)
    distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))

此外,利用NumPy的矢量化功能可能会很有用。为您的closest方法考虑以下方法:

def closest(colors, image):
    colors = np.array(colors).astype(np.int32)
    image = image.astype(np.int32)
    distances = np.argmin(np.array([np.sqrt(np.sum((color - image) ** 2, axis=2)) for color in colors]), axis=0)
    return colors[distances].astype(np.uint8)

所以,与其使用

迭代所有像素,
for y in np.arange(image_nd.shape[0]):
    for x in np.arange(image_nd.shape[1]):
        image_nd[y, x] = closest(four_major_colors, image_nd[y, x])

您可以简单地传递整个图像:

image_nd = closest(four_major_colors, image_nd)

使用给定的图像,我的机器的速度提高了100倍。当然,找到RGB直方图值也可以进行优化。 (不幸的是,我对Python词典的经验还不是很好...)

无论如何-希望能有所帮助!

相关问题