多维图像膨胀腐蚀与开闭运算

原理及作用:

形态学图像处理的理论根基是数学形态学(Mathematical Morphology),可以通过形态学处理获取图像中有意义的区域,比如边界信息。

3afe58d3f63776b603d347c2ce40a3fe.png

1. 腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。

腐蚀原理:

用3x3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为1,结果图像的该像素为1。否则为0。

2. 膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。

膨胀原理:

用3x3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为0,结果图像的该像素为0。否则为1。

3. 先腐蚀后膨胀的过程称为开运算。用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。

4. 先膨胀后腐蚀的过程称为闭运算。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。

扫描二维码关注公众号,回复: 16374308 查看本文章

不管是在二维图像还是三维图像中,膨胀腐蚀与开闭运算都有很重要的应用。下面将使用numpy来实现。(如果想要进一步加速的,可以使用cuda版本的numpy,cupy进行加速)。

膨胀

2d矩形膨胀

def conv2d_data2(data,k_size):
    padd_h = k_size[0]//2
    padd_w = k_size[1]//2
    x_pad = np.pad(data,((padd_h,padd_h),(padd_w,padd_w)))
    h_num = data.shape[0]
    w_num = data.shape[1]
    temp_h = np.array([x_pad[i:i+k_size[0],:] for i in range(h_num)])
    temp_w = np.array([temp_h]*k_size[1]).transpose([1,0,2,3])
    for i in range(1,k_size[1]):
        temp_w[:,i,:,:-i] = temp_w[:,i,:,i:]
    result = temp_w[:,:,:,:-(k_size[1]-1)].transpose(0,3,2,1)
    return result  
def dilate_rect2d(img,K_size):
    data = conv2d_data2(img>0,K_size)
    K = np.ones(K_size)
    result = np.einsum("abef,ef->ab",data,K)
    result = (result>0)*1
    return result

2d圆形膨胀

制作圆形卷积核

def generate_mask2d(img_height,img_width,radius,center_y,center_x):
    y = np.array(list(range(img_height))).reshape([img_height,1])
    x = np.array(list(range(img_width))).reshape([1,img_width])
    mask = (x-center_x)**2+(y-center_y)**2<=radius**2  
    return mask

圆形膨胀代码:

def dilate_circle2d(img,K_size):
    data = conv2d_data2(img>0,K_size)
    r = int(np.min(K_size)//2)
    center_y = int(K_size[0]//2)
    center_x = int(K_size[1]//2)
    K = generate_mask2d(K_size[0],K_size[1],r,center_y,center_x)*1
    result = np.einsum("abef,ef->ab",data,K)
    result = (result>0)*1
    return result

3d膨胀代码

矩形

def conv3d_data2(data,k_size):#k_size[c,h,w]
    padd_c = k_size[0]//2
    padd_h = k_size[1]//2
    padd_w = k_size[2]//2
    x_pad = np.pad(data,((padd_c,padd_c),(padd_h,padd_h),(padd_w,padd_w)))
    c_num = data.shape[0]
    h_num = data.shape[1]
    w_num = data.shape[2]
    temp_c = np.array([x_pad[i:i+k_size[0],:,:] for i in range(c_num)])
    temp_h = np.array([temp_c[:,:,i:i+k_size[1],:] for i in range(h_num)])
    temp_w = np.array([temp_h]*k_size[2]).transpose([2,1,0,3,4,5])
    for i in range(1,k_size[2]):
        temp_w[:,:,i,:,:,:-i] = temp_w[:,:,i,:,:,i:]
    result = temp_w[:,:,:,:,:,:-(k_size[2]-1)].transpose([0,1,5,3,4,2])
    return result 
def dilate_rect3d(img,K_size):
    data = conv3d_data2(img>0,K_size)
    K = np.ones(K_size)
    result = np.einsum("abcdef,def->abc",data,K)
    result = (result>0)*1
    return result

3d圆形膨胀

def generate_mask3d(img_depth,img_height,img_width,radius,center_z,center_y,center_x):
    y = np.array(list(range(img_height))).reshape([1,img_height,1])
    x = np.array(list(range(img_width))).reshape([1,1,img_width])
    z = np.array(list(range(img_depth))).reshape([img_depth,1,1])
    mask = (x-center_x)**2+(y-center_y)**2+(z-center_z)**2<=radius**2  
    return mask
def dilate_circle3d(img,K_size):
    data = conv3d_data2(img>0,K_size)
    r = int(np.min(K_size)//2)
    center_z = int(K_size[0]//2)
    center_y = int(K_size[1]//2)
    center_x = int(K_size[2]//2)
    K = generate_mask3d(K_size[0],K_size[1],K_size[2],r,center_z,center_y,center_x)*1
    result = np.einsum("abcdef,def->abc",data,K)
    result = np.array(result>0)*1
    return result

腐蚀

2d矩形腐蚀

def erode_rect2d(img,K_size):
    data = conv2d_data2(img>0,K_size)
    K = np.ones(K_size)
    summ = K.shape[0]*K.shape[1]
    result = np.einsum("abef,ef->ab",data,K)
    result = (result==summ)*1
    return result

2d圆形腐蚀

def erode_circle2d(img,K_size):
    data = conv2d_data2(img>0,K_size)
    r = int(np.min(K_size)//2)
    center_y = int(K_size[0]//2)
    center_x = int(K_size[1]//2)
    K = generate_mask2d(K_size[0],K_size[1],r,center_y,center_x)*1
    summ =np.sum(K)
    result = np.einsum("abef,ef->ab",data,K)
    result = (result==summ)*1
    return result

3d矩形腐蚀

def erode_rect3d(img,K_size):
    data = conv3d_data2(img>0,K_size)
    K = np.ones(K_size)
    summ = K.shape[0]*K.shape[1]*K.shape[2]
    result = np.einsum("abcdef,def->abc",data,K)
    result = (result==summ)*1
    return result

3d圆形腐蚀

def erode_circle3d(img,K_size):
    data = conv3d_data2(img>0,K_size)
    r = int(np.min(K_size)//2)
    center_z = int(K_size[0]//2)
    center_y = int(K_size[1]//2)
    center_x = int(K_size[2]//2)
    K = generate_mask3d(K_size[0],K_size[1],K_size[2],r,center_z,center_y,center_x)*1
    summ =np.sum(K)
    result = np.einsum("abcdef,def->abc",data,K)
    result = (result==summ)*1
    return result

开闭运算

开闭运算只需进行相应的腐蚀膨胀运算,此处不再放上代码。

猜你喜欢

转载自blog.csdn.net/weixin_41202834/article/details/121173759