将图像与内核 returns 空图像进行卷积
Convolving an image with kernel returns empty image
我接受了挑战,在 Python 中自己实现了一些 OpenCV 函数。这些函数中有很多都需要将图像与内核进行卷积,所以这是我为此编写的函数:
def convolve(img, kernel): # img should have zero padding
kx, ky = kernel.shape # kernel is square so kx == ky
start, end = floor(kx / 2), ceil(kx / 2)
x, y = img.shape
convolved = np.zeros((x, y))
for i in range(kx, x - kx):
for j in range(kx, y - kx):
convolved_area = img[i - start:i + end, j - start:j + end] * kernel
convolved[i][j] = np.sum(convolved_area)
return convolved
当我 运行 在我制作的图像和内核上执行此操作时,我收到了一张白色图像,唯一的颜色是黑色填充。
为了测试,我使用的内核是高斯内核:
for x in range(radius):
for y in range(radius): # Generate kernel with formula
kernel[x][y] = exp( -0.5 * (pow((x-mean)/sigma, 2.0) + pow((y-mean)/sigma,2.0)) ) / (2 * pi * sigma * sigma)
magnitude += kernel[x][y]
for x in range(radius): # normalize kernel
for y in range(radius):
kernel[x][y] /= magnitude
我知道内核可以工作,因为使用 OpenCV 的 filter2D
函数对我有用:
convolved = cv2.filter2D(img, -1, kernel)
我的问题是为什么我的 convolve
功能不起作用?
您需要为位于
的图像指定 uint8
的数据类型
convolved = np.zeros((x, y))
成功
convolved = np.zeros((x, y), 'uint8')
但是我建议使用np.zeros_like()
方法,它接受一个数组,returns数组用零填充,保留原始数据类型数组,这样您就不必指定 uint8
:
convolved = np.zeros_like(img)
以上是最实用的,还有几个备选方案
convolved = np.zeros((x, y)).astype('uint8')
和
convolved = np.uint8(np.zeros((x, y))
我接受了挑战,在 Python 中自己实现了一些 OpenCV 函数。这些函数中有很多都需要将图像与内核进行卷积,所以这是我为此编写的函数:
def convolve(img, kernel): # img should have zero padding
kx, ky = kernel.shape # kernel is square so kx == ky
start, end = floor(kx / 2), ceil(kx / 2)
x, y = img.shape
convolved = np.zeros((x, y))
for i in range(kx, x - kx):
for j in range(kx, y - kx):
convolved_area = img[i - start:i + end, j - start:j + end] * kernel
convolved[i][j] = np.sum(convolved_area)
return convolved
当我 运行 在我制作的图像和内核上执行此操作时,我收到了一张白色图像,唯一的颜色是黑色填充。
为了测试,我使用的内核是高斯内核:
for x in range(radius):
for y in range(radius): # Generate kernel with formula
kernel[x][y] = exp( -0.5 * (pow((x-mean)/sigma, 2.0) + pow((y-mean)/sigma,2.0)) ) / (2 * pi * sigma * sigma)
magnitude += kernel[x][y]
for x in range(radius): # normalize kernel
for y in range(radius):
kernel[x][y] /= magnitude
我知道内核可以工作,因为使用 OpenCV 的 filter2D
函数对我有用:
convolved = cv2.filter2D(img, -1, kernel)
我的问题是为什么我的 convolve
功能不起作用?
您需要为位于
的图像指定uint8
的数据类型
convolved = np.zeros((x, y))
成功
convolved = np.zeros((x, y), 'uint8')
但是我建议使用np.zeros_like()
方法,它接受一个数组,returns数组用零填充,保留原始数据类型数组,这样您就不必指定 uint8
:
convolved = np.zeros_like(img)
以上是最实用的,还有几个备选方案
convolved = np.zeros((x, y)).astype('uint8')
和
convolved = np.uint8(np.zeros((x, y))