7

के साथ त्रिकोणीय छवि क्षेत्र की प्रतिलिपि बना रहा है मेरे पास दो पीआईएल छवियां हैं और 2 डी बिंदुओं के दो सेट हैं जो त्रिभुज बनाते हैं।पीआईएल

उदाहरण के लिए:

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

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

मैं Image1 से त्रिकोणीय क्षेत्र को कॉपी करें और बदलने Image2 की इसी त्रिकोणीय क्षेत्र में फिट करने के लिए करना चाहते हैं। क्या पिक्सेल द्वारा पिक्सेल की प्रतिलिपि बनाये बिना पीआईएल के साथ ऐसा करने का कोई तरीका है और खुद को परिवर्तन की गणना करें?

उत्तर

3

मैं एक एफ़िन रूपांतरण के साथ ऐसा करने में सक्षम था (this question के लिए धन्यवाद)। Affine परिवर्तन के बाद, गंतव्य त्रिकोण एक मुखौटा के लिए खींचा जाता है और फिर गंतव्य छवि पर चिपकाया जाता है।

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 छवि इस तरह (सफेद में आच्छादित त्रिकोण) दिखता है:: यहाँ है कि मैं क्या के साथ आया है

src_before

गंतव्य 250x250 छवि लगता है कि यह (त्रिकोणीय क्षेत्र के साथ में भरा सफेद):

dst_before

और फिर परिवर्तन और पेस्ट करने के बाद, des tination छवि इस तरह दिखता है:

dst_after

+0

क्या आप हाथ से परिवर्तन की गणना नहीं करना चाहते थे? – carlosdc

+0

हां, लेकिन ऐसा लगता है कि पीआईएल के साथ ऐसा करने का कोई तरीका नहीं था।यह बहुत अधिक परेशानी नहीं थी क्योंकि मुझे संदर्भित पोस्ट से फॉर्मूला मिला और numpy मेरे लिए समीकरणों की प्रणाली हल करता है। जो मैं वास्तव में टालना चाहता था वह पिक्सेल-बाय-पिक्सेल की प्रतिलिपि बना रहा था। – jterrace

0

संपादित

इस रणनीति अभी भी कुछ पिक्सेल हेरफेर शामिल है, लेकिन कुछ हद तक API का लाभ उठाते कर सकते हैं।

  1. स्रोत छवि को आरजीबीए में कनवर्ट करें।
  2. अपने त्रिकोण के सबसे छोटे संलग्न आयत को खोजें।
  3. आयत के भीतर मैन्युअल रूप से सभी पिक्सल सेट करें, लेकिन त्रिभुज का हिस्सा पूरी तरह पारदर्शी नहीं है। (आप x/y मानों, map और partial के लिए सेट का उपयोग करके बहुत अधिक परेशानी के बिना ऐसा करने में सक्षम हो सकते हैं।)
  4. लक्ष्य छवि में त्रिकोण के सबसे छोटे संलग्न आयत को ढूंढें।
  5. लक्ष्य आकार में आयत संलग्न करने वाले स्रोत को स्केल करके आयत को लक्ष्य छवि में कॉपी करें।
+0

कि त्रिकोण नहीं मिलाया गया होगा Image2 – jterrace

+0

में निर्देशांक मैं अभी भी इस काम करता है नहीं लगता है के साथ Image1 में समन्वय करता है। यह केवल अनुवाद और पैमाने का ख्याल रखेगा, कतरनी और घूर्णन नहीं। – jterrace

+0

आपने अपने प्रश्न में इसका उल्लेख नहीं किया है। यदि कतरनी से आप ऑफसेट का मतलब रखते हैं, तो आपको लक्ष्य पर रखकर डेल्टा एक्स/वाई जोड़ना होगा। रोटेशन के लिए, आप त्रिकोण के केंद्र की गणना कर सकते हैं और फिर इस रोटेशन फॉर्मूला को लागू कर सकते हैं: http://stackoverflow.com/questions/6207480/how-to-rotate-a-two-dimensional-array-to-an-arbitrary- डिग्री/6207584 # 6207584 – wberry