# Morphology Exercises

A quick overview of the morphological operators
Erosion:

, where  is the image, and  is the structuring element.

Dilation:

Opening:

Closing:

Top-hat :

Bottom-hat :

Solution to the assignments from the book:

The solution.

## Exercise 4.4 - Part A

This exercise aims to provide the necessary knowledge in order to work effectively withmorphological operations in Matlab. First, take a look at the help pages in Matlab and search for morphology and get a list of all available morphology Matlab operations. In the following exercises we will use the image circles.png as example image. BW = imread('circles.png'); Take a look at it with imshow(BW);

clear all
close all

figure(1)
imshow(BW)
title('Original image of circles');
drawnow();


## Exercise 4.4 - Part B

Image boundary Find the boundary of the circles by using the function imerode. Then you first have to design a structure element by using strel. Make two structure elements, the first should be a disk with radius 1 and the second with radius 4. What is the result of using the different structure elements?

% Let's first try a structuring image of a disk with radius 1.
SE = strel('disk', 1);
se = getnhood(SE); %To get the actual image
figure(2)
subplot(121)
imshow(se,[]);
title('Disk size 1 structure');

subplot(122)
imshow(BW - imerode(BW,SE))
title('Boundary using size 1 strl');
drawnow();

% A structuring image of a disk with radius 4.
figure(3)
subplot(121)
SE = strel('disk',4);
se = getnhood(SE); %To get the actual image
imshow(se);
title('Disk size 4 structure');

subplot(122)
imshow(BW - imerode(BW,SE))
title('Boundary using size 4 strl');


## Exercise 4.4 - Part C

Image skeleton Then find the skeleton of the image BW by using bwmorph. The resulting image is noisy and not what we want, how can we improve it using bwmorph? Hint: use a function iteratively

figure(4)
imshow(BW);
title('Original image');
drawnow();

figure(5);
imshow(bwmorph(BW, 'skel',10));
title('Skeleton after 10 operations');
drawnow();

figure(6);
imshow(bwmorph(BW, 'skel',inf));
title('Skeleton used iteratively');
drawnow();

figure(7);
imshow(bwmorph(BW, 'thin', Inf));
title('Image thinned');
drawnow();


## Exercise 4.4 - Part D

Finding image patterns by hit-and-miss Generate an image by: I = checkerboard(10,10,10); I=abs((I<1)-1); and take a look at it. bwhitmiss(BW1,INTERVAL) performs the hit-and-miss operation defined in terms of a single array, called an interval o the image BW1. An interval is an array whose elements can contain 1, 0, or -1. The 1-valued elements make up the domain of SE1, the -1-valued elements make up the domain of SE2, and the 0-valued elements are ignored. The syntax bwhitmiss(INTERVAL) is equivalent to bwhitmiss(BW1,INTERVAL == 1, INTERVAL == -1).

%Lets make the image
I = checkerboard(10,10,10);
I = abs((I<1)-1);
figure(7);clf
imshow(I)
title('Checkerboard image');
drawnow();

interval = [ 0 -1 -1 ; ...
1  1 -1 ; ...
0  1  0 ];


## Answer this question before you test it: Which structure do you detect by performing a hit and miss with this interval on the image I?

- Corners (in 4-connectivity).

figure(8)
imagesc(interval);
colormap gray;
colorbar
title('The interval');
drawnow();

pause(0.5);

figure(88)
imshow(bwhitmiss(I, interval))
title('Hit-and-miss');
drawnow();


## Did it match?

- Yes. What happens in the middle of the chessboard pattern? - No detection, but these ain't corners in the normal sense. How should the interval be designed in order to detect all the wanted patterns?

interval = [ 0 -1  0 ; ...
1  1 -1 ; ...
0  1  0 ];
figure(9)
imagesc(interval);
colormap gray;
colorbar
title('A different interval');
drawnow();

pause(0.5);

