2013-02-22 35 views
5

मैं कोड लिख रहा हूं जो छवियों के बीच विशेषताओं को प्रदर्शित करता है। इस समय कोड काफी धीमा चलता है। मेरे पास कुछ गति है कि इसे कैसे गति दें, लेकिन मैं matplotlib के साथ 100% सहज नहीं हूं या दृश्यों के पीछे कैसे काम कर रहा हूं।matplotlib में कई पैच के साथ एकाधिक छवियों को साजिश करने का कुशल तरीका?

कोड की बुनियादी संरचना है: (मैं चीजों को बाहर जा रहा हूँ इसे और अधिक पठनीय बनाने के लिए)

from matplotlib.patches import Rectangle, Circle, Ellipse 
import matplotlib.gridspec as gridspec 
from matplotlib.transforms import Affine2D 
from scipy.linalg import inv, sqrtm 
import matplotlib.pyplot as plt 
import numpy as np 
  • एक सूची छवियों जोड़ें।

    gs = gridspec.GridSpec(nr, nc) 
    for i in range(num_images): 
        dm.ax_list[i] = plt.subplot(gs[i]) 
        dm.ax_list[i].imshow(img_list[i]) 
        transData_list[i] = dm.ax_list[i].transData 
    
  • अनेक बिंदु के रूप में सुविधा प्रतिनिधित्व कल्पना

    for i in range(num_chips): 
        axi = chips[i].axi 
        ax = dm.ax_list[axi] 
        transData = dm.transData_list[axi] 
        chip_feats = chips[i].features 
        for feat in chip_feats: 
         (x,y,a,c,d) = feat 
         A = numpy.array([ (a, 0, 0) , 
                (c, d, 0) , 
                (0, 0, 1) ] , dtype=np.float64) 
         EllShape = Affine2D(numpy.array(sqrtm(inv(A)), dtype=np.float64)) 
         transEll = EllShape.translate(x,y) 
         unitCirc = Circle((0,0),1,transform=transEll+transData) 
         ax.add_patch(unitCirc) 
    

मैं कोड प्रोफ़ाइल RunSnakeRun का उपयोग किया है, और सभी कुल्हाड़ी, और याद ax.transData: प्रत्येक छवि का अपना कुल्हाड़ियों हो जाता है मैं वास्तव में उस से इकट्ठा होता हूं कि सबकुछ खींचने में काफी समय लग रहा है। जब मैटलप्लिब में परिवर्तन के बारे में मैंने सीखा तो मूलभूत विचार था कि प्रत्येक छवि को अपने निर्देशांक में खींचें, और फिर कई परिवर्तनों को बनाए रखें ताकि मैं बाद में उनके साथ अच्छी चीजें कर सकूं, लेकिन मुझे संदेह है कि यह अच्छी तरह से स्केल नहीं करेगा।

ड्रा के वास्तविक उत्पादन इस तरह दिखता है:

आंकड़ा पुनः बनाने का है जब मैं इसे दोबारा आकार के बारे में 4 सेकंड लेता है, और मैं पैन/ज़ूम के लिए इच्छुक होने के लिए जा रहा हूँ।

मैं प्रत्येक सुविधा के लिए दो पैच जोड़ रहा था, और लगभग (प्रति छवि 300 विशेषताएं) ताकि मैं एक रूपरेखा और कुछ पारदर्शिता देख सकूं। तो, इसके लिए स्पष्ट रूप से ऊपर की ओर है। लेकिन यह किसी भी अंडाकार के बिना भी अपेक्षाकृत धीमी है।

मुझे मिलान करने वाली विशेषताओं के बीच लाइनों को रखने के लिए कुछ कोड लिखने की भी आवश्यकता है, लेकिन अब मुझे यह सुनिश्चित नहीं है कि एकाधिक अक्षों का उपयोग करना बहुत अच्छा विचार है, खासकर जब यह अपेक्षाकृत छोटा डेटासेट होता है।

