我有兩個PIL圖像和兩組相應的創建三角形的2D點。使用PIL複製三角形圖像區域
例如:
image1:
100x100 pixels
points = [(10,10), (20,20), (10,20)]
image2:
250x250 pixels
points = [(35,30), (75,19), (50,90)]
欲三角形區域從圖像1複製並變換其配合到圖像2的對應的三角形區域。有沒有辦法與PIL做到這一點,而不必逐個像素地複製並自己計算轉換?
我有兩個PIL圖像和兩組相應的創建三角形的2D點。使用PIL複製三角形圖像區域
例如:
image1:
100x100 pixels
points = [(10,10), (20,20), (10,20)]
image2:
250x250 pixels
points = [(35,30), (75,19), (50,90)]
欲三角形區域從圖像1複製並變換其配合到圖像2的對應的三角形區域。有沒有辦法與PIL做到這一點,而不必逐個像素地複製並自己計算轉換?
我能夠通過仿射變換完成此操作(感謝this question)。仿射變換之後,將目標三角形繪製到蒙版上,然後粘貼到目標圖像上。以下是我想出了:
import Image
import ImageDraw
import numpy
def transformblit(src_tri, dst_tri, src_img, dst_img):
((x11,x12), (x21,x22), (x31,x32)) = src_tri
((y11,y12), (y21,y22), (y31,y32)) = dst_tri
M = numpy.array([
[y11, y12, 1, 0, 0, 0],
[y21, y22, 1, 0, 0, 0],
[y31, y32, 1, 0, 0, 0],
[0, 0, 0, y11, y12, 1],
[0, 0, 0, y21, y22, 1],
[0, 0, 0, y31, y32, 1]
])
y = numpy.array([x11, x21, x31, x12, x22, x32])
A = numpy.linalg.solve(M, y)
src_copy = src_img.copy()
srcdraw = ImageDraw.Draw(src_copy)
srcdraw.polygon(src_tri)
src_copy.show()
transformed = src_img.transform(dst_img.size, Image.AFFINE, A)
mask = Image.new('1', dst_img.size)
maskdraw = ImageDraw.Draw(mask)
maskdraw.polygon(dst_tri, fill=255)
dstdraw = ImageDraw.Draw(dst_img)
dstdraw.polygon(dst_tri, fill=(255,255,255))
dst_img.show()
dst_img.paste(transformed, mask=mask)
dst_img.show()
im100 = Image.open('test100.jpg')
im250 = Image.open('test250.jpg')
tri1 = [(10,10), (20,20), (10,20)]
tri2 = [(35,30), (75,19), (50,90)]
transformblit(tri1, tri2, im100, im250)
源100x100的圖像看起來像這樣(三角形白色覆蓋):
目標250x250的圖像看起來是這樣的(三角形區域填滿了白):
,然後將變換和粘貼後的DES tination圖像看起來是這樣的:
EDITED
這種策略仍涉及一些像素操作,但可以在一定程度利用這些API。
map
和partial
,而無需太多麻煩。)
難道你不想用手來計算轉換嗎? – carlosdc
是的,但似乎沒有辦法用PIL做到這一點。從參考文章中得到公式後,並沒有太多的麻煩,numpy爲我解決了方程組。我真正想避免的是逐個像素地複製。 – jterrace