mercoledì 26 ottobre 2011

Gaussian filter python implementation

This post is, hopefully, a part of a bigger tutorial about edge detection. My final goal is to implement a Canny edge detector in python, it's just an exc
ercise to get a better understanding about the matter.

The first step in Canny algorithm is to apply a gaussian filter to the image, in order to get rid of some noise that will make edge detection harder.
I used this guide as a reference.


One-dimensional window

Here is the algorithm that applies the gaussian filter to a one dimentional list. The first step is to calculate wiindow weights, than, for every element in the list, we'll place the window over it, multiply the elements by their corresponding weight and then sum them up.



def get_window_weights(N):
support_points = [(float(3 * i)/float(N))**2.0 for i in range(-N,N + 1)]
gii_factors = [exp(-(i/2.0)) for i in support_points]
ki = float(sum(gii_factors))
return [giin/ki for giin in gii_factors]

def apply_filter(index,array,window):
N = (len(window)-1)/2
#fix out of range exception
array_l = [array[0] for i in range(N)] + array + [array[-1] for i in range(N)]
return sum(
(float(array_l[N + index + i]) * window[N+i]
for i in range(-N,N+1)
)
)

def gaussian_filter(data,window_weights,filter_func = apply_filter):
ret = []
for i in range(len(data)):
ret.append(filter_func(i,data,window_weights))
return ret



In order to apply the filter to images, we need a function that can work on pixels. The basic idea is to execute the same operations on every component of the color.


def sum_filtered_pixels(pix1,pix2):
return tuple([pix1[i]+pix2[i] for i in range(len(pix1))])

def apply_filter_to_pixel(index,array,window):
N = (len(window)-1)/2
#fix out of range exception
array_l = [array[0] for i in range(N)] + array + [array[-1] for i in range(N)]
return reduce(sum_filtered_pixels,
( tuple([float(v) * window[N+i] for v in array_l[N + index + i]])
for i in range(-N,N+1)
)
)



Bidimensional window

Obviously, we need to apply the filter to an image, so we need it to work with a bidimensional window. As explained in the guide, we can use a divide-et-impera approach and use the one dimensional algorithm. All we have to do is to run 1d gauss filter over all the pixel lines, and than again over all the columns.



def gaussian_filter_2d(matrix,window_weights,filter_func = apply_filter):
new_matrix = []
for i in range(len(matrix)):
new_matrix.append(gaussian_filter(matrix[i],window_weights,filter_func))
#apply 1d gaussian filter line by line
for i in range(len(matrix[0])):
temp_list = gaussian_filter([new_matrix[t][i] for t in range(len(matrix))],
window_weights,filter_func)
for t in range(len(matrix)):
new_matrix[t][i] = temp_list[t]
return new_matrix

def gaussian_blur(img_in,img_out,window_size):
img = Image.open(img_in)
width,height = img.size
window_weights = get_window_weights(window_size)
pixmap = gaussian_filter_2d([
[img.getpixel((w,h)) for w in range(width)]
for h in range(height)
],
window_weights,
apply_filter_to_pixel)

new_image = Image.new("RGB",(width,height))
for h in range(height):
for w in range(width):
new_image.putpixel(
(w,h),(int(pixmap[h][w][0]),
int(pixmap[h][w][1]),
int(pixmap[h][w][2]))
)
new_image.save(img_out)

if __name__ == '__main__':
gaussian_blur('wombat.jpg',"wombat_blurred.jpg",5)




Here is the result:

lunedì 24 ottobre 2011

HowTo: avoid 'Complete surveys to unblock the website

Just a stupid hint.


Whenever you find yourself in front of a page that blocks asking you to complete a survey in order to continue navigating, and you're looking for a simple link on the blocked page ( say a megavideo link) just do this:

  1. Go to the page source (CTRL + u on Google Chrome);
  2. search the link on the source (CTFL + f on Google Chrome), using some keyword (for example "megavideo.com";
  3. copy/paste the link (inside <a href="***" )
  4. enjoy.