似乎无法使用 Numpy 重新创建高斯模糊

问题描述 投票:0回答:1

我想仅使用 Numpy 实现高斯模糊(类似于 cv2.GaussianBlur),但我似乎不明白如何处理 alpha 通道。我的代码:

# 1D Gaussian PD Function
def gauss(x, sigma):
    g= (1/(((2*np.pi)**0.5)*sigma))* np.exp((-x**2)/(2*sigma**2))
    return g
def gaussian_filter(image, sigma, padding=True):
    
    ks= 2*(3*sigma)+1    #Height/ Width of Kernel. Using a Rule of Thumb explained in one of the books.
    image_result= np.zeros((image.shape[0], image.shape[1], image.shape[2]))
    
    if padding == True   #Using the appropriate padding to preserve dimensions
        pad= int((ks-1)/2)
        image= np.pad(image, ((pad,pad),(pad,pad),(0,0)))
           
    k= np.arange(-(ks-1)/2, ks/2)   # A simple array of size ks centred around 0 
    kernel= gauss(k, sigma)         # The corresponding Gaussian PD values with mean 0.
    kernel= kernel[:, np.newaxis]   
    kernel= [email protected]         #Using property of 2D Gaussian i.e product of two 1D Gaussians 
    kernel=kernel[:,:, np.newaxis]  
    
    h= kernel     #Adding another dimension to match the number of channels of img
    for i in range(image.shape[2]-1):
        kernel= np.concatenate((kernel, h), axis=2)
           
    for i in range(image_result.shape[0]):    #Convolution step
        for j in range(image_result.shape[1]):
            temp= image[i:i+ks, j:j+ks, :]
            temp= temp*kernel
            image_result[i,j] = (1/(ks*ks))*np.sum(np.sum(temp, axis= 0), axis=0)
    '''    
    ad= np.ones((image_result.shape[0], image_result.shape[1],1))     # Not sure about alpha channel. Tried setting it to maximum value.
    image_result= np.concatenate((image_result[:,:,0:3],ad), axis=2)
    '''
    return image_result

我通读了简历文档和维基百科来提出这个实现。但当我增加标准差时,图像会变得更暗。另外,结果与 cv2.GaussianBlur 生成的结果不一致,cv2.GaussianBlur 似乎保留了 alpha 通道而不对其进行卷积。 My results

非常感谢任何帮助:D

python numpy opencv gaussianblur
1个回答
0
投票

这似乎是一个标准化错误。我对代码做了一些小的修改,但最重要的修改是

kernel2d /= np.sum(kernel2d) * 255 

我以这种方式规范化内核并删除了

1 / (ks * ks)

因素。这是我的版本,它适用于我这边的 3 通道图像,请告诉我它是否也适用于 4 通道图像!

def gaussian_filter(image, sigma, padding=True):
    
    ks = 2 * (3 * sigma) + 1                # Height/ Width of Kernel. Using a Rule of Thumb explained in one of the books.
    image_result = np.zeros(image.shape)
    
    if padding == True:   #Using the appropriate padding to preserve dimensions
        pad = int((ks - 1) / 2)
        image = np.pad(image, ((pad,pad), (pad,pad), (0,0)), mode='reflect')
           
    k = np.arange(-(ks-1)/2, ks/2)            # A simple array of size ks centred around 0 
    kernel1d = gauss(k, sigma)                # The corresponding Gaussian PD values with mean 0.  
    kernel2d = np.outer(kernel1d, kernel1d)   # Using property of 2D Gaussian i.e product of two 1D Gaussians 
    kernel2d /= np.sum(kernel2d) * 255        # Normalising the kernel
           
    for i in range(image_result.shape[0]):    # Convolution step
        for j in range(image_result.shape[1]):
            temp = image[i:i+ks, j:j+ks, :]
            temp = temp * kernel2d[..., np.newaxis]
            image_result[i,j] = np.sum(temp, axis=(0,1))

    return image_result
© www.soinside.com 2019 - 2024. All rights reserved.