तो, अधिक ठोस प्रश्नों के लिए:

  • इसे और अधिक अनेक बिंदु बदल मंडलियां बनाम साजिश कुशल होगा? Matplotlib परिवर्तनों का उपयोग करने के ऊपरी हिस्से क्या है?
  • क्या पैच के समूह को गठबंधन करने का कोई तरीका है ताकि वे एक साथ या अधिक कुशलता से बदल सकें?
  • क्या यह सबकुछ एक अक्ष में पैक करने के लिए और अधिक कुशल होगा? यदि मैं ऐसा करता हूं तो क्या ट्रांसफॉर्म का प्रतिमान अभी भी उपयोग किया जा सकता है? या यहां मुख्य अपराधी को बदल दिया गया है?
  • क्या matrices ए की सूची में sqrtm (inv (ए)) करने का कोई त्वरित तरीका है? या यह भी ठीक है कि मेरे पास उन्हें लूप में है?
  • क्या मुझे pyqtgraph जैसे कुछ पर स्विच करना चाहिए? मैं पैन और ज़ूम से परे किसी भी एनीमेशन होने की योजना नहीं बना रहा हूं।(हो सकता है कि भविष्य में मैं एक इंटरैक्टिव ग्राफ में इन एम्बेड करने के लिए चाहता हूँ)

संपादन:

मैं वर्गमूल औंधा के रूप कंप्यूटिंग द्वारा ड्राइंग क्षमता में वृद्धि कर लिया है हाथ से मैट्रिक्स। यह भी एक बहुत बड़ी गति है।

उपरोक्त कोड में:

A = numpy.array([ (a, 0, 0) , 
          (c, d, 0) , 
          (0, 0, 1) ] , dtype=np.float64) 
EllShape = Affine2D(numpy.array(sqrtm(inv(A)), dtype=np.float64)) 

द्वारा

EllShape = Affine2D([\ 
(1/sqrt(a),   0, 0),\ 
((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0),\ 
(  0,   0, 1)]) 

बदल दिया है मैंने पाया कुछ रोचक समय भी परिणाम:

num_to_run = 100000 
    all_setup = ''' import numpy as np ; from scipy.linalg import sqrtm ; from numpy.linalg import inv ; from numpy import sqrt 
    a=.1 ; c=43.2 ; d=32.343''' 

    timeit(\ 
    'sqrtm(inv(np.array([ (a, 0, 0) , (c, d, 0) , (0, 0, 1) ])))',\ 
    setup=all_setup, number=num_to_run) 
    >> 22.2588094075 #(Matlab reports 8 seconds for this run) 

    timeit(\ 
    '[ (1/sqrt(a), 0, 0), ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0), (0, 0, 1) ]',\ 
    setup=all_setup, number=num_to_run) 
    >> 1.10265190941 #(Matlab reports .1 seconds for this run) 

संपादित 2

Ive को पचकोलेक्शन और कुछ मैन्युअल गणनाओं का उपयोग करके इलिप्स को गणना और बहुत जल्दी खींचा गया (लगभग एक सेकंड में, मैंने इसे प्रोफाइल नहीं किया)। केवल दोष यह है मैं स्थापित करने के लिए अनेक बिंदुओं का भरण झूठी

from matplotlib.collections import PatchCollection 
ell_list = [] 
for i in range(num_chips): 
    axi = chips[i].axi 
    ax = dm.ax_list[axi] 
    transData = dm.transData_list[axi] 
    chip_feats = chips[i].features 
    for feat in chip_feats: 
     (x,y,a,c,d) = feat 
     EllShape = Affine2D([\ 
      (1/sqrt(a),   0, x),\ 
      ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), y),\ 
      (  0,   0, 1)]) 
     unitCirc = Circle((0,0),1,transform=EllShape) 
     ell_list = [unitCirc] + ell_list 
    ellipses = PatchCollection(ell_list) 
    ellipses.set_color([1,1,1]) 
    ellipses.face_color('none') #'none' gives no fill, while None will default to [0,0,1] 
    ellipses.set_alpha(.05) 
    ellipses.set_transformation(transData) 
    ax.add_collection(ellipses) 
