簡體   English   中英

處理圖像中的 RGB 值

[英]Manipulate RGB values in image

我想對通過 PIL 加載的圖像的 RBG 值應用簡單的代數運算。 我當前的版本有效,但速度很慢:

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)

有人有更有效的想法嗎?

利用 NumPy 的矢量化操作來擺脫循環。

我修改了您原來的方法來比較以下不同解決方案之間的性能。 此外,如果您想完全擺脫 NumPy,我還使用ImageMath添加了僅 PIL 方法。

此外,我假設存在/曾經存在一個錯誤:

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

這是我所做的:

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 圖像的性能:

1.723889293 s    # your approach
0.055316339 s    # vectorized NumPy approach
0.062502050 s    # PIL only approach

希望有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM