7

두 개의 PIL 이미지와 삼각형을 만드는 2D 점 2 세트가 있습니다. 예를 들어PIL을 사용하여 삼각형 이미지 영역 복사

는 :

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

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

나는 image1에에서 삼각 지역을 복사 이미지 2의 해당 삼각형 영역에 맞도록 변환하고자합니다. PIL로 픽셀 단위로 복사하고 변환을 직접 계산하지 않고도이 작업을 수행 할 수 있습니까?

답변

3

어파인 변형으로이 작업을 수행 할 수있었습니다 (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) 

100 × 100 이미지 (흰색에 중첩 삼각형)과 같다 출처 : 여기에 내가 무엇을 최대 온의

src_before

이 (삼각 지역으로 채워처럼 250x250 크기의 이미지가 보이는 대상 흰색)

dst_before

그리고 변환 붙이기 후, 데스 큐틴 이미지는 다음과 같습니다 삼각형을 줄 수 없습니다

dst_after

+0

변형을 수동으로 계산하고 싶지 않습니까? – carlosdc

+0

네,하지만 PIL로 그렇게 할 수있는 것처럼 보이지 않았습니다.참조 된 게시물에서 수식을 얻었으므로 numpy는 나를위한 방정식 시스템을 해결하기 때문에 너무 많은 문제가 아니 었습니다. 내가 정말로 피하고 싶었던 것은 픽셀 단위로 복사하는 것이 었습니다. – jterrace

0

이 전략은 여전히 ​​픽셀 조작을 포함하지만, 다소 API를 활용할 수

편집했다.

  1. 소스 이미지를 RGBA로 변환합니다.
  2. 삼각형의 가장 작은 사각형을 찾으십시오.
  3. 삼각형의 일부가 아닌 사각형 내의 모든 픽셀을 완전히 투명하게 설정합니다. (x/y 값에 대한 세트를 사용하면 큰 문제없이이 작업을 수행 할 수 있습니다. mappartial)
  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- degree/6207584 # 6207584 – wberry

관련 문제