2012-06-18 16 views
6

के अंदर मिलान करने वाले पनडुब्बियों को ढूंढना मेरे पास 100x200 2 डी सरणी है जो एक अंधा सरणी के रूप में व्यक्त की गई है जिसमें काला (0) और सफेद (255) कोशिकाएं शामिल हैं। यह एक बिटमैप फ़ाइल है। इसके बाद मेरे पास 2 डी आकार होते हैं (उन्हें अक्षरों के रूप में सोचना सबसे आसान है) जो 2 डी काले और सफेद कोशिकाएं भी हैं।मैट्रिक्स

मुझे पता है कि मैं मैट्रिक्स के माध्यम से निष्क्रिय रूप से पुनरावृत्ति कर सकता हूं लेकिन यह मेरे कोड का 'गर्म' हिस्सा होगा, इसलिए गति चिंता का विषय है। क्या यह numpy/scipy में प्रदर्शन करने के लिए एक तेज तरीका है?

मैंने सिसि के सहसंबंध समारोह में संक्षेप में देखा। मुझे 'अस्पष्ट मैचों' में दिलचस्पी नहीं है, केवल सटीक मैच। मैंने कुछ अकादमिक कागजात भी देखे लेकिन वे मेरे सिर से ऊपर हैं।

उत्तर

8

आप सहसंबंध का उपयोग कर सकते हैं। आपको अपने काले मानों को -1 और अपने सफेद मानों को 1 (या इसके विपरीत) पर सेट करने की आवश्यकता होगी ताकि आप सहसंबंध की चोटी के मूल्य को जान सकें, और यह केवल सही अक्षर के साथ होता है।

निम्नलिखित कोड मैं क्या लगता है कि आप चाहते हैं करता है।

import numpy 
from scipy import signal 

# Set up the inputs 
a = numpy.random.randn(100, 200) 
a[a<0] = 0 
a[a>0] = 255 

b = numpy.random.randn(20, 20) 
b[b<0] = 0 
b[b>0] = 255 

# put b somewhere in a 
a[37:37+b.shape[0], 84:84+b.shape[1]] = b 

# Now the actual solution... 

# Set the black values to -1 
a[a==0] = -1 
b[b==0] = -1 

# and the white values to 1 
a[a==255] = 1 
b[b==255] = 1 

max_peak = numpy.prod(b.shape) 

# c will contain max_peak where the overlap is perfect 
c = signal.correlate(a, b, 'valid') 

overlaps = numpy.where(c == max_peak) 

print overlaps 

यह (array([37]), array([84])), ऑफसेट कोड में सेट के स्थानों को आउटपुट।

आपको शायद यह पता चलेगा कि यदि आपका बड़ा आकार आपके बड़े सरणी आकार से गुणा हुआ है तो मोटे तौर पर नोग्ल (एन) से बड़ा है, जहां एन उस बड़े सरणी का आकार है जिसमें आप खोज रहे हैं (प्रत्येक आयाम के लिए), फिर आप शायद scipy.signal.fftconvolve (- flipud और fliplr मन में असर है कि आप एक संबंध की तुलना में एक घुमाव के उपयोग कर रहे हैं बल्कि डेटासेट में से एक के प्रत्येक अक्ष फ्लिप करने की आवश्यकता होगी) की तरह एक fft आधारित एल्गोरिदम के उपयोग द्वारा गति को मिल जाएगा।

c = signal.fftconvolve(a, numpy.fliplr(numpy.flipud(b)), 'valid') 

ऊपर आकार पर समय की तुलना:

In [5]: timeit c = signal.fftconvolve(a, numpy.fliplr(numpy.flipud(b)), 'valid') 
100 loops, best of 3: 6.78 ms per loop 

In [6]: timeit c = signal.correlate(a, b, 'valid') 
10 loops, best of 3: 151 ms per loop 
+0

वाह, महान जवाब! मुझे चलाने के लिए कुछ परीक्षण मिल गए हैं। – DaveO

+1

मेरे साथ कुछ हुआ, आप 0 को मान सेट करके अपने सबमिट्रिक्स के क्षेत्रों को "परवाह नहीं करते" कर सकते हैं। इसका मतलब है कि उन मानों का पार-सहसंबंध पर कोई प्रभाव नहीं पड़ेगा। 'Max_peak' मान को' max_peak = b [b! = 0] .size' के रूप में पाया जा सकता है (यह काम करेगा कि आपके पास 0 मान हैं या नहीं)। –

+0

इसलिए मैंने दोपहर को अपना कोड संपादित कर लिया है और इसे काम कर लिया है! आइए मान लें कि 2 घटनाएं 2x3 आकार (सरणी ([0, 6]), सरणी ([1, 7]) पर पाए गए हैं) जिसका अर्थ है ऊपरी बाएं कोने [0, 1] और [6, 7] हैं। मैं जो करना चाहता हूं वह आकार के सभी 2x3 कोशिकाओं को अनुक्रमणित करने में सक्षम होना है और उन्हें अगले आकार पर 0 असाइन करना है, जिसे हम ढूंढ रहे हैं, हम छवि के उस भाग (ऊपर आपकी टिप्पणी के अनुसार) की जांच नहीं करेंगे। लूप का उपयोग किए बिना 2 डी आकार को इंडेक्स करने के लिए मैं सहसंबंध/fftconvolve के वापसी मूल्य का उपयोग कैसे कर सकता हूं? एक सूची-स्थान-स्थान टुकड़ा का क्रमबद्ध करें। – DaveO

7

यहाँ एक पद्धति का उपयोग करना, या अनुकूलन, के विवरण के आधार पर हासिल कर सकते हैं केवल संशोधन बताए ग होगा आपकी जरुरतें। यह ndimage.label and ndimage.find_objects:

  1. लेबल छवि इस सरणी में सभी धब्बे पाता है और उन्हें पूर्णांकों किए जाने वाले लेबल ndimage.label का उपयोग कर उपयोग करता है।

    import scipy 
    from scipy import ndimage 
    import matplotlib.pyplot as plt 
    
    #flatten to ensure greyscale. 
    im = scipy.misc.imread('letters.png',flatten=1) 
    objects, number_of_objects = ndimage.label(im) 
    letters = ndimage.find_objects(objects) 
    
    #to save the images for illustrative purposes only: 
    plt.imsave('ob.png',objects) 
    for i,j in enumerate(letters): 
        plt.imsave('ob'+str(i)+'.png',objects[j]) 
    

    उदाहरण इनपुट:

  2. ndimage.find_objects
  3. का उपयोग कर फिर सेट चौराहे का उपयोग करता है, तो found blobs1. और 2. के लिए अपने wanted blobs

संहिता के अनुरूप देखने के लिए इन धब्बे की स्लाइस जाओ

enter image description here

लेबल:

enter image description here

अलग धब्बे के खिलाफ परीक्षण करने के लिए: (यहां तक ​​कि समय)

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

+0

कमाल! यह लगभग है जो मैं करने की कोशिश कर रहा हूं। मुझे दोनों उत्तरों का प्रयास करना होगा और देखें कि सबसे अच्छा क्या काम करता है। इस पोस्ट के लिए समय निकालने के लिए धन्यवाद! – DaveO