无聊地打酱油中,翻翻CSDN又看到了恺明大神的那篇dark channel,顺手复现下论文代码
下面贴出部分C++代码来
注:图片用的比较小,直接从网上找的,450*301,所以用的较小的窗口 5*5
最后根据这个公式
,再算下透率什么的就OK了
paper链接 :http://files.cnblogs.com/Imageshop/SingleImageHazeRemovalUsingDarkChannelPrior.rar
后续考虑用导向滤波,链接:http://research.microsoft.com/en-us/um/people/kahe/eccv10/index.html
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
size_t smaller(size_t a, size_t b)
{
if (a <= b)
{
return a;
}
else
{
return b;
}
}
int main(void)
{
cv::Mat src;
src = cv::imread("./src.bmp");
// 中间结果
cv::Mat DarkBmp(src.rows, src.cols, CV_8UC1, cv::Scalar(0, 0, 0));
// 找出像素上的R/G/B最小值
for (int rr = 0; rr < src.rows; rr++)
{
for (int cc = 0; cc < src.cols; cc++)
{
int r = src.at<:vec3b>(rr, cc)[0];
int g = src.at<:vec3b>(rr, cc)[1];
int b = src.at<:vec3b>(rr, cc)[2];
int a = 0;
a = smaller(r, g);
a = smaller(a, b);
DarkBmp.at(rr, cc) = a;
}
}
// 做局部的最小值滤波
int winsize = 5;
cv::Mat FinalImg(src.rows, src.cols, CV_8UC1, cv::Scalar(0, 0, 0));
for (int rr = winsize / 2; rr < src.rows - winsize / 2; rr++)
{
for (int cc = winsize / 2; cc < src.cols - winsize / 2; cc++)
{
int sort_list[5 * 5] = { 0 };
int list_index = 0;
for (int r = rr - winsize / 2; r < rr + winsize / 2 + 1; r++)
{
for (int c = cc - winsize / 2; c < cc + winsize / 2 + 1; c++)
{
sort_list[list_index] = DarkBmp.at(r, c);
list_index++;
}
}
sort(sort_list, sort_list + 25);
FinalImg.at(rr, cc) = sort_list[0];
}
}
cv::imshow("final img", FinalImg);
cv::waitKey(0);
return 0;
}
效果:
参考内容: