Laboratory 2. Image Filtering
Laboratory 2. Image Filtering
2.1.1 Convolution.................................................................................................................. 3
2.1.2 Box blur ....................................................................................................................... 5
2.1.3 Gaussian filtering in OpenCV ...................................................................................... 6
2.1.4 Median filter................................................................................................................. 8
2.1.5 Bilateral filter ............................................................................................................... 9
Operations like Image Filtering are often used as a preprocessing step in Computer Vision
applications. The concept of signal frequency, known from 1D digital signal processing, can be extended
to signals in a 2D space, meaning images. The term indicates in a 2D signal the spatial frequency. The
spatial frequency is a measure of how often sinusoidal components (as determined by the Fourier transform)
of the structure repeat per unit of distance. An image region is said to have low frequency information if it
is smooth and does not have a lot of texture. An image area is considered to have high frequency information
if it has a lot of texture (edges, corners etc.). In Figure1 are displayed the Fourier transforms corresponding
to the logo images above them. In the center of the spectrum plots are situated the zero-frequency
components, while going from the center to the exterior, higher frequency components are displayed with
a color-coded amplitude. Larger dark blue areas (for low amplitude frequency components) correspond to
an image that is more uniform, without significant texture. Warm colors in the spectrum indicate higher
amplitudes. The original logo image contains more elements (contours, objects, …) and so the associated
spectrum has also significantly more higher frequency components.
1
Fundamentals of Image Processing and Computer Vision – Laboratory 2
Low Pass Filtering (LPF) is in essence the operation of blurring or smoothing of an input image.
Blurring is obtained by discarding the fine texture: it allows the lower frequency information to pass and it
blocks higher frequency information.
High Pass Filtering (HPF) represents a sharpening or edge enhancement type of operation. In this
case, the low frequency information is suppressed and the high frequency information is preserved.
2
Fundamentals of Image Processing and Computer Vision – Laboratory 2
Figure 2. Example of an input image that will be filtered with a 3x3 kernel. One output pixel will be a weighted
combination of its collocated pixel (yellow) and neighborhood values (blue). The weights will be specified in the kernel.
When the output pixel depends only on a linear combination of the input pixels, we call the filter a
Linear Filter. Otherwise, it is called a Nonlinear Filter.
2.1.1 Convolution
Linear filters are implemented using 2D convolution. Operations like blurring and contour
detection are realized using convolution. Let us consider a 3x3 kernel:
−1 0 1
h = [−2 0 2]
−1 0 1
that we will use to filter the yellow center pixel in Figure 2. The output filtered pixel value is computed by
multiplying corresponding elements of the input blue & yellow patch and the convolution kernel, followed
by adding up all the products:
𝑜𝑢𝑡𝑐𝑒𝑛𝑡𝑒𝑟 = 206 × (−1) + 203 × 0 + 205 × 1 + 205 × (−2) + 204 × 0 + 205 × 2 + 203 × (−1)
+ 203 × 0 + 205 × 1 = 1
In order to filter an entire image, this process is repeated pixel by pixel (the kernel slides through
the image, left to right, top to bottom). For color images, the convolution is performed independently on
each channel. At the boundary, the convolution is not uniquely defined. There are several options to choose
from:
- Ignore the boundary pixels: by discarding the boundary pixels, the output image will be slightly
smaller than the input image.
- Zero padding: the input image is padded with zeros at the boundary pixels to make it larger and
then convolution is performed.
3
Fundamentals of Image Processing and Computer Vision – Laboratory 2
- Replicate border: another option is to replicate the boundary pixels of the input image and then
perform the convolution operation on this larger image.
- Reflect border: the preferred option is to reflect the border about the boundary. Reflecting
ensures a smooth intensity transition of pixels at the boundary.
In OpenCV, the convolution is performed using the function filter2D. The function syntax is:
with parameters:
src input image.
dst output image of the same size and the same number of channels as src.
ddepth desired depth of the destination image.
kernel convolution kernel, a single-channel floating point matrix; if you want to apply different
kernels to different channels, split the image into separate color planes using split and process
them individually.
anchor anchor of the kernel that indicates the relative position of a filtered point within the kernel;
the anchor should lie within the kernel; the default value (-1,-1) means that the anchor is at the
kernel center.
delta an optional value added to the filtered pixels before storing them in dst.
borderType pixel extrapolation method.
The optional parameters like anchor point, delta and borderType are almost never changed
from their default values.
For the function cv2.filter2D in the OpenCV documentation, the term convolution is wrongly
used instead of cross-correlation. It actually performs cross-correlation, which is identical to convolution
only if the filter kernel is symmetric!
Example:
import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread(”test.jpg”)
4
Fundamentals of Image Processing and Computer Vision – Laboratory 2
kernel = np.ones((ker_size, ker_size), dtype=np.float32) / ker_size**2
print (kernel)
The second parameter of cv2.filter2D (depth) is set to -1, which means the bit-depth of the
output image is the same as the input image. So if the input image is of type uint8, the output image will
also be of the same type.
• Ex. 2.1 Change the kernel used in the previous example and analyze the results. Try to use a kernel
without normalizing the values by the number of elements in the kernel. How is this altering the output
image brightness level compared to the input image?
• Ex. 2.2 Modify the previous example by testing the following kernels on the input images
“white_square.jpg” and “hop.jpg”.
0 0 0 0 0 0 −1 −1 −1 1 1 2 1
ℎ1 = [0 1 0] ℎ2 = [0 0 0] ℎ3 = [−1 8 −1] ℎ4 = [2 4 2]
16
0 0 0 0 0 1 −1 −1 −1 1 2 1
Describe the effect of each kernel on the input image.
src – represents the input image and it can have any number of channels, which are processed
independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst – output image of the same size and type as src.
ksize stands for the blurring kernel size
anchor – anchor point; default value is Point(-1,-1) means that the anchor is at the kernel center.
borderType – border mode used to extrapolate pixels outside of the image.
5
Fundamentals of Image Processing and Computer Vision – Laboratory 2
Example:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('logo_noise2.jpg')
plt.figure(figsize=[30,10])
plt.subplot(131);plt.imshow(img[...,::-1]);plt.title("Noisy Image")
plt.subplot(132);plt.imshow(dst1[...,::-1]);plt.title("Smoothed 3x3")
plt.subplot(133);plt.imshow(dst2[...,::-1]);plt.title("Smoothed 5x5")
plt.show()
• Ex. 2.3 Describe both smoothing operations in view of the final results: How much smoother
appears the logo background? How are the contours changing with the blurring kernel?
6
Fundamentals of Image Processing and Computer Vision – Laboratory 2
An image blurred using the Gaussian kernel looks less blurry compared to a box kernel of the same
size. A small amount of Gaussian blurring is frequently used to remove noise from an image. It is also
applied to the image prior to a noise sensitive image filtering operation. For example, the Sobel kernel used
for calculating the derivative of an image is a combination of a Gaussian kernel and a finite difference
kernel.
The OpenCV function that implements the Gaussian filtering is GaussianBlur with the following
syntax:
src – represents the input image; the image can have any number of channels, which are processed
independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst – is the output image of the same size and type as src.
ksize – Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive
and odd. Or, they can be zero's and then they are computed from sigma.
sigmaX – Gaussian kernel standard deviation in X direction.
sigmaY – Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be equal to
sigmaX – if both sigmas are zeros, they are computed from ksize.width and ksize.height,
respectively; to fully control the result regardless of possible future modifications of all this semantics, it is
recommended to specify all of ksize, sigmaX, and sigmaY.
borderType – pixel extrapolation method.
• Ex. 2.4 Add the missing lines of code, indicated by the comments. Describe both smoothing
operations comparing the final images: how much smoother appears the logo background? How are the
contours in the image changing with the blurring kernel? Try Gaussian filtering for the test images
“logo_noise2.jpg” and “lina_noise.jpg” and identify the best kernel size.
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('logo_noise.jpg')
# Apply gaussian blur with kernel 5x5 and sigmaX=0, sigmaY=0; output image dst1
# Apply gaussian blur with kernel 15x15 and sigmaX=3, sigmaY=3; ; output image
# dst2
plt.figure()
plt.subplot(131);plt.imshow(img[...,::-1]);plt.title("Noisy Image")
plt.subplot(132);plt.imshow(dst1[...,::-1]);plt.title("Smoothed 5x5")
plt.subplot(133);plt.imshow(dst2[...,::-1]);plt.title("Smoothed 15x15")
plt.show()
7
Fundamentals of Image Processing and Computer Vision – Laboratory 2
• Ex. 2.5 Add the missing lines of code, indicated by the comments. What type of texture is affected
the most by the salt-and-pepper noise? Which smoothing filter performs better on the edges? In order
to preserve the edges, is it better to use a larger kernel or a smaller one? Which removes the noise most
efficiently? Try experimenting with other kernel sizes as well!
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('lina_noise.jpg')
# Apply gaussian blur with kernel 5x5 and sigmaX=0, sigmaY=0; output image dst1
8
Fundamentals of Image Processing and Computer Vision – Laboratory 2
kernelSize = 5
# Performing Median Blurring with kernelSize=5 and store it in numpy array
# "dst2"
plt.figure()
plt.subplot(131);plt.imshow(img[...,::-1]);plt.title("Noisy Image")
plt.subplot(132);plt.imshow(dst1[...,::-1]);plt.title("gaussian 5x5")
plt.subplot(133);plt.imshow(dst2[...,::-1]);plt.title("median 5x5")
plt.show()
9
Fundamentals of Image Processing and Computer Vision – Laboratory 2
1
𝑂𝑐 = ∑ 𝐺𝜎𝑠 (‖𝑐 − 𝑛‖) 𝐺𝜎𝑟 (𝐼𝑐 − 𝐼𝑛 )
𝑊𝑐
𝑐
where 𝑊𝑐 is a normalization constant, 𝐺𝜎𝑠 represents the Spatial Gaussian kernel, 𝐺𝜎𝑟 represents the color /
range Gaussian kernel, 𝑐 is the center pixel position, 𝑛 is the neighboring pixel position, 𝐼𝑐 represents the
intensity at the center pixel and 𝐼𝑛 is the intensity at the neighboring location 𝑛.
If the neighborhood pixels are edges, the difference in intensity (𝐼𝑐 − 𝐼𝑛 ) will be higher. Since the
Gaussian is a decreasing function, 𝐺𝜎𝑟 (𝐼𝑐 − 𝐼𝑛 ) will have lower weights for higher values. Hence, the
smoothing effect will be lower for such pixels, preserving the edges.
There are 2 significant parameters in bilateral filtering: σ𝑠 and σ𝑟 . σ𝑠 controls the amount of
spatial smoothing, and σ𝑟 controls how dissimilar colors within the neighborhood will be averaged. A
higher σ𝑟 results in larger regions of constant color. The OpenCV function for bilateral filtering is:
with parameters
src – Source image – 8-bit or floating-point, 1-channel or 3-channel image.
dst – Destination image of the same size and type as src.
d – Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed
from sigmaSpace.
sigmaColor – Filter sigma in the color space. A larger value of the parameter means that farther colors
within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting in larger areas of
semi-equal color.
sigmaSpace – Filter sigma in the coordinate space. A larger value of the parameter means that farther
pixels will influence each other as long as their colors are close enough (see sigmaColor ). When d>0,
it specifies the neighborhood size, regardless of sigmaSpace. Otherwise, d is proportional to
sigmaSpace.
borderType – border mode used to extrapolate pixels outside of the image.
• Ex. 2.6 Add the missing lines of code, indicated by the comments. Read multiple images affected
by different types of noise: salt-and-pepper noise is present in “logo_noise.jpg” and
“lina_noise.jpg”, while gaussian noise is present in “logo_noise2.jpg”. Experiment with different
values of kernel size and sigma and establish which type of filtering: median or bilateral is best in
each case, depending on the noise type. Show the comparison results and comment on the best
choice of parameters for each filter.
import cv2
import numpy as np
10
Fundamentals of Image Processing and Computer Vision – Laboratory 2
import matplotlib.pyplot as plt
img = cv2.imread('test_image.jpg')
# Larger the value more the influence of the farther placed pixels
# as long as their colors are close enough
sigmaSpace=80
plt.figure()
plt.subplot(121);plt.imshow(img[...,::-1]);plt.title("Noisy Image")
plt.subplot(122);plt.imshow(dst1[...,::-1]);plt.title("Bilateral filter")
plt.show()
11
Fundamentals of Image Processing and Computer Vision – Laboratory 2
- pixels G and I have gradients in the x- and y-directions, respectively, but they are quite subtle. The
gradient magnitude is no longer maximum, since the transition is between dark gray to lighter gray
(not from black to white as before).
- pixel H has gradients in both directions, which is the case for most pixels in natural images.
In color images, gradients can be computed for every color channel separately (1 pixel will have 6
values representing the 3 color gradients in x and y directions). In many applications color gradients are not
needed, so usually color images are converted to grayscale and intensity gradients are computed instead.
Let us denote the gradient in the x-direction Ix and the gradient in the y-direction, Iy. A pixel gradient
is therefore similar to a vector with x and y components. One pixel’s gradient magnitude is given by
𝐺 = √𝐼𝑥2 + 𝐼𝑦2
12
Fundamentals of Image Processing and Computer Vision – Laboratory 2
Using Prewitt filters to compute the image gradients 𝐼𝑥 and 𝐼𝑦 , we actually computed the x and y derivatives
of the image.
with parmeters:
src input image
dst output image of the same size and the same number of channels as src
ddepth output image depth,in the case of 8-bit input images it will result in truncated derivatives.
dx order of the derivative x.
dy order of the derivative y.
ksize size of the extended Sobel kernel; it must be 1, 3, 5, or 7.
scale optional scale factor for the computed derivative values; by default, no scaling is applied.
delta optional delta value that is added to the results prior to storing them in dst
borderType pixel extrapolation method.
• Ex. 2.7
- Read the image “Halep.jpg” as grayscale.
- Use the Sobel function to compute the X and Y gradients. Set the depth of the output images to
CV_32F since the gradients can take negative values.
- Use the function cv2.normalize to normalize the gradients, so that all pixel values lie between
0 and 1.
- Display both gradient images. Can they be used as edge detectors?
13
Fundamentals of Image Processing and Computer Vision – Laboratory 2
𝜕2𝐼 𝜕2𝐼
𝐿(𝑥, 𝑦) = +
𝜕𝑥 2 𝜕𝑦 2
and the corresponding convolution kernel is
0 1 0
[1 −4 1]
0 1 0
The Laplacian filter is very sensitive to noise and therefore it is important to smooth the image
before applying it. The associated function in OpenCV is cv2.Laplacian.
• Ex. 2.8
- Read the image “Hummingbird.jpg” as grayscale.
- Apply gaussian blurring using cv2.GaussianBlur for a kernel size of 3x3 pixels.
- Apply Laplacian filtering on the previous blurred image. The depth of the output image should be
set to CV_32F since gradients can take negative values!
- Use the function cv2.normalize to normalize the gradients, so that all pixel values lie between
0 and 1.
- Display the final normalized image! What are the advantages of a Laplacian edge detector
compared to Sobel filters?
- Try also the Laplacian filtering without the Gaussian smoothing. Compare both filtered images!
14
Fundamentals of Image Processing and Computer Vision – Laboratory 2
0 −1 0
[−1 5 −1]
0 −1 0
The above kernel is obtained using 𝛼 = 1 and approximating 𝐼 − 𝐼𝑏 using the Laplacian kernel.
0 0 0 0 −1 0
[0 1 0] + [−1 4 −1]
0 0 0 0 −1 0
Example:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("tree1.jpg")
# Sharpen kernel
sharpen = np.array(( [0, -1, 0],
[-1, 5, -1],
[0, -1, 0]), dtype="int")
sharpImg = cv2.filter2D(img, -1, sharpen)
plt.figure(figsize=[20,10])
plt.subplot(121);plt.imshow(img[...,::-1]);plt.title("Original image")
plt.subplot(122);plt.imshow(sharpImg[...,::-1]);plt.title("Sharpen output")
plt.show()
• Ex. 2.9 What are the texture components highlighted by the sharpening effect? Experiment also
with other images (parrots.jpg). Describe the type of texture that is more prominent after the sharpen
filtering.
15