2012-06-05 13 views
5

मेरे पास एक छवि है।एक छवि पर 3x3 स्लाइडिंग विंडो खोजें

मैं छवि में प्रत्येक पिक्सेल के लिए 3x3 विंडो (पड़ोसी पिक्सेल) प्राप्त करना चाहता हूं।

मैं इस अजगर कोड है:

for x in range(2,r-1,1): 
    for y in range(2,c-1,1): 
     mask5=numpy.array([cv.Get2D(copy_img,x-1,y-1),cv.Get2D(copy_img,x-1,y),cv.Get2D(copy_img,x-1,y+1),cv.Get2D(copy_img,x,y-1),cv.Get2D(copy_img,x,y),cv.Get2D(copy_img,x,y+1),cv.Get2D(copy_img,x+1,y-1),cv.Get2D(copy_img,x+1,y),cv.Get2D(copy_img,x+1,y+1)]) 
     cent=[cv.Get2D(copy_img,x,y)] 

mask5 3x3 खिड़की है। केंद्र केंद्र पिक्सेल है।

क्या ऐसा करने का एक और अधिक प्रभावी तरीका है - यानी नक्शे, इटरेटर का उपयोग करना - कुछ भी घोंसले वाले लूपों का उपयोग मैंने किया है?

+0

आपका इरादा क्या है निम्नलिखित कोड का प्रयास करें? शायद आप एक रूपांतरण करना चाहते हैं? हमें बताएं कि आप 'मास्क 5' के साथ क्या करने जा रहे हैं, तो हम आपको बेहतर, चीयर्स की मदद कर सकते हैं। – fraxel

+0

@fraxel: मुझे विंडो मिलने के बाद, मुझे पिक्सेल को 3x3 विंडो में तीव्रता से क्रमबद्ध करने की आवश्यकता है, और इस सूची में एक और (एक-आयामी) स्लाइडिंग विंडो बनाएं, और पिक्सेल के माध्यमों पर जटिल स्थिति के आधार पर ये (1-डी) स्लाइड, तदनुसार मूल केंद्र पिक्सेल को संशोधित करें। –

+0

