删除图像的抗锯齿 [英] Remove anti-aliasing from an image

查看:64
本文介绍了删除图像的抗锯齿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to remove the antialiasing from an image. This code will get the 4 major colors from an image, compare each pixel to the 4 major colors and assign the closest color.

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")

这是结果:

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

As you can see, the borders between colors aren't perfect.

这是我追求的结果:

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

(it seems the image hosting site compresses the image, and won't show "aliased" image properly)

推荐答案

此处的主要问题位于您的最近的方法中:

The main problem here is located in your closest method:

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

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

Both colors and color become NumPy arrays of type uint8. Now, when subtracting uint8 values, you won't get negative values, but integer underflow will happen, resulting in values near 255. Therefore, the then calculated distances are wrong, which finally leads to the wrong color picking.

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

So, the fastest fix would be to cast both variables to 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的矢量化功能可能会很有用.为您的最接近方法考虑以下方法:

Also, it might be useful to make use of NumPy's vectorization power. Consider the following approach for your closest method:

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])

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

you can simply pass the whole image:

image_nd = closest(four_major_colors, image_nd)

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

Using the given image, I get a speed-up of 100x on my machine. Surely, finding the RGB histogram values can also be optimized. (Unfortunately, my experience with Python dictionaries isn't yet that great...)

无论如何–希望有帮助!

Anyway – hope that helps!

这篇关于删除图像的抗锯齿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