Revision 4156203a63dc2a24f3a91b5bcb488d914186d12b (click the page title to view the current version)
Image Filters
Briefing Filters
A simple blurring filter.
In addition to OpenCV, we need numpy for arrays and the signal processing library from SciPy.
We need a test image which we convert to greyscale. Here we use lenna.ppm, which you have to download and place in your working directory.
Other test images can be found at the same source.
We display the image to check that everything works:
Averaging pixels
- Consider the following python code. What does it do?
(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)
- Run the python code. What does the matrix
new
look like? - Display
new
as an image and compare it to the originalgrey
. 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.
- What does this look like as a matrix?
To apply the filter to the image, we can use the standard convolution operator as follows:
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
- 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.
The second argument (-1) specifies the colour depth of the output which should be the same as for the input.
Other test images
- Download a couple of other test images that you can use. It is instructive to use a few with very sharp edges, such as text, as well as smoother images.
- Using the procedures above, test how the filter works on different images.
Other smoothing filters
Test a couple of different filters in the same way, such as the following.
Averaging filters
- We can make square averaging filters with different sizes.
f3 = np.ones((3,3)) / 9 # 3x3 averaging
f5 = np.ones((5,5)) / 25 # 5x5 averaging
f9 = np.ones((5,5)) / 81 # 9x9 averaging
- We could make a circular averaging filter, such as this:
circle = np.array([[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0]])/37
Note that the divisor, 37, is the number of ones in the matrix.
- Test different filters on different images. What do you see?
A Gaussian filter
The Gaussian filter is a little trickier to implement, since we want to be able to vary its parameters. We use the Gaussian function \[g(x,y) = \frac{1}{2\pi\sigma^2}\exp\frac{-(x^2+y^2)}{2\sigma^2},\] where \(\sigma\) is the standard deviation and \((x,y)\) is the pixel co-ordinates with \((0,0)\) in the centre of the filter.
Firstly, the Gaussian function in python
becomes
- Check that the above code matches the mathematical formula.
We can make a list of lists of Gaussian coefficients in a simple one-liner:
where t
is an integer and the resulting filter is \((2t+1)\times(2t+1)\).
- How does the above code work?
To turn B
into a matrix, we do
Make the matrix
A
. What does the matrix look like?The elements of the filter should add to one, to maintain the luminence of the image. You can check this by calculating
sum(A.flatten()
. What do you think, is this sufficiently close to one? Why is it less than one?We can normalise the filter by calculating
AA = A/sum(A.flatten())
. Why does this give unit sum?Now, test the Gaussian filter on your test images. Use a couple of different sizes, e.g. \(t=3,7,11\), and a couple of different standard deviations, e.g. \(\sigma=0.5,1,2\). What do you observe?