--- title: Image Filters categories: tutorial --- **Briefing** [Filters]() # A simple blurring filter. In addition to OpenCV, we need numpy for arrays and the signal processing library from SciPy. ```python import cv2 as cv import numpy as np import scipy.signal as sig ``` We need a test image which we convert to greyscale. Here we use [lenna.ppm](http://www.hlevkin.com/hlevkin/TestImages/lenna.ppm), which you have to download and place in your working directory. ```python frame =cv.imread( "lenna.ppm" ) grey = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) ``` Other test images can be found at the [same source](http://www.hlevkin.com/hlevkin/06testimages.htm). We display the image to check that everything works: ```python cv.imshow("img",grey) cv.waitKey(0) ``` ## Averaging pixels 1. Consider the following python code. What does it do? ```python (n,m) = grey.shape new = np.zeros((n-6,m-6),dtype=np.uint8) for i in range(n-6): for j in range(m-6): orig = grey[i:i+7,j:j+7] new[i,j] = round(sum(orig.flatten())/49) ``` 2. Run the python code. What does the matrix `new` look like? 3. Display `new` as an image and compare it to the original `grey`. What is the visual effect? What you should observe is a blurring effect. Contours are smoothened by averaging a neighbourhood. ## Using a signal processing library What we did above is such a standard operation that we have an API therefore. We can define a $7\times7$ averaging filter like this. ```python f7 = np.ones((7,7)) / 49 ``` + What does this look like as a matrix? To apply the filter to the image, we can use the standard convolution operator as follows: ```python g7 = sig.convolve2d(grey,f7).astype(np.uint8) ``` Note that we have to convert the result to integers explicitly, lest OpenCV will not interpret it as an image. The result can be displayed as ```python cv.imshow("filtered",g7) cv.waitKey(0) ``` + Compare the two images. What does the filter do? + Compare the filtered image to the image `new` from your manual averaging. Do they look different in any way? The API has different methods to handle the boundaries. We simply cropped a few pixel around the border, and thus `new` may be smaller than images filtered with the API. We can do the same thing using the OpenCV library, like this. ```python c7 = cv.filter2D(grey,-1,f7) ``` The second argument (-1) specifies the colour depth of the output which should be the same as for the input. ## ```python f3 = np.ones((3,3)) / 9 f5 = np.ones((5,5)) / 25 ```