IVR Practical Three: Introduction to Vision 1 (Week 3)


The purpose of this practical is to:
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