多次元画像拡張エロージョンと開閉操作

原理と機能:

形態学的画像処理の理論的基礎は数学的形態学であり、形態学的処理を通じて境界情報などの画像内の意味のある領域を取得できます。

3afe58d3f63776b603d347c2ce40a3fe.png

1. 腐食は、境界点を除去し、境界を内側に縮小するプロセスです。小さくて意味のないオブジェクトを削除するために使用できます。

腐食原理:

3x3 の構造要素を使用して画像の各ピクセルをスキャンし、構造要素とそれに含まれるバイナリ イメージを使用して「AND」演算を実行します。両方が 1 の場合、結果の画像のピクセルは 1 になります。それ以外の場合は 0。

2. 膨張とは、オブジェクトと接触しているすべての背景点をオブジェクトにマージし、境界を外側に拡張するプロセスです。オブジェクトの穴を埋めるために使用できます。

拡張原理:

3x3 の構造要素を使用してイメージの各ピクセルをスキャンし、構造要素とそれがカバーするバイナリ イメージで「AND」演算を実行します。両方が 0 の場合、結果のイメージのピクセルは 0 になります。それ以外の場合は 1。

3. 最初の侵食とその後の拡張のプロセスは、オープニング操作と呼ばれます。小さなオブジェクトを削除し、オブジェクトを細い点で分離し、大きなオブジェクトの領域を大きく変えることなく境界を滑らかにするために使用されます。

4. 最初に膨張し、次に腐食するプロセスを密閉操作と呼びます。オブジェクトの小さな穴を埋めたり、隣接するオブジェクトを接続したり、領域を大きく変えることなく境界を滑らかにしたりするために使用されます。

2 次元画像であろうと 3 次元画像であろうと、拡張侵食および開閉操作には非常に重要な用途があります。以下は 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

2次元の円形展開

循環畳み込みカーネルを作成する

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