7

私は、2つのPIL画像と、三角形を作る対応する2次元点の2つのセットを持っています。例えばPILによる三角画像領域のコピー

image1: 
100x100 pixels 
points = [(10,10), (20,20), (10,20)] 

image2: 
250x250 pixels 
points = [(35,30), (75,19), (50,90)] 

は、私がイメージ1から三角形の領域をコピーして、画像2の対応する三角形の領域に収まるように、それを変換したいです。 PILでこれを行う方法はありますか?ピクセルごとにコピーして変換を自分で計算する必要はありませんか?

答えて

3

私はこれをアフィン変換(this questionのおかげで)できました。アファイン変換の後、デスティネーショントライアングルはマスクに描画され、デスティネーションイメージに貼り付けられます。ソース100×100の画像は、この(白に重ね三角形)のように見えます

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) 

src_before

先250×250の画像がで満たされたこの(三角形の領域のように見えるここに私が思い付いたものです白):

dst_before

そして変換と貼り付けた後、DES tinationの画像は、次のようになります三角形をラインアップしません

dst_after

+0

あなたは手で変換を計算したくありませんでしたか? – carlosdc

+0

はい、それはPILでそれを行う方法があるようには思われませんでした。私は参照されたポストから数式を得てnumpyは私のための方程式のシステムを解決するので、あまりにも多くのトラブルではありませんでした。私が実際に避けたかったのは、ピクセル単位でのコピーでした。 – jterrace

0

EDITED

この戦略は、まだいくつかのピクセル操作を含むが、多少のAPIを活用することができます。

  1. ソースイメージをRGBAに変換します。
  2. 三角形を囲む最小の四角形を探します。
  3. 三角形の一部ではなく、四角形内のすべてのピクセルを完全に透明に手動で設定します。 x/yの値がmapおよびpartialのセットを使用すると、あまり問題なくこれを行うことができます。
  4. ターゲットイメージの三角形の最小の四角形を見つけます。
  5. 矩形をターゲットのサイズにスケーリングすることによって、矩形をターゲットイメージにコピーします。
+0

は、私はまだこの作品とは思わない画像2 – jterrace

+0

の座標とimage1の座標。それはせん断と回転ではなく、平行移動とスケールのみを処理します。 – jterrace

+0

あなたはあなたの質問にそれを言及していませんでした。あなたがせん断によってあなたがオフセットを意味するならば、ターゲットの上に置くときにデルタx/yを加えなければなりません。回転の場合、三角形の中心を計算し、この回転式を適用することができます:http://stackoverflow.com/questions/6207480/how-to-rotate-a-two-dimensional-array-to-an-arbitrary-度/ 6207584#6207584 – wberry

関連する問題