+0

आप के बाद आप उन्हें स्वतंत्र रूप से तैयार की है पैच संशोधित करने के लिए सक्षम होने के लिए की जरूरत है? – tacaswell

+0

प्लॉट पर खींचे जाने के बाद इलिप्स को आकार बदलने की आवश्यकता नहीं होगी। वे साजिश के साथ स्केल या ट्रांसफॉर्म कर सकते हैं, लेकिन एक दूसरे से स्वतंत्र रूप से नहीं। मैं यूनिट सर्कल को इलिप्स में बदल रहा हूं क्योंकि मैट्रिक्स से एक्सस्केल, वाईस्केल और रोटेशन प्राप्त करने की कोशिश करने से यह आसान है। – Erotemic

+3

आप सभी इलिप्स को एक पैच संग्रह में डाल सकते हैं जो ड्राइंग को भी तेज कर सकता है। – tacaswell

उत्तर

0

मैं हाथ से वर्गमूल उल्टे मैट्रिक्स के रूप कंप्यूटिंग द्वारा ड्राइंग क्षमता में वृद्धि कर लिया है प्रतीत नहीं कर सकते हैं। यह भी एक बहुत बड़ी गति है।

उपरोक्त कोड में:

A = numpy.array([ (a, 0, 0) , 
          (c, d, 0) , 
          (0, 0, 1) ] , dtype=np.float64) 
EllShape = Affine2D(numpy.array(sqrtm(inv(A)), dtype=np.float64)) 

द्वारा

EllShape = Affine2D([\ 
(1/sqrt(a),   0, 0),\ 
((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0),\ 
(  0,   0, 1)]) 

बदल दिया है मैंने पाया कुछ रोचक समय भी परिणाम:

num_to_run = 100000 
    all_setup = ''' import numpy as np ; from scipy.linalg import sqrtm ; from numpy.linalg import inv ; from numpy import sqrt 
    a=.1 ; c=43.2 ; d=32.343''' 

    timeit(\ 
    'sqrtm(inv(np.array([ (a, 0, 0) , (c, d, 0) , (0, 0, 1) ])))',\ 
    setup=all_setup, number=num_to_run) 
    >> 22.2588094075 #(Matlab reports 8 seconds for this run) 

    timeit(\ 
    '[ (1/sqrt(a), 0, 0), ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), 0), (0, 0, 1) ]',\ 
    setup=all_setup, number=num_to_run) 
    >> 1.10265190941 #(Matlab reports .1 seconds for this run) 

संपादित 2

Ive को पचकोलेक्शन और कुछ मैन्युअल गणनाओं का उपयोग करके इलिप्स को गणना और बहुत जल्दी खींचा गया (लगभग एक सेकंड में, मैंने इसे प्रोफाइल नहीं किया)। केवल दोष यह है मैं स्थापित करने के लिए अनेक बिंदुओं का भरण गलत नहीं कर पा रहे

from matplotlib.collections import PatchCollection 
ell_list = [] 
for i in range(num_chips): 
    axi = chips[i].axi 
    ax = dm.ax_list[axi] 
    transData = dm.transData_list[axi] 
    chip_feats = chips[i].features 
    for feat in chip_feats: 
     (x,y,a,c,d) = feat 
     EllShape = Affine2D([\ 
      (1/sqrt(a),   0, x),\ 
      ((c/sqrt(a) - c/sqrt(d))/(a - d), 1/sqrt(d), y),\ 
      (  0,   0, 1)]) 
     unitCirc = Circle((0,0),1,transform=EllShape) 
     ell_list = [unitCirc] + ell_list 
    ellipses = PatchCollection(ell_list) 
    ellipses.set_color([1,1,1]) 
    ellipses.face_color('none') #'none' gives no fill, while None will default to [0,0,1] 
    ellipses.set_alpha(.05) 
    ellipses.set_transformation(transData) 
    ax.add_collection(ellipses) 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^