您的位置:首页 > 编程语言 > C语言/C++

基于c++opencv的导向滤波器

2018-03-22 14:26 260 查看
这里主要是main代码。实现的cpp在我资源里可以下载。
// day11.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <iostream>;
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "guidedfilter.h"
#define ATV at<Vec3d>
#define ATD at<double>
#define ATU at<int>
#define win_size 5
#define omegar 0.95
#define gfR 15
#define gfE 0.001using namespace cv;
using namespace std;Mat pick_patch(Mat& mat, int r, int c, int patch_size)
{
 return mat(Range(r, r + patch_size), Range(c, c + patch_size));
}double min3(double a, double b, double c)
{
 if (a > b)
 {
  if (b > c)
  {
   return c;
  }
  else
  {
   return b;
  }
 }
 else
 {
  if (a < c)
  {
   return a;
  }
  else
  {
   return c;
  }
 }
}
double calMin(Mat &img)
{
 double result;
 vector<Mat> temp;
 split(img, temp); Point minPoint;
 double minVal1 = 0;
 minMaxLoc(temp[0], &minVal1, NULL, &minPoint, NULL);
 double minVal2 = 0;
 minMaxLoc(temp[1], &minVal2, NULL, &minPoint, NULL);
 double minVal3 = 0;
 minMaxLoc(temp[2], &minVal3, NULL, &minPoint, NULL); result = min3(minVal1, minVal2, minVal3); return result;
}
Mat getDarkChannel(Mat &image, int winSize)
{
 int nRows = image.rows;
 int nCols = image.cols;
 Mat result = Mat::zeros(nRows, nCols, CV_64FC1);
 /*
 Rect roi(winSize / 2, winSize / 2, nCols, nRows);
 Mat tempI = Mat::ones(nRows + (winSize / 2) * 2, nCols + (winSize / 2) * 2, CV_64FC3);
 image.copyTo(tempI(roi));
 */
 Mat tempI;
 copyMakeBorder(image, tempI, winSize / 2, winSize / 2, winSize / 2, winSize / 2, BORDER_REPLICATE);
 double temp = 0.0;
 Mat patch;
 for (int i = 0; i < nRows; ++i)
 {
  for (int j = 0; j < nCols; ++j)
  {
   patch = pick_patch(tempI, i, j, winSize);
   temp = calMin(patch);
   result.ATD(i, j) = temp;
  }
 }
 return result;
}vector<double> getAtmosphere(Mat &img, Mat &darkChannel)
{
 int m = img.rows;
 int n = img.cols;
 vector<double> result(3);
 int nPixels = m*n;
 int nSearchPixels = nPixels*0.01; Mat darkVect = darkChannel.reshape(0, nPixels);
 Mat imgVect = img.reshape(0, nPixels);
 Mat indices;
 sortIdx(darkVect, indices, SORT_EVERY_COLUMN + SORT_DESCENDING);
 vector<double> accumulator(3);
 accumulator[0] = 0.0;
 accumulator[1] = 0.0;
 accumulator[2] = 0.0;
 for (int i = 0; i < nSearchPixels; ++i)
 {
  accumulator[0] += imgVect.ATD(indices.ATU(i, 0), 0);
  accumulator[1] += imgVect.ATD(indices.ATU(i, 0), 1);
  accumulator[2] += imgVect.ATD(indices.ATU(i, 0), 2);
 }
 result[0] = accumulator[0] / nSearchPixels;
 result[1] = accumulator[1] / nSearchPixels;
 result[2] = accumulator[2] / nSearchPixels;
 return result;
}Mat getTransmissionEstimate(Mat &img, vector<double> &atmosphere, double omega, int winSize)
{
 Mat result;
 int m = img.rows;
 int n = img.cols;
 Mat tempAtm(1, 1, CV_64FC3);
 tempAtm.ATV(0, 0)[0] = atmosphere[0];
 tempAtm.ATV(0, 0)[1] = atmosphere[1];
 tempAtm.ATV(0, 0)[2] = atmosphere[2];
 Mat repAtmosphere = repeat(tempAtm, m, n); Mat tempDiv;
 divide(img, repAtmosphere, tempDiv);
 result = 1.0 - omega * getDarkChannel(tempDiv, win_size); return result;
}Mat guidedfilter(Mat& source, Mat& guidedImage, int radius, double epsilon)
{
 Mat result; Mat IP, I2;
 multiply(guidedImage, source, IP);
 multiply(guidedImage, guidedImage, I2); Mat meanI, meanP, meanIP, meanI2;
 Size wSize(2 * radius + 1, 2 * radius + 1);
 boxFilter(source, meanP, CV_64FC1, wSize);
 boxFilter(guidedImage, meanI, CV_64FC1, wSize);
 boxFilter(IP, meanIP, CV_64FC1, wSize);
 boxFilter(I2, meanI2, CV_64FC1, wSize); Mat varI = meanI2 - meanI.mul(meanI);
 Mat covIP = meanIP - meanI.mul(meanP);
 varI += epsilon; Mat a, b;
 divide(covIP, varI, a);
 b = meanP - a.mul(meanI); Mat meanA, meanB;
 boxFilter(a, meanA, CV_64FC1, wSize);
 boxFilter(b, meanB, CV_64FC1, wSize); result = meanA.mul(guidedImage) + meanB;
 return result;
}Mat getRadiance(Mat &img, Mat &transmission, vector<double> &atmosphere)
{
 Mat result;
 int m = img.rows;
 int n = img.cols;
 Mat tempAtm(1, 1, CV_64FC3);
 tempAtm.ATV(0, 0)[0] = atmosphere[0];
 tempAtm.ATV(0, 0)[1] = atmosphere[1];
 tempAtm.ATV(0, 0)[2] = atmosphere[2];
 Mat repAtmosphere = repeat(tempAtm, m, n); Mat maxTransmission(m, n, CV_64FC3);
 for (int i = 0; i < m; ++i)
 {
  for (int j = 0; j < n; ++j)
  {
   if (transmission.ATD(i, j) <= 0.1)
   {
    transmission.ATD(i, j) == 0.1;
   }
   maxTransmission.ATV(i, j)[0] = transmission.ATD(i, j);
   maxTransmission.ATV(i, j)[1] = transmission.ATD(i, j);
   maxTransmission.ATV(i, j)[2] = transmission.ATD(i, j);
  }
 }
 Mat tempDiv = img - repAtmosphere;
 divide(tempDiv, maxTransmission, result);
 result = result + repAtmosphere; for (int i = 0; i < m; ++i)
 {
  for (int j = 0; j < n; ++j)
  {
   if (result.ATV(i, j)[0] < 0.0)
   {
    result.ATV(i, j)[0] = 0.0;
   }
   if (result.ATV(i, j)[0] > 1.0)
   {
    result.ATV(i, j)[0] = 1.0;
   }   if (result.ATV(i, j)[1] < 0.0)
   {
    result.ATV(i, j)[1] = 0.0;
   }
   if (result.ATV(i, j)[1] > 1.0)
   {
    result.ATV(i, j)[1] = 1.0;
   }   if (result.ATV(i, j)[2] < 0.0)
   {
    result.ATV(i, j)[2] = 0.0;
   }
   if (result.ATV(i, j)[2] > 1.0)
   {
    result.ATV(i, j)[2] = 1.0;
   }
  }
 } return result;
}int main()
{
 Mat src = imread("009.bmp");// IMG_8766.jpg train.bmp tiananmen.png pumpkins.jpg IMG_8766.jpg int ratio = 1.0;
 resize(src, src, cv::Size(src.cols / ratio, src.rows / ratio)); Mat tempImg;
 cvtColor(src, tempImg, CV_RGB2GRAY); int m = src.rows;
 int n = src.cols; src.convertTo(src, CV_64FC3, 1.0 / 255.0, 0);
 tempImg.convertTo(tempImg, CV_64FC1, 1.0 / 255.0, 0); Mat darkChannel;
 darkChannel = getDarkChannel(src, win_size); Mat temp;
 darkChannel.convertTo(temp, CV_8UC3, 255.0, 0);
// imshow("temp", temp); vector<double> atmosphere(3);
 atmosphere = getAtmosphere(src, darkChannel);
 cout << atmosphere[0] << " " << atmosphere[1] << " " << atmosphere[2] << endl; Mat transEst = getTransmissionEstimate(src, atmosphere, omegar, win_size); Mat x = guidedFilter(tempImg, transEst, gfR, gfE);
// imshow("x ", x);
 Mat result;
 result = getRadiance(src, x, atmosphere); result.convertTo(result, CV_8UC3, 255.0, 0); imwrite("myresult.jpg", result);
 imshow("result", result); waitKey();
 return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  导向滤波