我正在使用 OpenCV 和 NumPy 对 Python 中的图像应用 Sobel 滤波器,并且我预计应用滤波器后输出的尺寸会更小。根据方程output = input - kernel_size // stride + 1,我认为输出应该比输入小内核大小(在本例中为3)。但是,当我应用 Sobel 滤波器时,输出图像尺寸与输入图像保持相同。
这是我正在使用的代码:
import cv2
import numpy as np
input_image = cv2.imread('img3.pgm', cv2.IMREAD_GRAYSCALE)
print(f"length of input image rows : {len(input_image)}")
print(f"length of input image columns: {len(input_image[0])}")
sobel_x = cv2.Sobel(input_image, cv2.CV_64F, 1, 0, ksize=3) # Sobel in x-direction
sobel_y = cv2.Sobel(input_image, cv2.CV_64F, 0, 1, ksize=3) # Sobel in y-direction
edge_magnitude = cv2.magnitude(sobel_x, sobel_y)
edge_magnitude_cropped = np.clip(edge_magnitude, 0, 255).astype(np.uint8)
print(f"length of filtered_image row {len(edge_magnitude_cropped)}" )
print(f"length of filtered_image col {len(edge_magnitude_cropped[0])}" )
cv2.imwrite('filtered_image_cv_cropped.pgm', edge_magnitude_cropped)
print("\nFiltered image saved as 'filtered_image_cv.pgm'.")
with open('original_image_cv_cropped.txt', 'w') as f:
for row in input_image:
f.write(" ".join(str(pixel) for pixel in row) + "\n")
print("\nOriginal image data saved as 'original_image_cv.txt'.")
with open('filtered_image_cv_cropped.txt', 'w') as f:
for row in edge_magnitude_cropped:
f.write(" ".join(str(pixel) for pixel in row) + "\n")
print("\nFiltered image data saved as 'filtered_image_cv.txt'.")
在上面的代码中,我应用了内核大小为 3 的 Sobel 滤波器。输入图像为 736x736,根据公式,我预计输出会更小。但应用 Sobel 滤波器后,输出的尺寸与输入相同 (736x736)。当我手动执行操作时,我得到了预期的较小图像。为什么 OpenCV 会出现这种情况?
文档明确提到输出图像具有与[输入图像]相同的尺寸和相同的通道数。这是通过在应用 Sobel 算子之前填充输入图像来实现的(在文档中称为“像素外推”)。您可以通过
borderType
的 cv2.Sobel
参数控制使用哪种填充方法。关闭填充似乎不是一个选项。