我想仅使用 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 通道而不对其进行卷积。
非常感谢任何帮助:D
这似乎是一个标准化错误。我对代码做了一些小的修改,但最重要的修改是
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