IVR Practical Three: Introduction to Vision 1 (Week 3)
The purpose of this practical is to:
- Perform some simple image manipulation in Matlab
- Use histograms and thresholds to isolate foreground from
background
- Test this method on a variety of real images captured with the
webcam
There are a number of matlab programs for image processing that you can
download from:
http://www.inf.ed.ac.uk/teaching/courses/ivr/MATLAB/FLATPARTRECOG/
For this lab you want:
myjpgload.m
myrgb2gray.m
liveimagejpg.m
dohist.m
As some of these programs use special Matlab toolboxes, you may run into
problems with licenses. You can look in the above folder for some alternative
scripts that may solve the problems.
Loading and capturing images
Look at the m-file myjpgload.m
Note how this uses several in-built matlab functions to read the
image, convert it to grayscale, convert the pixel values to a format
that can be numerically manipulated (double precision instead of
unsigned integers) and show it as a matlab figure. Try
running it to load and display a jpeg (save one from a website if you
don't have one somewhere in your files already). N.B. to save this file
in your workspace for later use, make sure you assign the output from
the function, e.g.
>>
first_pic = myjpgload('<filename>',1);
From week one, you should remember how to run a unix command from
matlab that captures an image from the webcam as a jpeg. Using the
webcam, capture an image and then load and show a greyscale version of
it in matlab. How many pixels are in the image? Can you capture an
image with fewer pixels? The m-file liveimagejpg
.m is
a simple function that does the capture and load.
(N.B. an alternative to the function imread (used in myjpgload.m and liveimagejpg
.m) is importdata.
Similarly, instead of imshow you can use image.)
Image histograms
Look at the help information for the matlab functions hist and histc (the
simplest way is to type:
>> help
hist
Create a histogram of the pixel values in the
image you have captured. Note that you first need to convert the image
array to a vector, otherwise a histogram is calculated for each column.
Use
>> vec = reshape(first_pic,1,m*n);
where m,n are the dimensions of the image. Make sure you understand
what this is telling
you about the image (if uncertain, consult a demonstrator).
Look at the m-file dohist.m
Make sure you understand how it works and then try running it on your
image - as before, save the output by using e.g.:
>>
first_hist = dohist(first_pic,1)
Capture several more images - try varying the lighting, the distance
and so on - and compare the histograms. What kind of information do the
histograms provide?
Applying a convolution to smooth a histogram
The histograms you have produced probably look very irregular. To
extract information more easily, we can smooth the histogram by
applying a convolution operator. A popular smoothing operator is a
gaussian distribution. To generate a gaussian filter with a
window size of 50 use:
>>filter
= gausswin(50,6); % 6 is a width parameter
>>filter = filter/sum(filter); % this normalises the filter
>>plot(filter)
If you run into a license problem while running gausswin
try:
>>
filter = fspecial('gaussian', [50 1], 6);
Or:
>>
filter = exp ( -0.5 * ( 6/50 * [ -49 : 2 : 49 ]' ) .^ 2 );
To apply the filter to your histogram, use:
>>
smooth_hist = conv(filter,first_hist);
>> plot(smooth_hist)
Image segmentation
A basic step in image processing is distinguishing the object of
interest from the background. One simple approach is to use an
intensity threshold. Set up a relatively simple scene with a dark
object on a light background. Capture the image and look at the
histogram (smooth it if necessary). Do you think there is a threshold
value that will separate the object and background? Try writing a
function that, given an image and a threshold, returns a binary image binary_pic where
every pixel below the threshold is set to 0 and everything above the
threshold is set to 1 . A couple of hints: you can address individual
pixel elements of the image array as first_pic(i,j); you can find out
the size of the image using [m,n]=size(first_pic); use help for to
see how to loop through elements of an array; and help if to see how to do a
comparison. (An alternative and very compact way to do this would
be to use the find function). To show the result
as a black and white image use:
>>imshow(binary_pic) or
>>image(binary_pic);
Test your function on several
different images. How
well does it pick out the foreground object? E.g. can you see a robot
on the desk? Are shadows a problem?
How are you choosing the threshold? Can you write a function that
automates the choice of threshold?
Automatic and adaptive thresholding
You can also try using the following m-files from the website above:
findthresh.m - given a histogram, this automatically
generates a
suitable threshold value, using the method described in lectures. Note
it assumes that the histogram input is a column vector (256x1) as is
produced by the output of dohist.m; if
your histogram is a row vector you need to transpose it when calling
the function.
adapt.m - does adaptive thresholding across an image. Note
this is a script, not a function, so you will need to edit to operate
on your own image. It can be very slow on large images, so if possible,
try it on a small image or part of an image.
Which approach (choosing your own threshold, choosing automatically, or
adaptive thresholding) works best on your captured images? Why?
More about thresholding, including some further exercises to try, can
be found at http://homepages.inf.ed.ac.uk/rbf/HIPR2/threshld.htm
Main IVR Page