首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在图像中操作RGB值

在图像中操作RGB值
EN

Stack Overflow用户
提问于 2019-11-29 07:21:35
回答 1查看 163关注 0票数 1

我想将一个简单的代数运算应用于图像的RBG值,这是我通过PIL加载的。我的当前版本可以工作,但速度很慢:

代码语言:javascript
运行
复制
from PIL import Image
import numpy as np

file_name = '1'
im = Image.open('data/' + file_name + '.jpg').convert('RGB')
pixels = np.array(im)
s = pixels.shape
p = pixels.reshape((s[0] * s[1], s[2]))


def update(ratio=0.5):
    p2 = np.array([[min(rgb[0] + rgb[0] * ratio, 1), max(rgb[1] - rgb[1] * ratio, 0), rgb[2]] for rgb in p])
    img = Image.fromarray(np.uint8(p2.reshape(s)))
    img.save('result/' + file_name + '_test.png')
    return 0

update(0.5)

有人有更有效的主意吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-29 08:31:51

利用NumPy的矢量化操作来摆脱循环。

我修改了您最初的方法,以比较以下不同的解决方案之间的性能。此外,如果您想完全摆脱ImageMath,那么我添加了一种只使用NumPy的PIL方法。

此外,我认为存在/曾经有一个bug:

代码语言:javascript
运行
复制
p2 = np.array([[min(rgb[0] + rgb[0] * ratio, 1), max(rgb[1] - rgb[1] * ratio, 0), rgb[2]] for rgb in p])

实际上,您做的是而不是转换为float,所以在min调用中应该是255而不是1

以下是我所做的:

代码语言:javascript
运行
复制
import numpy as np
from PIL import Image, ImageMath
import time


# Modified, original implementation; fixed most likely wrong compare value in min (255 instead of 1)
def update_1(ratio=0.5):
    pixels = np.array(im)
    s = pixels.shape
    p = pixels.reshape((s[0] * s[1], s[2]))
    p2 = np.array([[min(rgb[0] + rgb[0] * ratio, 255), max(rgb[1] - rgb[1] * ratio, 0), rgb[2]] for rgb in p])
    img = Image.fromarray(np.uint8(p2.reshape(s)))
    img.save('result_update_1.png')
    return 0


# More efficient vectorized approach using NumPy
def update_2(ratio=0.5):
    pixels = np.array(im)
    pixels[:, :, 0] = np.minimum(pixels[:, :, 0] * (1 + ratio), 255)
    pixels[:, :, 1] = np.maximum(pixels[:, :, 1] * (1 - ratio), 0)
    img = Image.fromarray(pixels)
    img.save('result_update_2.png')
    return 0


# More efficient approach only using PIL
def update_3(ratio=0.5):
    (r, g, b) = im.split()
    r = ImageMath.eval('min(float(r) / 255 * (1 + ratio), 1) * 255', r=r, ratio=ratio).convert('L')
    g = ImageMath.eval('max(float(g) / 255 * (1 - ratio), 0) * 255', g=g, ratio=ratio).convert('L')
    Image.merge('RGB', (r, g, b)).save('result_update_3.png')
    return 0


im = Image.open('path/to/your/image.png')

t1 = time.perf_counter()
update_1(0.5)
print(time.perf_counter() - t1)

t1 = time.perf_counter()
update_2(0.5)
print(time.perf_counter() - t1)

t1 = time.perf_counter()
update_3(0.5)
print(time.perf_counter() - t1)

在我的机器上的[400, 400] RGB映像上的性能:

代码语言:javascript
运行
复制
1.723889293 s    # your approach
0.055316339 s    # vectorized NumPy approach
0.062502050 s    # PIL only approach

希望这能帮上忙!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59100363

复制
相关文章

相似问题

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