OpenCV图像平滑:使用泰勒展开式消除噪声
OpenCV图像平滑:使用泰勒展开式消除噪声
本文将介绍如何使用 OpenCV 和泰勒展开式对图像进行平滑处理,以消除噪声。
代码示例:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('lizi4mohu.jpg')
# 将图像转为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 计算灰度图像的一阶和二阶导数
dx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
dy = cv2.Sobel(gray, cv2.CV_64F, 0, 1)
dxx = cv2.Sobel(gray, cv2.CV_64F, 2, 0)
dyy = cv2.Sobel(gray, cv2.CV_64F, 0, 2)
# 利用泰勒展式计算平滑图像
ksize = 3 # 平滑半径
sigma = 1 # 标准差
H = np.zeros((2 * ksize + 1, 2 * ksize + 1), dtype=np.float32)
for i in range(-ksize, ksize + 1):
for j in range(-ksize, ksize + 1):
H[i + ksize, j + ksize] = np.exp(-(i ** 2 + j ** 2) / (2 * sigma ** 2))
H /= np.sum(H)
smooth = np.zeros_like(gray, dtype=np.float32)
for i in range(ksize, gray.shape[0] - ksize):
for j in range(ksize, gray.shape[1] - ksize):
f = np.array([gray[i - ksize:i + ksize + 1, j - ksize:j + ksize + 1]])
fx = np.array([dx[i - ksize:i + ksize + 1, j - ksize:j + ksize + 1]])
fy = np.array([dy[i - ksize:i + ksize + 1, j - ksize:j + ksize + 1]])
fxx = np.array([dxx[i - ksize:i + ksize + 1, j - ksize:j + ksize + 1]])
fyy = np.array([dyy[i - ksize:i + ksize + 1, j - ksize:j + ksize + 1]])
F = np.vstack([f, fx, fy, fxx, fyy])
A = np.linalg.inv(F.dot(H).dot(F.T)).dot(F).dot(H)
smooth[i, j] = A.dot(f.T)
# 将平滑图像转为8位灰度图像并显示
smooth = np.uint8(np.clip(smooth, 0, 255))
cv2.imshow('Smooth Image', smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码解释:
- 读取图像: 使用
cv2.imread()函数读取目标图像。 - 转换为灰度图像: 使用
cv2.cvtColor()函数将彩色图像转换为灰度图像。 - 计算导数: 使用
cv2.Sobel()函数计算图像的一阶和二阶导数。 - 构建平滑滤波器: 使用泰勒展开式构建一个平滑滤波器。滤波器的大小由
ksize参数控制,标准差由sigma参数控制。 - 应用滤波器: 使用循环遍历图像,对每个像素点应用平滑滤波器,得到平滑后的图像。
- 显示结果: 使用
cv2.imshow()函数显示平滑后的图像。
常见错误:
在运行代码时,可能会出现以下错误:
cv2.error: OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'imshow'
> Overload resolution failed:
> - mat is not a numpy array, neither a scalar
> - Expected Ptr<cv::UMat> for argument 'mat'
> - Expected Ptr<cv::cuda::GpuMat> for argument 'mat'
> - Expected Ptr<cv::ogl::Texture2D> for argument 'mat'
解决方法:
cv2.imshow() 函数需要一个图像数组作为参数,而 smooth 变量是一个浮点数数组。需要将 smooth 转换为 8 位灰度图像数组,再传入 imshow() 函数。
# 将平滑图像转为8位灰度图像并显示
smooth = np.uint8(np.clip(smooth, 0, 255))
cv2.imshow('Smooth Image', smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过以上步骤,我们可以使用 OpenCV 和泰勒展开式对图像进行平滑处理,有效地消除噪声。
原文地址: https://www.cveoy.top/t/topic/nSB6 著作权归作者所有。请勿转载和采集!