我有一个2d
numpy
array
包含从到的greyscale
像素值。我想做的是从头开始创建一个. 我已经编写了一个生成高斯函数的函数:0
255
gaussian filter
normalized
kernel
def gaussianKernel(size, sigma):
kernel = np.fromfunction(lambda x, y: (1/(2*math.pi*sigma**2)) * math.e ** ((-1*((x-(size-1)/2)**2+(y-(size-1)/2)**2))/(2*sigma**2)), (size, size))
return kernel / np.sum(kernel)
效果很好:
>>> vision.gaussianKernel(5, 1.5)
array([[ 0.01441882, 0.02808402, 0.0350727 , 0.02808402, 0.01441882],
[ 0.02808402, 0.05470021, 0.06831229, 0.05470021, 0.02808402],
[ 0.0350727 , 0.06831229, 0.08531173, 0.06831229, 0.0350727 ],
[ 0.02808402, 0.05470021, 0.06831229, 0.05470021, 0.02808402],
[ 0.01441882, 0.02808402, 0.0350727 , 0.02808402, 0.01441882]])
因此,我创建了一个基本convolution
函数来将其kernel
应用于每个函数pixel
并产生gaussian
模糊:
def gaussianBlurOld(img, kSize, kSigma):
kernel = gaussianKernel(kSize, kSigma)
d = int((kSize-1)/2)
gaussian = np.zeros((img.shape[0]-2*d, img.shape[1]-2*d))
for y in range(d, img.shape[0]-d):
for x in range(d, img.shape[1]-d):
gaussian[y-d][x-d] = np.sum(np.multiply(img[y-d:y+d+1, x-d:x+d+1], kernel))
return gaussian
它工作正常并且模糊了图像,但是,由于这段代码最终将在树莓派上运行,我需要它高效并且速度更快。因此,感谢我昨天提出的关于如何加速边缘检测器的问题的答案Sobel
,我尝试将他给出的相同逻辑应用于gaussian
过滤器。但是,由于function
将接受 的variable
大小参数kernel
,因此与设置的Sobel
内核大小(即3x3
.
如果我正确理解了解释,我需要首先将内核分成x
和y
组件,这可以通过使用原始的顶部row
和左侧来完成(显然它们是相同的,但我决定将它们分开,因为我有内核已经计算)。下面是分离的矩阵:column
kernel
2d
从这些row
和column
向量中,我需要遍历每个值并将'window'
数组的值乘以它的元素。在每个之后,将减小的窗口大小沿数组向右移动。为了更清楚地显示我认为我需要做的事情,这些是'windows'
我正在谈论的 3 个不同kernel
大小的小图像3x3
:
_______3_______
_____|_2_______ |
_____|_1__|____| | |
| | | | | |
|123,|213,|124,|114,|175|
|235,|161,|127,|215,|186|
|128,|215,|111,|141,|221|
|224,|171,|193,|127,|117|
|146,|245,|129,|213,|221|
|152,|131,|150,|112,|171|
因此,对于每个'window'
,您乘以index
内核中该窗口的 并将其添加到总数中。
然后,获取已应用内核x
组件的img 并对组件执行相同操作。gaussian
y
这些是我认为我可以gaussian
比使用上述方法更快地计算模糊的步骤nested
for-loops
,这是我编写的尝试执行此操作的代码:
def gaussianBlur(img, kSize, kSigma):
kernel = gaussianKernel(kSize, kSigma)
gausX = np.zeros((img.shape[0], img.shape[1] - kSize + 1))
for i, v in enumerate(kernel[0]):
gausX += v * img[:, i : img.shape[1] - kSize + i + 1]
gausY = np.zeros((gausX.shape[0] - kSize + 1, gausX.shape[1]))
for i, v in enumerate(kernel[:,0]):
gausY += v * gausX[i : img.shape[0] - kSize + i + 1]
return gausY
我的问题是这个函数产生了正确的“模糊效果”,但由于某种原因0
,输出值都介于两者之间。幸运的是,由于某些其他原因,仍然可以正常显示输出,因此我可以检查它是否正确模糊了图像。3
floats
matplotlib
问题很简单:为什么像素值输出在0
和之间3
?
我已经调试了几个小时,但找不到原因。我很确定某处只有一点缩放细节,但我就是找不到。任何帮助将非常感激!