लगता है जैसे आप [अनुकूली दहलीज] (http://opencv.willowgarage.com/documentation/python/imgproc_miscellaneous_image_transformations.html?highlight=adaptivethreshold#AdaptiveThreshold) करने की कोशिश कर रहे हैं? उस पर एक नज़र डालें, यह वही कर सकता है जो आप चाहते हैं। – fraxel

उत्तर

2

यह तेजी से किया जा सकता है, देगी और कुल्हाड़ियों की अदला-बदली, और तब सभी गिरी तत्वों से अधिक दोहरा, इस तरह से:

im = np.arange(81).reshape(9,9) 
print np.swapaxes(im.reshape(3,3,3,-1),1,2) 

यह आपको 3 * 3 टाइल की एक सरणी जो भर में tessalates देता है सतह:

[[[[ 0 1 2] [[ 3 4 5] [[ 6 7 8] 
    [ 9 10 11] [12 13 14] [15 16 17] 
    [18 19 20]] [21 22 23]] [24 25 26]]] 

[[[27 28 29] [[30 31 32] [[33 34 35] 
    [36 37 38] [39 40 41] [42 43 44] 
    [45 46 47]] [48 49 50]] [51 52 53]]] 

[[[54 55 56] [[57 58 59] [[60 61 62] 
    [63 64 65] [66 67 68] [69 70 71] 
    [72 73 74]] [75 76 77]] [78 79 80]]]] 

vstack औरका एक संयोजन का उपयोग करके अतिव्यापी टाइल्स हम इस 8 आगे बार दोहराने की आवश्यकता है, लेकिन 'रैपिंग' सरणी, प्राप्त करने के लिए। ध्यान दें कि सही और नीचे टाइल सरणियों लपेट (जो हो सकता है या नहीं हो सकता है कि आप क्या चाहते हैं, आप कैसे व्यवहार कर रहे बढ़त की स्थिति के आधार पर):

im = np.vstack((im[1:],im[0])) 
im = np.column_stack((im[:,1:],im[:,0])) 
print np.swapaxes(im.reshape(3,3,3,-1),1,2) 

#Output: 
[[[[10 11 12] [[13 14 15] [[16 17 9] 
    [19 20 21] [22 23 24] [25 26 18] 
    [28 29 30]] [31 32 33]] [34 35 27]]] 

[[[37 38 39] [[40 41 42] [[43 44 36] 
    [46 47 48] [49 50 51] [52 53 45] 
    [55 56 57]] [58 59 60]] [61 62 54]]] 

[[[64 65 66] [[67 68 69] [[70 71 63] 
    [73 74 75] [76 77 78] [79 80 72] 
    [ 1 2 3]] [ 4 5 6]] [ 7 8 0]]]] 

यह इस तरह से आप सरणियों के 9 सेट के साथ हवा कर , तो फिर आपको उन्हें एक साथ वापस ज़िप करने की आवश्यकता है। यह है, और सभी को पुन: आकार (सरणियों जहां आयाम 3 से विभाज्य हैं के लिए) इस के लिए generalises:

def new(im): 
    rows,cols = im.shape 
    final = np.zeros((rows, cols, 3, 3)) 
    for x in (0,1,2): 
     for y in (0,1,2): 
      im1 = np.vstack((im[x:],im[:x])) 
      im1 = np.column_stack((im1[:,y:],im1[:,:y])) 
      final[x::3,y::3] = np.swapaxes(im1.reshape(rows/3,3,cols/3,-1),1,2) 
    return final 

तेजी से सभी स्लाइस (नीचे) के माध्यम से पाशन को यह new समारोह मुकाबले timeit का उपयोग कर, अपने बारे में 4 बार 300 * 300 सरणी के लिए।

def old(im): 
    rows,cols = im.shape 
    s = [] 
    for x in xrange(1,rows): 
     for y in xrange(1,cols): 
      s.append(im[x-1:x+2,y-1:y+2]) 
    return s 
+0

धन्यवाद। मैंने यह सब ठीक से कोड की एक छोटी सी पंक्ति में कम करने में कामयाब रहा - दुर्भाग्य से, MATLAB (im2col फ़ंक्शन) में। क्या इस समारोह में पाइथन में प्रत्यक्ष समतुल्य है? –

+0

@ वेलवेटगोस्ट आईएम 2col सिर्फ एक ऐसा कार्य है जो एक कार्यान्वयन [जैसे मेरा] (http://stackoverflow.com/a/10900022/709852) या ऊपर वाला एक (हालांकि थोड़ा और पॉलिश के साथ) लपेटता है। MATLAB कार्यान्वयन जादुई रूप से कोड को हटा नहीं देता है। यदि आप अपने स्वयं के फ़ंक्शन का उपयोग कर सकते हैं, तो बेहतर होगा क्योंकि आप काम करने के लिए महंगे टूलबॉक्स पर निर्भर नहीं हैं (जैसे MATLAB का आनंद)। साथ ही, यह न मानें कि यह टूलबॉक्स में है, यह तेज़ या कुशल है। –

+0

@ हेनरीगोमरल: धन्यवाद! हां, मुझे पता है कि MATLAB जादुई रूप से कोड को हटा नहीं देता है। एक समय सीमा के तहत कोड लिखते समय मुझे बस इतना आसान और तेज मिला। हालांकि आपके पायथन कार्यान्वयन के लिए बहुत बहुत धन्यवाद। जब मुझे थोडा समय लगेगा तो यह मुझे पाइथन के बारे में और जानने में मदद करेगा। –

1

मुझे लगता है कि आप निम्नलिखित के बाद क्या करते हैं। लूप केवल 9 तत्वों से अधिक है। मुझे यकीन है कि इसे सदिश बनाने का एक तरीका है, लेकिन शायद यह प्रयास के लायक नहीं है।

import numpy 

im = numpy.random.randint(0,50,(5,7)) 

# idx_2d contains the indices of each position in the array 
idx_2d = numpy.mgrid[0:im.shape[0],0:im.shape[1]] 

# We break that into 2 sub arrays 
x_idx = idx_2d[1] 
y_idx = idx_2d[0] 

# The mask is used to ignore the edge values (or indeed any values). 
mask = numpy.ones(im.shape, dtype='bool') 
mask[0, :] = False 
mask[:, 0] = False 
mask[im.shape[0] - 1, :] = False 
mask[:, im.shape[1] - 1] = False 

# We create and fill an array that contains the lookup for every 
# possible 3x3 array. 
idx_array = numpy.zeros((im[mask].size, 3, 3), dtype='int64') 

# Compute the flattened indices for each position in the 3x3 grid 
for n in range(0, 3): 
    for m in range(0, 3): 
     # Compute the flattened indices for each position in the 
     # 3x3 grid 
     idx = (x_idx + (n-1)) + (y_idx + (m-1)) * im.shape[1] 

     # mask it, and write it to the big array 
     idx_array[:, m, n] = idx[mask] 


# sub_images contains every valid 3x3 sub image 
sub_images = im.ravel()[idx_array] 

# Finally, we can flatten and sort each sub array quickly 
sorted_sub_images = numpy.sort(sub_images.reshape((idx[mask].size, 9))) 
1

के रूप में matlab समारोह im2col (...)

import numpy as np 

def im2col(Im, block, style='sliding'): 
    """block = (patchsize, patchsize) 
     first do sliding 
    """ 
    bx, by = block 
    Imx, Imy = Im.shape 
    Imcol = [] 
    for j in range(0, Imy): 
     for i in range(0, Imx): 
      if (i+bx <= Imx) and (j+by <= Imy): 
       Imcol.append(Im[i:i+bx, j:j+by].T.reshape(bx*by)) 
      else: 
       break 
    return np.asarray(Imcol).T 

if __name__ == '__main__': 
    Im = np.reshape(range(6*6), (6,6)) 
    patchsize = 3 
    print Im 
    out = im2col(Im, (patchsize, patchsize)) 
    print out 
    print out.shape 
    print len(out) 
संबंधित मुद्दे