├── .gitignore ├── bilateral.pdf ├── filtered_image_own.png ├── original_image_grayscale.png ├── CMakeLists.txt ├── README.md ├── bilateral_filter.py └── bilateral_filter.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /bilateral.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anlcnydn/bilateral/HEAD/bilateral.pdf -------------------------------------------------------------------------------- /filtered_image_own.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anlcnydn/bilateral/HEAD/filtered_image_own.png -------------------------------------------------------------------------------- /original_image_grayscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anlcnydn/bilateral/HEAD/original_image_grayscale.png -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project( assignment2 ) 3 | find_package( /usr/local/opt/opencv3/share/OpenCV/OpenCV REQUIRED ) 4 | add_executable( bilateral_filter bilateral_filter.cpp) 5 | target_link_libraries( bilateral_filter ${OpenCV_LIBS} ) 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Bilateral Filter 2 | 3 | [Details](https://raw.githubusercontent.com/anlcnydn/bilateral/master/bilateral.pdf) 4 | 5 | ### Original: 6 | 7 | ![](https://raw.githubusercontent.com/anlcnydn/bilateral/master/original_image_grayscale.png) 8 | 9 | ### Filtered: 10 | 11 | ![](https://raw.githubusercontent.com/anlcnydn/bilateral/master/filtered_image_own.png) 12 | -------------------------------------------------------------------------------- /bilateral_filter.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import sys 4 | import math 5 | 6 | 7 | def distance(x, y, i, j): 8 | return np.sqrt((x-i)**2 + (y-j)**2) 9 | 10 | 11 | def gaussian(x, sigma): 12 | return (1.0 / (2 * math.pi * (sigma ** 2))) * math.exp(- (x ** 2) / (2 * sigma ** 2)) 13 | 14 | 15 | def apply_bilateral_filter(source, filtered_image, x, y, diameter, sigma_i, sigma_s): 16 | hl = diameter/2 17 | i_filtered = 0 18 | Wp = 0 19 | i = 0 20 | while i < diameter: 21 | j = 0 22 | while j < diameter: 23 | neighbour_x = x - (hl - i) 24 | neighbour_y = y - (hl - j) 25 | if neighbour_x >= len(source): 26 | neighbour_x -= len(source) 27 | if neighbour_y >= len(source[0]): 28 | neighbour_y -= len(source[0]) 29 | gi = gaussian(source[neighbour_x][neighbour_y] - source[x][y], sigma_i) 30 | gs = gaussian(distance(neighbour_x, neighbour_y, x, y), sigma_s) 31 | w = gi * gs 32 | i_filtered += source[neighbour_x][neighbour_y] * w 33 | Wp += w 34 | j += 1 35 | i += 1 36 | i_filtered = i_filtered / Wp 37 | filtered_image[x][y] = int(round(i_filtered)) 38 | 39 | 40 | def bilateral_filter_own(source, filter_diameter, sigma_i, sigma_s): 41 | filtered_image = np.zeros(source.shape) 42 | 43 | i = 0 44 | while i < len(source): 45 | j = 0 46 | while j < len(source[0]): 47 | apply_bilateral_filter(source, filtered_image, i, j, filter_diameter, sigma_i, sigma_s) 48 | j += 1 49 | i += 1 50 | return filtered_image 51 | 52 | 53 | if __name__ == "__main__": 54 | src = cv2.imread(str(sys.argv[1]), 0) 55 | filtered_image_OpenCV = cv2.bilateralFilter(src, 5, 12.0, 16.0) 56 | cv2.imwrite("original_image_grayscale.png", src) 57 | cv2.imwrite("filtered_image_OpenCV.png", filtered_image_OpenCV) 58 | filtered_image_own = bilateral_filter_own(src, 5, 12.0, 16.0) 59 | cv2.imwrite("filtered_image_own.png", filtered_image_own) 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /bilateral_filter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace cv; 6 | 7 | float distance(int x, int y, int i, int j) { 8 | return float(sqrt(pow(x - i, 2) + pow(y - j, 2))); 9 | } 10 | 11 | double gaussian(float x, double sigma) { 12 | return exp(-(pow(x, 2))/(2 * pow(sigma, 2))) / (2 * CV_PI * pow(sigma, 2)); 13 | 14 | } 15 | 16 | void applyBilateralFilter(Mat source, Mat filteredImage, int x, int y, int diameter, double sigmaI, double sigmaS) { 17 | double iFiltered = 0; 18 | double wP = 0; 19 | int neighbor_x = 0; 20 | int neighbor_y = 0; 21 | int half = diameter / 2; 22 | 23 | for(int i = 0; i < diameter; i++) { 24 | for(int j = 0; j < diameter; j++) { 25 | neighbor_x = x - (half - i); 26 | neighbor_y = y - (half - j); 27 | double gi = gaussian(source.at(neighbor_x, neighbor_y) - source.at(x, y), sigmaI); 28 | double gs = gaussian(distance(x, y, neighbor_x, neighbor_y), sigmaS); 29 | double w = gi * gs; 30 | iFiltered = iFiltered + source.at(neighbor_x, neighbor_y) * w; 31 | wP = wP + w; 32 | } 33 | } 34 | iFiltered = iFiltered / wP; 35 | filteredImage.at(x, y) = iFiltered; 36 | 37 | 38 | } 39 | 40 | Mat bilateralFilterOwn(Mat source, int diameter, double sigmaI, double sigmaS) { 41 | Mat filteredImage = Mat::zeros(source.rows,source.cols,CV_64F); 42 | int width = source.cols; 43 | int height = source.rows; 44 | 45 | for(int i = 2; i < height - 2; i++) { 46 | for(int j = 2; j < width - 2; j++) { 47 | applyBilateralFilter(source, filteredImage, i, j, diameter, sigmaI, sigmaS); 48 | } 49 | } 50 | return filteredImage; 51 | } 52 | 53 | 54 | int main(int argc, char** argv ) { 55 | Mat src; 56 | src = imread( argv[1], 0 ); 57 | imwrite("original_image_grayscale.png", src); 58 | 59 | if ( !src.data ) 60 | { 61 | printf("No image data \n"); 62 | return -1; 63 | } 64 | 65 | Mat filteredImageOpenCV; 66 | bilateralFilter(src, filteredImageOpenCV, 5, 12.0, 16.0); 67 | imwrite("filtered_image_OpenCV.png", filteredImageOpenCV); 68 | Mat filteredImageOwn = bilateralFilterOwn(src, 5, 12.0, 16.0); 69 | imwrite("filtered_image_own.png", filteredImageOwn); 70 | 71 | return 0; 72 | } --------------------------------------------------------------------------------