Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fast Guided filter for OpenCV

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].

Usage

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

Examples

These examples are adapted from the original MATLAB implementation.

Smoothing

P: GrayScale I: GrayScale

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);
		}
	}
}

 

Cat

  • r=2,eps=0.1^2 -0.4^2,s=1 time: 1.7ms

r=2, eps=0.1^2 r=2, eps=0.2^2 r=2, eps=0.4^2

  • r=2,eps=0.1^2 -0.4^2,s=2 time: 0.6ms

r=2, eps=0.1^2 r=2, eps=0.2^2 r=2, eps=0.4^2

  • r=4,eps=0.1^2 -0.4^2,s=1 time: 1.7ms

r=4, eps=0.1^2 r=4, eps=0.2^2 r=4, eps=0.4^2

  • r=4,eps=0.1^2 -0.4^2,s=2 time: 0.6ms

r=4, eps=0.1^2 r=4, eps=0.2^2 r=4, eps=0.4^2

  • r=8,eps=0.1^2 -0.4^2,s=1 time: 1.7ms

r=8, eps=0.1^2 r=8, eps=0.2^2 r=8, eps=0.4^2

  • r=8,eps=0.1^2 -0.4^2,s=2 time: 0.6ms

r=8, eps=0.1^2 r=8, eps=0.2^2 r=8, eps=0.4^2

P: RGB(3 channels) I: GrayScale or RGB

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);
		}
	}
}

People

  • I=grayscale r=2,eps=0.1^2 -0.4^2,s=1 time: 6ms

I=grayscale r=2, eps=0.1^2 I=grayscaler=2, eps=0.2^2 I=grayscaler=2, eps=0.4^2

  • I=RGB r=2,eps=0.1^2 -0.4^2,s=1 time: 16ms

I=RGB r=2, eps=0.1^2 I=RGB r=2, eps=0.2^2 I=RGB r=2, eps=0.4^2

  • I=RGB r=2,eps=0.1^2 -0.4^2,s=2 time: 6ms

I=RGB r=2, eps=0.1^2 I=RGB r=2, eps=0.2^2 I=RGB r=2, eps=0.4^2

  • I=grayscale r=4,eps=0.1^2 -0.4^2,s=1 time: 6ms

I=grayscale r=4, eps=0.1^2 I=grayscaler=4, eps=0.2^2 I=grayscaler=4, eps=0.4^2

  • I=RGB r=4,eps=0.1^2 -0.4^2,s=1 time: 16ms

I=RGB r=4, eps=0.1^2 I=RGB r=4, eps=0.2^2 I=RGB r=4, eps=0.4^2

  • I=RGB r=4,eps=0.1^2 -0.4^2,s=2 time: 6ms

I=RGB r=4, eps=0.1^2 I=RGB r=4, eps=0.2^2 I=RGB r=4, eps=0.4^2

I=grayscale r=8,eps=0.1^2 -0.4^2,s=1 time: 6ms

I=grayscale r=8, eps=0.1^2 I=grayscaler=8, eps=0.2^2 I=grayscaler=8, eps=0.4^2

  • I=RGB r=8,eps=0.1^2 -0.4^2,s=1 time: 16ms

I=RGB r=8, eps=0.1^2 I=RGB r=8, eps=0.2^2 I=RGB r=8, eps=0.4^2

  • I=RGB r=8,eps=0.1^2 -0.4^2,s=2 time: 6ms

I=RGB r=8, eps=0.1^2 I=RGB r=8, eps=0.2^2 I=RGB r=8, eps=0.4^2

Flash/no-flash denoising

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);

Cave Flash Cave No Flash Cave Denoised

Feathering

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);

Mask Guidance Feathering

Enhancement

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;

Tulip Smoothed Enhanced

License

MIT license.

About

fast guided filter implementation for OpenCV

Topics

Resources

Stars

73 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages