在图像上找到3x3滑动窗口 [英] Find a 3x3 sliding window over an image

查看:211
本文介绍了在图像上找到3x3滑动窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张图片。

我想为图片中的每个像素获取一个3x3窗口(相邻像素)。

I want to obtain a 3x3 window (neighbouring pixels) for every pixel in the image.

我有这个Python代码:

I have this Python code:

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窗口。 cent是中心像素。

mask5 is the 3x3 window. cent is the center pixel.

有没有更有效的方法来做到这一点 - 即使用map,iterators - 除了我使用的两个嵌套循环之外的任何东西?

Is there a more efficient way to do this - i.e. using maps, iterators - anything but the two nested loops I've used?

推荐答案

这可以通过重新整形和交换轴,然后重复所有内核元素来更快地完成,如下所示:

This can be done faster, by reshaping and swapping axes, and then repeating over all kernel elements, like this:

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

这给你一个3 * 3的数组在表面上划线的瓷砖:

This gives you an array of 3*3 tiles which tessalates across the surface:

[[[[ 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]]]]

要获得重叠的瓷砖,我们需要再重复8次,但是'通过使用 vstack column_stack 的组合来包装数组。请注意,右侧和底部图块阵列环绕(可能是您想要的,也可能不是,取决于您如何处理边缘条件):

To get the overlapping tiles we need to repeat this 8 further times, but 'wrapping' the array, by using a combination of vstack and column_stack. Note that the right and bottom tile arrays wrap around (which may or may not be what you want, depending on how you are treating edge conditions):

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整除的数组):

Doing it this way you wind up with 9 sets of arrays, so you then need to zip them back together. This, and all the reshaping generalises to this (for arrays where the dimensions are divisible by 3):

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

比较新的函数循环遍历所有切片(下面),使用 timeit ,大约快4倍,对于300 * 300阵列。

Comparing this new function to looping through all the slices (below), using timeit, its about 4 times faster, for a 300*300 array.

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

这篇关于在图像上找到3x3滑动窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