在python中为不规则图像添加边框

时间:2017-11-22 12:23:40

标签: python image numpy

我想为不规则的三维图像添加边框,该图像存储为二进制numpy数组。我想过可能将图像左/右,前/后,上/下移动,然后组合这6个图像并减去原始图像;使用以下代码:

#make copy of the image shifted one voxel to the left
image_border = np.zeros((img_dim[0], img_dim[1], img_dim[2]))    
for x in xvoxels:
    x_slice_original = image[x, :, :]
    x_slice_new = np.zeros((img_dim[1], img_dim[2]))
    for y in yvoxels:
        for z in zvoxels:
            if x_slice_original[y, z] == 1:
                x_slice_new[(y-1), z] = 1
            else:
                x_slice_new[(y-1), z] = 0
    image_border[x, :, :] = x_slice_new

这似乎有点低效,但是想知道是否有人有更整洁的解决方案?

编辑: 该图像是MRI图像91 * 109 * 91体素。 xvoxels和zvoxels是0:90的列表,yvoxels是0:108的列表。有问题的图像的2D切片如下:enter image description here

2 个答案:

答案 0 :(得分:0)

这是一个使用scipy.ndimage.binary_dilation的非常简单的方法,它本质上是您所考虑的操作的库版本。剩下要做的就是将原始体素清空。正如你所看到的那样,整个事物在一条线上舒适地适合。

import numpy as np
from scipy import ndimage

# create mock data
i,j,k = np.ogrid[:10,:10,:10]
ball = ((i-5)**2+(j-5)**2+(k-5)**2 < 16).view(np.int8)

# create border
shell = (ndimage.binary_dilation(ball) & ~ball).view(np.int8)

# that's all folks, show one section of original and border
print(ball[5])
# [[0 0 0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 0 0 0 0]
#  [0 0 0 1 1 1 1 1 0 0]
#  [0 0 1 1 1 1 1 1 1 0]
#  [0 0 1 1 1 1 1 1 1 0]
#  [0 0 1 1 1 1 1 1 1 0]
#  [0 0 1 1 1 1 1 1 1 0]
#  [0 0 1 1 1 1 1 1 1 0]
#  [0 0 0 1 1 1 1 1 0 0]
#  [0 0 0 0 0 0 0 0 0 0]]
print(shell[5])
# [[0 0 0 0 0 0 0 0 0 0]
#  [0 0 0 1 1 1 1 1 0 0]
#  [0 0 1 0 0 0 0 0 1 0]
#  [0 1 0 0 0 0 0 0 0 1]
#  [0 1 0 0 0 0 0 0 0 1]
#  [0 1 0 0 0 0 0 0 0 1]
#  [0 1 0 0 0 0 0 0 0 1]
#  [0 1 0 0 0 0 0 0 0 1]
#  [0 0 1 0 0 0 0 0 1 0]
#  [0 0 0 1 1 1 1 1 0 0]]

答案 1 :(得分:0)

您想要做的是一个名为'扩张'的过程。对于二进制图像,您的想法是循环遍历图像中的所有像素。如果像素为“True”,则在其周围创建一组指定像素也为“True”(由“内核”或“结构”定义)。例如

0,0,0,0,0
0,0,0,0,0
0,0,1,1,0
0,0,0,0,0
0,0,0,0,0

带内核

0,1,0
1,1,1
0,1,0
  1. 当达到(2,2)时,它变为:

    0,0,0,0,0
    0,0,1,0,0
    0,1,1,1,0
    0,0,1,0,0
    0,0,0,0,0
    
  2. 到达(2,3)时变为:

    0,0,0,0,0
    0,0,1,1,0
    0,1,1,1,1
    0,0,1,1,0
    0,0,0,0,0
    
  3. 您可以重复此操作,或使用其他内核。例如:

    import scipy.ndimage
    import numpy as np
    import matplotlib.pyplot as plt
    
    im = np.zeros((90,90),dtype='bool')
    im[30:61,30:61] = True
    
    fig = plt.figure(figsize=(18,6))
    fig.set_tight_layout(True)
    
    fig.add_subplot(1,3,1)
    plt.imshow(im,interpolation='nearest')
    
    fig.add_subplot(1,3,2)
    plt.imshow(scipy.ndimage.binary_dilation(im,iterations=4),interpolation='nearest')
    
    fig.add_subplot(1,3,3)
    plt.imshow(scipy.ndimage.binary_dilation(im,iterations=4,structure=np.ones((3,3))),interpolation='nearest')
    
    plt.show()
    

    结果:

    enter image description here

      

    当然,获取“外部”边界只是扩张图像和原始图像的差异。