figure(99)
imshow(bwhitmiss(I, interval))
title('Hit-and-miss');
drawnow();


## Exercise 4.5

In inspection of electronic circuit cards there is a need to inspect the number of holes and the diameter of the holes, see figure below. We want to measure the number of holes and the diameter using morphology. Use the morphology operators in Matlab to solve the exercise. The image pcb.jpg can be downloaded from ~inf3300/www_docs/bilder/pcb.jpg (then it can be reached on the web at http://www.ifi.uio.no/~inf3300/bilder/pcb.jpg) Tip: One solution is to use the Matlab functions imfill and regionprops

clear all
close all

%Let's look at the image
figure(10)
subplot(121)
imshow(I)
title('Original');
subplot(122)
imhist(I(:,:,1)) % JPEG compression error
title('Histogram');

% Let's clean it into an actually binary image
figure(11)
BW = I(:,:,1) > 127;
subplot(121)
imshow(BW);
title('BW image');
subplot(122)
imhist(BW);
title('Histogram');
drawnow();


Let's try out the hint and use the imfill function.

BW_filled = imfill(BW,'holes');
figure(12)
imshow(BW_filled)
title('BW after imfill');
drawnow();


The difference will leave us with only the holes

BW_holes = logical(BW_filled - BW);
figure(13);clf
imshow(BW_holes)
title('The difference between BW and BW\_filled')
drawnow();


Then we can use regionprops to estimate the diameter

figure(13);clf
imshow(BW_holes)
title('The holes with diameter')
hold on;
stats = regionprops(BW_holes, 'Area', 'Centroid');
for k = 1:length(stats)
%Calculate the radius and plot the diameter on the image
centroid = stats(k).Centroid;
plot(centroid(1),centroid(2),'ko');
text(centroid(1)+2, centroid(2), sprintf('%.1f',2*radius) ,'Color', 'r', 'FontSize', 24, 'FontWeight', 'bold');
end
drawnow();


## Exercise 4.6

Experiment with using either top hat or bottom hat as preprocessing before applying global thresholding to the image ~inf3300/www_docs/bilder/morf_test.png. The images contain letters on a very noisy background with varying illumination. Try to estimate a good estimate of the background, and subtract the estimated background from the original. Then try to use global thresholding on the resulting image. Do you also need a noise filter? Can you segment out the numbers fairly well? Also consider if there are gaps or connected symbols that you can improve by applying simple binary morphology operations.

clear all
close all

figure(1)
imshow(I,[])
title('Original');
drawnow();

figure(11)
imshow(im2bw(I,graythresh(I)))
title('Tresholded');
drawnow();
% We see that a simple graytreshold is not doing the trick


Let's try to estimate the backtround by using imcloseing with a structuring element

background = imclose(I, strel('disk', 5));

figure(2)
imshow(background)
title('The background');
drawnow();

I2 = background - I;
figure(22)
imshow(I2, [])
title('The background subtracted the image');
drawnow();

figure(23)
imshow(imbothat(I, strel('disk', 5)),[]) % the same
title('Which is the same as a bottomhat');
drawnow();


Let's do another treshold to clean up a bit

figure(3)
BW = im2bw(I2, graythresh(I2));
imshow(BW)
title('Tresholded image to clean up a bit');
drawnow();


Remove all objects that are less than 5 pixels

figure(4)
BW = bwareaopen(BW, 5);
imshow(BW)
drawnow();

figure(5);
imshow(I,[]);
title('Original');
drawnow();
figure(6);
imshow(1-BW,[]);
title('Cleaned up');
drawnow();
% Suggestion to further processing:
% 1. Rotate back, for example imrotate()
% 2. Apply some closings with line SE, e.g. horisontal, vertical and +-45 degrees.
% 3. Opening with vertical line SE.

% I'll let you have some fun. Maybe you could also use regionprops to for
% example find all zeros??

% post_id = 692; %delete this line to force new post;