multidimensional filtering

Overview:

Noise has a great impact on image processing, and it affects the input, acquisition and processing of image processing, as well as the output results. Therefore, before performing other image processing, it is necessary to perform denoising processing on the image. Especially in medical images, there may be a large amount of 3D data. This article will gradually implement 2D and 3D common filtering.

1. Mean filtering

Mean filtering is the most commonly used method in image processing. From the perspective of frequency domain, mean filtering is a low-pass filter, and high-frequency signals will be removed, so it can help eliminate sharp image noise and achieve image smoothing, blurring and other functions. . The ideal mean filter is to replace each pixel in the image with the average value calculated for each pixel and its surrounding pixels. The sampled Kernel data is usually a 3X3 matrix, represented as follows:

Red is the center pixel, calculate the average of nine pixels, and replace the center pixel.

033a52c7ce9fe2a1104779a18fadf70f.png

Advantages: simple algorithm, fast calculation speed;

Disadvantages: While reducing noise, the image will be blurred, especially the edges and details of the scene.

2. Median filtering

Median filtering is also one of the most common means of eliminating image noise, especially to eliminate salt and pepper noise. The effect of median filtering is better than that of mean filtering. The median filter is to sort the surrounding pixels and the central pixel, and take the median value. A 3X3 size median filter is as follows:

e0e5eef10edd29a7840e6379a2300c90.png

Advantages: the suppression effect is very good, and the clarity of the picture is basically maintained;

Disadvantages: The suppression effect on Gaussian noise is not very good.

3. Gaussian filtering

Gaussian filter is a linear filter that can effectively suppress noise and smooth images. Its working principle is similar to the mean filter, and the mean value of the pixels in the filter window is taken as the output. The coefficient of the window template is different from that of the mean filter, and the template coefficient of the mean filter is the same as 1; while the template coefficient of the Gaussian filter decreases as the distance from the center of the template increases. Therefore, the Gaussian filter blurs the image less than the mean filter. The two-dimensional Gaussian function is as follows:

26e20c4878fd066160b931279bc7cfed.png

A 3X3 size Gaussian filter is as follows:

41b36551e6efb36e4bc99f0321c28357.png

A convolutional block that quickly divides an image into chunks:

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-1)].transpose(0,3,2,1)
    return result

Gaussian 2d fast filtering:

def GaussianFilter2d_speed(img,K_size,sigma):#单通道,K_size[h,w]
    #生成卷积块
    data = conv2d_data(img,K_size)
    
    #生成卷积核
    padd_h = K_size[0]//2
    padd_w = K_size[1]//2
    K = np.zeros((K_size[0],K_size[1]),dtype=np.float)
    for x in range(-padd_w,-padd_w+K_size[1]):
        for y in range(-padd_h,-padd_h+K_size[0]):
            K[y+padd_h,x+padd_w] = np.exp(-(x**2+y**2)/(2*(sigma**2)))
    K /= (sigma**2*2*np.pi)
    K /=  K.sum()
    
    #滤波
    result = np.squeeze(np.einsum("abef,fg->abeg",data.reshape(data.shape[0], data.shape[1], 1, -1) ,K.reshape(-1, 1)))
    return result

The above code only needs to replace the convolution and part to complete most of the filtering operations.

The three-dimensional Gaussian function is as follows:

175e55dd37c5340549ca259448b7f2ad.png

Quickly divide 3d convolutional blocks:

def conv3d_data2(data,k_size):#stride只能是1,pad是旁边填0,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

Gaussian 3d fast filtering:

def GaussianFilter3d_speed(img,K_size,sigma):#单通道,K_size[h,w]
    #生成卷积块
    data = conv3d_data2(img,K_size)
    
    #生成卷积核
    padd_c = K_size[0]//2
    padd_h = K_size[1]//2
    padd_w = K_size[2]//2
    K = np.zeros((K_size[0],K_size[1],K_size[2]),dtype=np.float)
    for x in range(-padd_w,-padd_w+K_size[2]):
        for y in range(-padd_h,-padd_h+K_size[1]):
            for z in range(-padd_c,-padd_c+K_size[0]):
                K[z+padd_c,y+padd_h,x+padd_w] = np.exp(-(x**2+y**2+z**2)/(2*(sigma**2)))
    K /= (sigma*np.sqrt(2*np.pi))**3
    K /=  K.sum()
    
    #滤波
    result = np.squeeze(np.einsum("abcdef,dfg->abcdeg",data.reshape(data.shape[0], data.shape[1], data.shape[2], 1, 1, -1) ,K.reshape(1, -1, 1)))
    return result

Most of the 3d filtering operations can be done by simply replacing the above convolution and part. The data of [300,512,512] takes about 10s.

The above code is the result of my optimization after many times. If anyone has a better optimization method, welcome to private message me or leave me a message.

Guess you like

Origin blog.csdn.net/weixin_41202834/article/details/121173753