基于暗通道先验和双边滤波的去雾算法 opencv c++ api
时间: 2023-07-27 10:05:52 浏览: 119
基于暗通道先验的图像去雾算法-源码
基于暗通道先验和双边滤波的去雾算法是一种比较常用的去雾算法,OpenCV中也提供了相应的API支持。下面我将给出一个基于OpenCV C++ API实现的去雾算法的示例代码。
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// 读取输入图像
Mat image = imread(argv[1], IMREAD_COLOR);
if (image.empty())
{
cerr << "Failed to read image: " << argv[1] << endl;
return -1;
}
// 转换为浮点类型
Mat img_float;
image.convertTo(img_float, CV_32FC3, 1.0 / 255.0);
// 计算暗通道图像
Mat dark_channel;
cvtColor(img_float, dark_channel, COLOR_BGR2GRAY);
int patch_size = 15;
for (int i = 0; i < dark_channel.rows; i++)
{
for (int j = 0; j < dark_channel.cols; j++)
{
int x1 = max(j - patch_size / 2, 0);
int y1 = max(i - patch_size / 2, 0);
int x2 = min(j + patch_size / 2, dark_channel.cols - 1);
int y2 = min(i + patch_size / 2, dark_channel.rows - 1);
Scalar minVal;
minMaxLoc(dark_channel(Rect(x1, y1, x2 - x1 + 1, y2 - y1 + 1)), &minVal);
dark_channel.at<float>(i, j) = minVal[0];
}
}
// 计算大气光
Scalar airlight = mean(img_float.reshape(3), dark_channel > 0.1);
// 计算透射率
double omega = 0.95;
Mat transmission = 1 - omega * dark_channel / airlight[0];
// 双边滤波
int filter_size = 15;
Mat img_filtered;
bilateralFilter(img_float, img_filtered, filter_size, 0.1, 10.0);
// 恢复原始图像
Mat img_dehazed = (img_filtered - airlight[0]) / max(transmission, 0.1) + airlight[0];
img_dehazed.convertTo(img_dehazed, CV_8UC3, 255.0);
// 显示结果
imshow("Input Image", image);
imshow("Dehazed Image", img_dehazed);
waitKey(0);
return 0;
}
```
上述代码中,首先读入输入图像并将其转换为浮点类型。然后计算暗通道图像,并根据暗通道图像估计大气光。接着计算透射率,并使用双边滤波进行图像去噪。最后根据透射率和大气光恢复原始图像,并将其转换为8位无符号整型格式。最后显示输入图像和去雾后的图像。
需要注意的是,该算法的具体参数需要根据实际情况进行调整,以获得最佳效果。
阅读全文