2、 设图像尺度为 100mm,在曝光时间 T=50ms 内在水平方 向平移了 5mm,请编写程序实现图像模糊的模拟(可在空域, 也可在频域)。根据参数,计算并得到传递函数,使用直接逆 滤波对图像进行复原处理。c++
时间: 2024-03-23 11:38:28 浏览: 10
以下是一个基于空域的图像模糊模拟程序示例,使用了OpenCV库:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 读取原始图像
Mat img = imread("lena.jpg");
// 显示原始图像
namedWindow("Original Image");
imshow("Original Image", img);
// 定义传递函数
int T = 50; // 曝光时间
int dx = 5; // 水平方向平移距离
double D = 0.1; // 模糊半径
Mat H(img.size(), CV_64F);
double cx = img.cols / 2.0; // 图像中心点的x坐标
double cy = img.rows / 2.0; // 图像中心点的y坐标
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
double r = sqrt(pow(j - cx, 2) + pow(i - cy, 2)); // 像素点到中心点的距离
H.at<double>(i, j) = (T*D*r / (dx*img.cols)) * sin(2 * CV_PI*r*dx / img.cols) * exp(-CV_PI*pow(D*r / img.cols, 2));
}
}
// 对传递函数进行归一化
Mat H_norm;
normalize(H, H_norm, 0, 1, NORM_MINMAX);
// 显示传递函数
namedWindow("Transfer Function");
imshow("Transfer Function", H_norm);
// 对图像进行模糊
Mat img_blur;
dft(img, img);
dft(H, H, DFT_COMPLEX_OUTPUT);
mulSpectrums(img, H, img, 0);
idft(img, img_blur, DFT_SCALE | DFT_REAL_OUTPUT);
// 显示模糊后的图像
namedWindow("Blurred Image");
imshow("Blurred Image", img_blur);
// 直接逆滤波
Mat H_inv;
H_inv.create(H.size(), H.type());
for (int i = 0; i < H.rows; i++)
{
for (int j = 0; j < H.cols; j++)
{
H_inv.at<Complex<double>>(i, j) = H.at<Complex<double>>(i, j) != 0 ? 1.0 / H.at<Complex<double>>(i, j) : 0;
}
}
Mat img_restore;
dft(img_blur, img);
mulSpectrums(img, H_inv, img, 0);
idft(img, img_restore, DFT_SCALE | DFT_REAL_OUTPUT);
// 显示恢复后的图像
namedWindow("Restored Image");
imshow("Restored Image", img_restore);
waitKey();
return 0;
}
```
该程序首先读取一张图像,然后根据参数计算传递函数,使用频域的乘积操作对图像进行模糊处理,接着使用直接逆滤波对模糊图像进行复原处理。最终,原始图像、传递函数、模糊图像和恢复后的图像分别在窗口中显示出来。
需要注意的是,直接逆滤波是一种非常敏感的方法,容易受到噪声和估计误差的影响,可能会产生振铃、噪声和伪影等不良效果。因此,在实际应用中,通常需要采用一些更加鲁棒的方法,如维纳滤波、Tikhonov正则化等。