嵌套for循环到numpy convolve

时间:2013-02-07 18:46:11

标签: python numpy convolution

如何提高此功能的速度?

def foo(mri_data, radius):

    mask = mri_data.copy()

    ny = len(mri_data[0,:])
    nx = len(mri_data[:])

    for y in xrange(0, ny):
        for x in xrange(0, nx):
            if (mri_data[x-radius:x+radius,y-radius:y+radius] != 1.0).all():
                mask[x,y] = 0.0                    
    return mask.copy() 

它采用numpy数组形式的图像切片。迭代每个像素并测试该像素周围的边界框。如果框中的值不等于1,则通过将其设置为0来丢弃该像素。

我被告知我可以使用numpy.convolve,但我不确定这是如何相关的。

编辑:图像值在二进制范围内,因此最低值为0.0,最大值为1.0。值介于ex:0.767之间。

2 个答案:

答案 0 :(得分:3)

您可以滥用卷积的一个案例。我不会使用它,但边界是另外繁琐的......

from scipy.ndimage import convolve

not_one = (mri_data != 1.0) # are you sure you want to compare with float like that?!

conv = convolve(not_one, np.ones((2*radius, 2*radius)))
all_not_one = (conv == (2*radius)**2)

mask[all_not_one] = 0

真的应该做同样的事情......

答案 1 :(得分:3)

您正在做的事情被称为binary_dilation但您的代码中存在一个小错误。特别是当x,y小于radius时,你得到负指数。使用numpy索引规则解释这些负数,这不是您想要的more on indexing here,在图像的两个边缘给出错误的结果。

以下是一些使用二进制扩张来完成相同操作的代码,并修复了上述错误。

import numpy as np
from scipy.ndimage import binary_dilation

def foo(mri_data, radius):
    structure = np.ones((2*radius, 2*radius))
    # I set the origin here to match your code
    mask = binary_dilation(mri_data == 1, structure, origin=-1)
    return np.where(mask, mri_data, 0)
相关问题