Fast Guided filter is an edge-preserving smoothing filter like the bilateral filter. It is straightforward to implement and has linear complexity independent of the kernel size. For more details about this filter see[Guided filte] [Fast Guided filte].
The interface consists of one simple function fastGuidedFilter
and a class FastGuidedFilter
. If you have multiple images to filter with the same guidance image then use FastGuidedFilter
class to avoid extra computations on initialization stage. The code supports single-channel and 3-channel (color) guidance images and CV_8U
, CV_8S
, CV_16U
, CV_16S
, CV_32S
, CV_32F
and CV_64F
data types.
$ mkdir build && cd build
$ cmake ..
$ make
$ ./fast-guided-filter
These examples are adapted from the original MATLAB implementation.
int R[]={2,4,8};
double EPS[]={0.1,0.2,0.4};
Mat result;
for(int s=1;s<=2;++s) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
Mat P = cv::imread("./imgs/cat.png", CV_LOAD_IMAGE_GRAYSCALE);
Mat I;
I = P;
int r = R[i];
float eps = EPS[j]*EPS[j];
eps *= 255 * 255;
clock_t start_time1 = clock();
result = fastGuidedFilter(I, P, r, eps, s);
clock_t end_time1 = clock();
cout << "fastguidedfilter Running time is: "
<< static_cast<double>(end_time1 - start_time1) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
string name = "result_s:" + to_string(s) + "_r:" + to_string(r) + "_eps:" + to_string(EPS[j]) + "^2.png";
imwrite(name, result);
}
}
}
- r=2,eps=0.1^2 -0.4^2,s=1 time: 1.7ms
- r=2,eps=0.1^2 -0.4^2,s=2 time: 0.6ms
- r=4,eps=0.1^2 -0.4^2,s=1 time: 1.7ms
- r=4,eps=0.1^2 -0.4^2,s=2 time: 0.6ms
- r=8,eps=0.1^2 -0.4^2,s=1 time: 1.7ms
- r=8,eps=0.1^2 -0.4^2,s=2 time: 0.6ms
int R[]={2,4,8};
double EPS[]={0.1,0.2,0.4};
Mat result;
for(int s=1;s<=2;++s) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
Mat P = imread("../imgs/people.png", CV_LOAD_IMAGE_ANYCOLOR);
Mat I;
//cvtColor(P,I,CV_BGR2GRAY);
I = P;
int r = R[i];
float eps = EPS[j]*EPS[j];
eps *= 255 * 255;
clock_t start_time1 = clock();
result = fastGuidedFilter(I, P, r, eps, s);
clock_t end_time1 = clock();
cout << "fastguidedfilter Running time is: "
<< static_cast<double>(end_time1 - start_time1) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
string name = "I:color_result_s:" + to_string(s) + "_r:" + to_string(r) + "_eps:" + to_string(EPS[j]) + "^2.png";
imwrite(name, result);
}
}
}
- I=grayscale r=2,eps=0.1^2 -0.4^2,s=1 time: 6ms
- I=RGB r=2,eps=0.1^2 -0.4^2,s=1 time: 16ms
- I=RGB r=2,eps=0.1^2 -0.4^2,s=2 time: 6ms
- I=grayscale r=4,eps=0.1^2 -0.4^2,s=1 time: 6ms
- I=RGB r=4,eps=0.1^2 -0.4^2,s=1 time: 16ms
- I=RGB r=4,eps=0.1^2 -0.4^2,s=2 time: 6ms
I=grayscale r=8,eps=0.1^2 -0.4^2,s=1 time: 6ms
- I=RGB r=8,eps=0.1^2 -0.4^2,s=1 time: 16ms
- I=RGB r=8,eps=0.1^2 -0.4^2,s=2 time: 6ms
cv::Mat I = cv::imread("./img_flash/cave-flash.bmp", CV_LOAD_IMAGE_COLOR);
cv::Mat p = cv::imread("./img_flash/cave-noflash.bmp", CV_LOAD_IMAGE_COLOR);
int r = 8;
double eps = 0.02 * 0.02;
eps *= 255 * 255; // Because the intensity range of our images is [0, 255]
cv::Mat q = guidedFilter(I, p, r, eps);
cv::Mat I = cv::imread("./img_feathering/toy.bmp", CV_LOAD_IMAGE_COLOR);
cv::Mat p = cv::imread("./img_feathering/toy-mask.bmp", CV_LOAD_IMAGE_GRAYSCALE);
int r = 60;
double eps = 1e-6;
eps *= 255 * 255; // Because the intensity range of our images is [0, 255]
cv::Mat q = guidedFilter(I, p, r, eps);
cv::Mat I = cv::imread("./img_enhancement/tulips.bmp", CV_LOAD_IMAGE_COLOR);
I.convertTo(I, CV_32F, 1.0 / 255.0);
cv::Mat p = I;
int r = 16;
double eps = 0.1 * 0.1;
cv::Mat q = guidedFilter(I, p, r, eps);
cv::Mat I_enhanced = (I - q) * 5 + q;
MIT license.