如何将图像合并为透明层?

时间:2019-03-25 07:22:24

标签: python python-3.x image-processing

我正在为树莓派开发视频编辑器,但是在将图像放置在图像上的速度方面存在问题。目前,使用imagemagick最多需要10秒钟才能在树莓派上使用1080x1920 png图像将一幅图像放置在另一幅图像上,这太多了。随着图像数量的增加,时间也会增加。关于如何加快速度的任何想法? Imagemagick代码:

composite -blend 90 img1.png img2.png new.png

不透明性支持缓慢的视频编辑器here

--------编辑--------

稍微快一点的方法:

import numpy as np
from PIL import Image
size_X, size_Y = 1920, 1080#  put images resolution, else output may look wierd
image1 = np.resize(np.asarray(Image.open('img1.png').convert('RGB')), (size_X, size_Y, 3))
image2 = np.resize(np.asarray(Image.open('img2.png').convert('RGB')), (size_X, size_Y, 3))
output = image1*transparency+image2*(1-transparency)
Image.fromarray(np.uint8(output)).save('output.png')

2 个答案:

答案 0 :(得分:3)

我的Raspberry Pi目前不可用-我要说的是卷入了黑烟,我在做软件,而不是硬件!结果,我只在Mac上进行了测试。它使用pg_restore -a -h your_host -U your_user -W -Fc your_database < DATA.dump

首先,我在这2张图片上使用了您的Numpy代码:

enter image description here

enter image description here

然后,我使用Numba实现了相同的操作。 Numba版本在我的iMac上运行速度提高了5.5倍。由于Raspberry Pi具有4个核心,因此您可以尝试进行以下实验:

Numba

代码如下:

@jit(nopython=True,parallel=True)
def method2(image1,image2,transparency):
   ...

结果是:

enter image description here

其他想法...我就地进行了复合操作,覆盖了输入#!/usr/bin/env python3 import numpy as np from PIL import Image import numba from numba import jit def method1(image1,image2,transparency): result = image1*transparency+image2*(1-transparency) return result @jit(nopython=True) def method2(image1,image2,transparency): h, w, c = image1.shape for y in range(h): for x in range(w): for z in range(c): image1[y][x][z] = image1[y][x][z] * transparency + (image2[y][x][z]*(1-transparency)) return image1 i1 = np.array(Image.open('image1.jpg').convert('RGB')) i2 = np.array(Image.open('image2.jpg').convert('RGB')) res = method1(i1,i2,0.4) res = method2(i1,i2,0.4) Image.fromarray(np.uint8(res)).save('result.png') 以尝试节省缓存空间。这可能会有所帮助或阻碍-请尝试。我可能未按照最佳顺序处理像素-请尝试。

答案 1 :(得分:2)

作为另一种选择,我尝试了pyvips(完整披露:我是pyvips维护者,所以我不是很中立):

#!/usr/bin/python3

import sys
import time
import pyvips

start = time.time()

a = pyvips.Image.new_from_file(sys.argv[1], access="sequential")
b = pyvips.Image.new_from_file(sys.argv[2], access="sequential")
out = a * 0.2 + b * 0.8
out.write_to_file(sys.argv[3])

print("pyvips took {} milliseconds".format(1000 * (time.time() - start)))

pyvips是一个“管道”图像处理库,因此代码可以并行执行加载,处理和保存所有操作。

在这两个内核的四线程i5笔记本电脑上,我使用了Mark的两个测试图像:

$ ./overlay-vips.py blobs.jpg ships.jpg x.jpg
took 39.156198501586914 milliseconds

因此,两次加载,处理和一次保存jpg的时间为39ms。

您可以通过将源图像和结果复制到内存中来仅为混合部分计时,如下所示:

a = pyvips.Image.new_from_file(sys.argv[1]).copy_memory()
b = pyvips.Image.new_from_file(sys.argv[2]).copy_memory()

start = time.time()
out = (a * 0.2 + b * 0.8).copy_memory()
print("pyvips between memory buffers took {} milliseconds"
        .format(1000 * (time.time() - start)))

我知道:

$ ./overlay-vips.py blobs.jpg ships.jpg x.jpg 
pyvips between memory buffers took 15.432596206665039 milliseconds

在同一测试中,numpy约为60ms。

我尝试了Mark的漂亮numba示例的一些变体:

#!/usr/bin/python3

import sys
import time
import numpy as np
from PIL import Image

import numba
from numba import jit, prange

@jit(nopython=True, parallel=True)
def method2(image1, image2, transparency):
   h, w, c = image1.shape
   for y in prange(h):
      for x in range(w):
         for z in range(c):
            image1[y][x][z] = image1[y][x][z] * transparency \
                    + (image2[y][x][z] * (1 - transparency))
   return image1

# run once to force a compile
i1 = np.array(Image.open(sys.argv[1]).convert('RGB'))
i2 = np.array(Image.open(sys.argv[2]).convert('RGB'))
res = method2(i1, i2, 0.2)

# run again and time it
i1 = np.array(Image.open(sys.argv[1]).convert('RGB'))
i2 = np.array(Image.open(sys.argv[2]).convert('RGB'))

start = time.time()
res = method2(i1, i2, 0.2)
print("numba took {} milliseconds".format(1000 * (time.time() - start)))

Image.fromarray(np.uint8(res)).save(sys.argv[3])

我看到:

$ ./overlay-numba.py blobs.jpg ships.jpg x.jpg 
numba took 8.110523223876953 milliseconds

因此,在这台笔记本电脑上,numba比pyvips快约2倍。

如果同时加载和保存时间,则速度会慢很多:

$ ./overlay-numba.py blobs.jpg ships.jpg x.jpg 
numba plus load and save took 272.8157043457031 milliseconds

但这似乎是不公平的,因为几乎所有时间都在PIL加载和保存中。