首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >黑白图像像素化

黑白图像像素化
EN

Code Review用户
提问于 2016-01-17 12:18:00
回答 1查看 1.1K关注 0票数 4

我正在做一个功能,像素黑白图像。函数必须被称为pixelate(img, (pixel_width, pixel_height), mode)

参数(pixel_width, pixel_height)是一个元组,它指示结果像素值的大小。函数必须在任何情况下返回结果,即使它们高于图像维数。如果图像大小不是像素大小的倍数,则一些结果像素的大小将小于(pixel_width, pixel_height)。这个较小的像素将位于图像的右侧和底部边缘,如下面的示例所示。换句话说,像素总是从图像的左上角开始。

参数模式是字符串、'min‘、'max’或‘平均值’。如果我们想要计算新图像像素所在区域的平均值,我们将写“平均值”。我们会写'max‘,如果我们想要最亮的值或最黑暗的'min’。如果平均值有小数,我们将只使用整数部分。

现在我已经完成了程序,但我想写尽可能短的代码,使用尽可能少的CPU内存和时间。

代码语言:javascript
复制
from PIL import Image

import numpy as np

def pixelate_mode(mode):
    if mode == 'mean':
        return np.mean
    elif mode == 'min':
        return min
    elif mode == 'max':
        return max

def pixelate(img, (pixel_width, pixel_height), mode):
    width, height = img.size
    W = 0
    while W * pixel_width < width:
        H = 0
        while H * pixel_height < height:
            l = []
            for x in xrange(pixel_width * W, pixel_width * (W + 1)):
                for y in xrange(pixel_height * H, pixel_height * (H + 1)):
                    if x < width and y < height:
                        l.append(img.getpixel((x, y)))
            color = pixelate_mode(mode)(l)
            for x in xrange(pixel_width * W, pixel_width * (W + 1)):
                for y in xrange(pixel_height * H, pixel_height * (H + 1)):
                    if x < width and y < height:
                        img.putpixel((x, y), color)
            H += 1
        W += 1
    return img

下面是一些将程序应用于这个映像的例子:它有200×200像素,每平方图像10×10像素。

pixelate(img, (10, 10), 'mean')pixelate(img, (5, 5), 'max')pixelate(img, (2, 2), 'min')pixelate(img, (1, 1), 'mean')返回相同的图像。

pixelate(img, (11, 11), 'mean')返回

EN

回答 1

Code Review用户

回答已采纳

发布于 2016-01-17 18:04:34

简单优化

与在嵌套循环中执行color = pixelate_mode(mode)(l)不同,您可以在函数开始时计算一次modefunc = pixelate_mode(mode),然后根据需要调用modefunc(l)

其他优化

与检查xy是否在范围内不同,您只需生成它们,使它们始终在范围内:

代码语言:javascript
复制
l = []
for x in xrange(pixel_width * W, min(width, pixel_width * (W + 1))):
    for y in xrange(pixel_height * H, min(height, pixel_height * (H + 1))):
        l.append(img.getpixel((x, y)))
color = modefunc(l)
for x in xrange(pixel_width * W, min(width, pixel_width * (W + 1))):
    for y in xrange(pixel_height * H, min(height, pixel_height * (H + 1))):
        img.putpixel((x, y), color)

此外,对于更优化的版本,您只能计算一次限制:

代码语言:javascript
复制
minx, maxx = pixel_width * W, min(width, pixel_width * (W + 1))
miny, maxy = pixel_height * H, min(height, pixel_height * (H + 1))
l = []
for x in xrange(minx, maxx):
    for y in xrange(miny, maxy):
        l.append(img.getpixel((x, y)))
color = modefunc(l)
for x in xrange(minx, maxx):
    for y in xrange(miny, maxy):
        img.putpixel((x, y), color)

列表表达式

您可以使用列表表达式来定义l。更好的是,您根本不需要l作为列表,只需使用生成器表达式(编辑:显然这对np.array不起作用,所以您必须无论如何构建字符串,可能是使用多个append__s或使用列表理解)。

代码语言:javascript
复制
minx, maxx = pixel_width * W, min(width, pixel_width * (W + 1))
miny, maxy = pixel_height * H, min(height, pixel_height * (H + 1))
color = modefunc(img.getpixel(x, y)
                for x in xrange(minx, maxx)
                for y in xrange(miny, maxy))
for x in xrange(minx, maxx):
    for y in xrange(miny, maxy): 
        img.putpixel((x, y), color)

更多的优化

您可以在嵌套循环之外计算x限制。

您的while循环实际上是伪装的for循环,您可以通过使用for W in range(width/pixel_width)来提高效率,或者可以使用range的step参数来使用您实际需要的值:for w in range(0, width, pixel_width): (在这两种情况下,可能都有一个不一致的问题,但我会让您检查和修复)。

最终(未经测试)版本的代码

代码语言:javascript
复制
def pixelate(img, (pixel_width, pixel_height), mode):
    width, height = img.size
    modefunc = pixelate_mode(mode)
    for w in range(0, width, pixel_width):
        minx, maxx = w, min(width, w + pixel_width)
        for h in range(0, height, pixel_height):
            miny, maxy = h, min(height, h + pixel_height)
            color = modefunc(img.getpixel(x, y)
                    for x in xrange(minx, maxx)
                    for y in xrange(miny, maxy))
            for x in xrange(minx, maxx):
                for y in xrange(miny, maxy):
                img.putpixel((x, y), color)
    return img
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/117069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档