基于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;
}
// 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;
}
相关文章推荐
- 基于opencv的Gabor滤波器设计(C++)版
- 基于C++和OpenCv的SIFT_图像局部特征检测算法代码的实现
- LLC(Locality-constrained Linear Coding)基于OpenCV的C++源码实现
- OpenCV图像处理教程C++(二十二)基于距离变换与分水岭的图像分割
- 基于OpenCV库的Gabor滤波器的实现
- 活动轮廓模型(ACM)的界面设计——基于Opencv3、MFC、C++
- 基于OpenCV的人脸检测——C++和Python实现
- 基于OpenCv的边缘检测——Laplacian算子、scharr滤波器
- Matlab和C++联合编程(基于opencv的特征点检测)
- 基于opencv和c++的图像基本操作
- 基于C++的OpenCV常用函数
- 直方图均衡化的 C++ 实现(基于 openCV)
- 【基于C++和Python的Opencv3学习笔记之颜色空间缩减、ROI提取及多通道分离合并】
- OpenCV_(Based on Sobel Filter to Detect edges) 基于Sobel算子的方向滤波器检查边缘
- 【算法+OpenCV】基于三次Bezier原理的曲线拟合算法C++与OpenCV实现
- 基于VS C++平台的OpenCV设置,实现简单的行人检测
- OpenCV视频分析与对象跟踪C++(一)视频读写、背景消除建模(BSM)、对象检测与跟踪(基于颜色)
- 基于opencv和c++的图像处理:直方图均衡化
- 基于C++的OpenCV常用函数
- 自适应中值滤波(基于C++和OpenCV)Kinect深度图