opencv 图像去雾的C++实现 您所在的位置:网站首页 车窗去雾功能 opencv 图像去雾的C++实现

opencv 图像去雾的C++实现

2024-06-09 20:11| 来源: 网络整理| 查看: 265

去雾原理原理是根据何凯明博士的《Single Image Haze Removal Using Dark Channel Prior》这篇文章,介绍见https://www.cnblogs.com/Imageshop/p/3281703.html。及Python代码见:OpenCV—Python 暗通道图像去雾算法_opencv 暗通道 函数-CSDN博客。

本文主要介绍C++实现,工程文件见:https://download.csdn.net/download/qq_34902877/12017480。

1、求暗通道

       窗口的大小size,这个对结果来说是个关键的参数,窗口越大,其包含暗通道的概率越大,暗通道也就越黑,去雾的效果越不明显,一般窗口大小在11-51之间,即半径在5-25之间。

Mat DarkChannel(Mat srcImg, int size) { vector chanels; split(srcImg, chanels); //求RGB三通道中的最小像像素值 Mat minChannel = (cv::min)((cv::min)(chanels[0], chanels[1]), chanels[2]); Mat kernel = getStructuringElement(MORPH_RECT, Size(size, size)); Mat dark(minChannel.rows, minChannel.cols, CV_32FC1); erode(minChannel, dark, kernel); //图像腐蚀 return dark; }

2、求全球大气光值A

void AtmLight(Mat src, Mat dark, float outA[3]) { int row = src.rows; int col = src.cols; int imgSize = row*col; //将暗图像和原图转为列向量 vector darkVector = dark.reshape(1, imgSize); Mat srcVector = src.reshape(3, imgSize); //按照亮度的大小取前0.1%的像素(亮度高) int numpx = int(max(floor(imgSize / 1000), 1.0)); vector indices = argsort(darkVector); vector dstIndices(indices.begin() + (imgSize - numpx), indices.end()); for (int i = 0; i < numpx; ++i) { outA[0] += srcVector.at(dstIndices[i], 0)[0]; outA[1] += srcVector.at(dstIndices[i], 0)[1]; outA[2] += srcVector.at(dstIndices[i], 0)[2]; } outA[0] /= numpx; outA[1] /= numpx; outA[2] /= numpx; }

3、计算计算透射率预估值

 中的omega具有着明显的意义,其值越小,去雾效果越不明显

Mat TransmissionEstimate(Mat src, float outA[3], int size, float omega) { Mat imgA = Mat::zeros(src.rows, src.cols, CV_32FC3); vector chanels; split(src, chanels); for (int i = 0; i < 3; ++i) { chanels[i] = chanels[i] / outA[i]; } merge(chanels, imgA); Mat transmission = 1 - omega*DarkChannel(imgA, size); //计算透射率预估值 return transmission; }

4、导向滤波

Mat Guidedfilter(Mat src, Mat te, int r, float eps) { Mat meanI, meanT, meanIT, meanII, meanA, meanB; boxFilter(src, meanI, CV_32F, Size(r, r)); boxFilter(te, meanT, CV_32F, Size(r, r)); boxFilter(src.mul(te), meanIT, CV_32F, Size(r, r)); Mat covIT = meanIT - meanI.mul(meanT); boxFilter(src.mul(src), meanII, CV_32F, Size(r, r)); Mat varI = meanII - meanI.mul(meanI); Mat a = covIT / (varI + eps); Mat b = meanT - a.mul(meanI); boxFilter(a, meanA, CV_32F, Size(r, r)); boxFilter(b, meanB, CV_32F, Size(r, r)); Mat t = meanA.mul(src) + meanB; return t; }

5、通过导向滤波计算透射率

Mat TransmissionRefine(Mat src, Mat te) { Mat gray; cvtColor(src, gray, CV_BGR2GRAY); gray.convertTo(gray, CV_32F); gray /= 255; int r = 60; float eps = 0.0001; Mat t = Guidedfilter(gray, te, r, eps); return t; }

6、图像去雾

Mat Defogging(Mat src, Mat t, float outA[3], float tx) { Mat dst = Mat::zeros(src.rows, src.cols, CV_32FC3); t = (cv::max)(t, tx); //设置阈值当投射图t 的值很小时,会导致图像整体向白场过度 vector chanels; split(src, chanels); for (int i = 0; i < 3; ++i) { chanels[i] = (chanels[i] - outA[i]) / t + outA[i]; } merge(chanels, dst); dst *= 255; //归一化还原 return dst; }

结果展示:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有