如何用OpenCV C++去除图像中的垂直条纹?
去除图像中垂直条纹的OpenCV实现方案
示例图像:
针对图像中的垂直条纹,这里提供几种适合初学者的OpenCV实现方法:
方法一:水平方向均值滤波
垂直条纹在水平方向上存在像素值突变,用水平方向的均值滤波能平滑这类突变,同时保留竖直方向的图像细节。
代码示例
import cv2 import numpy as np # 读取图像(替换为你的图像路径) img = cv2.imread("your_image.jpg", cv2.IMREAD_GRAYSCALE) # 创建水平均值滤波核,宽度可根据条纹粗细调整 kernel = np.ones((1, 15), np.float32) / 15 # 应用滤波 filtered_img = cv2.filter2D(img, -1, kernel) # 对比显示原图和结果 cv2.imshow("Original", img) cv2.imshow("Horizontal Mean Filtered", filtered_img) cv2.waitKey(0) cv2.destroyAllWindows()
方法二:傅里叶变换频域去条纹
垂直条纹在频域中会呈现为竖直方向的亮线,通过傅里叶变换定位并屏蔽这些分量,再逆变换即可得到去条纹后的图像。
代码示例
import cv2 import numpy as np # 读取灰度图像 img = cv2.imread("your_image.jpg", cv2.IMREAD_GRAYSCALE) # 执行傅里叶变换并将低频移到中心 f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 创建掩码:屏蔽中心区域左右的竖直高频分量 rows, cols = img.shape center_row, center_col = rows // 2, cols // 2 mask = np.ones((rows, cols), np.uint8) # 调整屏蔽的宽度,适配条纹的密度 mask[:, center_col - 20 : center_col + 20] = 0 # 应用掩码并逆变换 fshift_masked = fshift * mask f_ishift = np.fft.ifftshift(fshift_masked) img_back = np.fft.ifft2(f_ishift) img_back = np.abs(img_back) # 将结果转换为8位灰度图 img_back = cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) # 显示结果 cv2.imshow("Original", img) cv2.imshow("FFT Filtered", img_back) cv2.waitKey(0) cv2.destroyAllWindows()
方法三:形态学开运算
使用水平方向的结构元素做开运算(先腐蚀后膨胀),可以消除垂直方向的细小条纹,同时尽量保留图像的主体结构。
代码示例
import cv2 import numpy as np # 读取图像 img = cv2.imread("your_image.jpg", cv2.IMREAD_GRAYSCALE) # 创建水平结构元素,长度根据条纹粗细调整 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 1)) # 执行开运算 filtered_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # 对比显示 cv2.imshow("Original", img) cv2.imshow("Morphology Open Filtered", filtered_img) cv2.waitKey(0) cv2.destroyAllWindows()
实用提示
- 所有方法中的核大小/屏蔽宽度都可以根据实际条纹的粗细、密度调整,数值越大,条纹去除越彻底,但图像细节损失也会增加
- 如果处理彩色图像,可以先转成灰度图处理,也可以对每个RGB通道分别处理后再合并
内容的提问来源于stack exchange,提问作者grandlee
相关产品推荐
相关产品推荐

