Accelerating the pace of engineering and science

# Documentation Center

• Trials

## Analyzing Images

The toolbox also includes functions that return information about the texture of an image. See Analyzing the Texture of an Image for more information.

### Detecting Edges Using the edge Function

In an image, an edge is a curve that follows a path of rapid change in image intensity. Edges are often associated with the boundaries of objects in a scene. Edge detection is used to identify the edges in an image.

To find edges, you can use the edge function. This function looks for places in the image where the intensity changes rapidly, using one of these two criteria:

• Places where the first derivative of the intensity is larger in magnitude than some threshold

• Places where the second derivative of the intensity has a zero crossing

edge provides a number of derivative estimators, each of which implements one of the definitions above. For some of these estimators, you can specify whether the operation should be sensitive to horizontal edges, vertical edges, or both. edge returns a binary image containing 1's where edges are found and 0's elsewhere.

The most powerful edge-detection method that edge provides is the Canny method. The Canny method differs from the other edge-detection methods in that it uses two different thresholds (to detect strong and weak edges), and includes the weak edges in the output only if they are connected to strong edges. This method is therefore less likely than the others to be fooled by noise, and more likely to detect true weak edges.

The following example illustrates the power of the Canny edge detector by showing the results of applying the Sobel and Canny edge detectors to the same image:

1. Read image and display it.

I = imread('coins.png');
imshow(I)

2. Apply the Sobel and Canny edge detectors to the image and display them.

BW1 = edge(I,'sobel');
BW2 = edge(I,'canny');
imshow(BW1)
figure, imshow(BW2)

### Detecting Corners Using the corner Function

Corners are the most reliable feature you can use to find the correspondence between images. The following diagram shows three pixels—one inside the object, one on the edge of the object, and one on the corner. If a pixel is inside an object, its surroundings (solid square) correspond to the surroundings of its neighbor (dotted square). This is true for neighboring pixels in all directions. If a pixel is on the edge of an object, its surroundings differ from the surroundings of its neighbors in one direction, but correspond to the surroundings of its neighbors in the other (perpendicular) direction. A corner pixel has surroundings different from all of its neighbors in all directions.

The corner function identifies corners in an image. Two methods are available—the Harris corner detection method (the default) and Shi and Tomasi's minimum eigenvalue method. Both methods use algorithms that depend on the eigenvalues of the summation of the squared difference matrix (SSD). The eigenvalues of an SSD matrix represent the differences between the surroundings of a pixel and the surroundings of its neighbors. The larger the difference between the surroundings of a pixel and those of its neighbors, the larger the eigenvalues. The larger the eigenvalues, the more likely that a pixel appears at a corner.

The following example demonstrates how to locate corners with the corner function and adjust your results by refining the maximum number of desired corners.

1. Create a checkerboard image, and find the corners.

I = checkerboard(40,2,2);
C = corner(I);

2. Display the corners when the maximum number of desired corners is the default setting of 200.

subplot(1,2,1);
imshow(I);
hold on
plot(C(:,1), C(:,2), '.', 'Color', 'g')
title('Maximum Corners = 200')
hold off

3. Display the corners when the maximum number of desired corners is 3.

corners_max_specified = corner(I,3);
subplot(1,2,2);
imshow(I);
hold on
plot(corners_max_specified(:,1), corners_max_specified(:,2), ...
'.', 'Color', 'g')
title('Maximum Corners = 3')
hold off


### Tracing Object Boundaries in an Image

The toolbox includes two functions you can use to find the boundaries of objects in a binary image:

The bwtraceboundary function returns the row and column coordinates of all the pixels on the border of an object in an image. You must specify the location of a border pixel on the object as the starting point for the trace.

The bwboundaries function returns the row and column coordinates of border pixels of all the objects in an image.

For both functions, the nonzero pixels in the binary image belong to an object, and pixels with the value 0 (zero) constitute the background.

The following example uses bwtraceboundary to trace the border of an object in a binary image. Then, using bwboundaries, the example traces the borders of all the objects in the image:

1. Read image and display it.

I = imread('coins.png');
imshow(I)

2. Convert the image to a binary image. bwtraceboundary and bwboundaries only work with binary images.

BW = im2bw(I);
imshow(BW)

3. Determine the row and column coordinates of a pixel on the border of the object you want to trace. bwboundary uses this point as the starting location for the boundary tracing.

dim = size(BW)
col = round(dim(2)/2)-90;
row = min(find(BW(:,col)))
4. Call bwtraceboundary to trace the boundary from the specified point. As required arguments, you must specify a binary image, the row and column coordinates of the starting point, and the direction of the first step. The example specifies north ('N'). For information about this parameter, see Choosing the First Step and Direction for Boundary Tracing.

boundary = bwtraceboundary(BW,[row, col],'N');
5. Display the original grayscale image and use the coordinates returned by bwtraceboundary to plot the border on the image.

imshow(I)
hold on;
plot(boundary(:,2),boundary(:,1),'g','LineWidth',3);

6. To trace the boundaries of all the coins in the image, use the bwboundaries function. By default, bwboundaries finds the boundaries of all objects in an image, including objects inside other objects. In the binary image used in this example, some of the coins contain black areas that bwboundaries interprets as separate objects. To ensure that bwboundaries only traces the coins, use imfill to fill the area inside each coin.

BW_filled = imfill(BW,'holes');
boundaries = bwboundaries(BW_filled);

bwboundaries returns a cell array, where each cell contains the row/column coordinates for an object in the image.

7. Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.

for k=1:10
b = boundaries{k};
plot(b(:,2),b(:,1),'g','LineWidth',3);
end

#### Choosing the First Step and Direction for Boundary Tracing

For certain objects, you must take care when selecting the border pixel you choose as the starting point and the direction you choose for the first step parameter (north, south, etc.).

For example, if an object contains a hole and you select a pixel on a thin part of the object as the starting pixel, you can trace the outside border of the object or the inside border of the hole, depending on the direction you choose for the first step. For filled objects, the direction you select for the first step parameter is not as important.

To illustrate, this figure shows the pixels traced when the starting pixel is on a thin part of the object and the first step is set to north and south. The connectivity is set to 8 (the default).

Impact of First Step and Direction Parameters on Boundary Tracing

### Detecting Lines Using the Hough Transform

This section describes how to use the Hough transform functions to detect lines in an image. The following table lists the Hough transform functions in the order you use them to perform this task.

FunctionDescription
hough

The hough function implements the Standard Hough Transform (SHT). The Hough transform is designed to detect lines, using the parametric representation of a line:

rho = x*cos(theta) + y*sin(theta)

The variable rho is the distance from the origin to the line along a vector perpendicular to the line. theta is the angle between the x-axis and this vector. The hough function generates a parameter space matrix whose rows and columns correspond to these rho and theta values, respectively.

houghpeaks

After you compute the Hough transform, you can use the houghpeaks function to find peak values in the parameter space. These peaks represent potential lines in the input image.

houghlines

After you identify the peaks in the Hough transform, you can use the houghlines function to find the endpoints of the line segments corresponding to peaks in the Hough transform. This function automatically fills in small gaps in the line segments.

The following example shows how to use these functions to detect lines in an image.

1. Read an image into the MATLAB® workspace.

I  = imread('circuit.tif');
2. For this example, rotate and crop the image using the imrotate function.

rotI = imrotate(I,33,'crop');
fig1 = imshow(rotI);

3. Find the edges in the image using the edge function.

BW = edge(rotI,'canny');
figure, imshow(BW);

4. Compute the Hough transform of the image using the hough function.

[H,theta,rho] = hough(BW);
5. Display the transform using the imshow function.

figure, imshow(imadjust(mat2gray(H)),[],'XData',theta,'YData',rho,...
'InitialMagnification','fit');
xlabel('\theta (degrees)'), ylabel('\rho');
axis on, axis normal, hold on;
colormap(hot)

6. Find the peaks in the Hough transform matrix, H, using the houghpeaks function.

P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
7. Superimpose a plot on the image of the transform that identifies the peaks.

x = theta(P(:,2));
y = rho(P(:,1));
plot(x,y,'s','color','black');

8. Find lines in the image using the houghlines function.

lines = houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',7);
9. Create a plot that superimposes the lines on the original image.

figure, imshow(rotI), hold on
max_len = 0;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

% Determine the endpoints of the longest line segment
len = norm(lines(k).point1 - lines(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end

% highlight the longest line segment
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','red');

### Analyzing Image Homogeneity Using Quadtree Decomposition

Quadtree decomposition is an analysis technique that involves subdividing an image into blocks that are more homogeneous than the image itself. This technique reveals information about the structure of the image. It is also useful as the first step in adaptive compression algorithms.

You can perform quadtree decomposition using the qtdecomp function. This function works by dividing a square image into four equal-sized square blocks, and then testing each block to see if it meets some criterion of homogeneity (e.g., if all the pixels in the block are within a specific dynamic range). If a block meets the criterion, it is not divided any further. If it does not meet the criterion, it is subdivided again into four blocks, and the test criterion is applied to those blocks. This process is repeated iteratively until each block meets the criterion. The result might have blocks of several different sizes.

To illustrate, this example performs quadtree decomposition on a 512-by-512 grayscale image.

1. Read in the grayscale image.

I = imread('liftingbody.png');
2. Specify the test criteria used to determine the homogeneity of each block in the decomposition. For example, the criterion might be this threshold calculation.

max(block(:)) - min(block(:)) <= 0.27

You can also supply qtdecomp with a function (rather than a threshold value) for deciding whether to split blocks; for example, you might base the decision on the variance of the block. See the reference page for qtdecomp for more information.

3. Perform this quadtree decomposition by calling the qtdecomp function, specifying the image and the threshold value as arguments.

S = qtdecomp(I,0.27)

You specify the threshold as a value between 0 and 1, regardless of the class of I. If I is uint8, qtdecomp multiplies the threshold value by 255 to determine the actual threshold to use. If I is uint16, qtdecomp multiplies the threshold value by 65535.

qtdecomp first divides the image into four 256-by-256 blocks and applies the test criterion to each block. If a block does not meet the criterion, qtdecomp subdivides it and applies the test criterion to each block. qtdecomp continues to subdivide blocks until all blocks meet the criterion. Blocks can be as small as 1-by-1, unless you specify otherwise.

qtdecomp returns S as a sparse matrix, the same size as I. The nonzero elements of S represent the upper left corners of the blocks; the value of each nonzero element indicates the block size.

The following figure shows the original image and a representation of its quadtree decomposition. (To see how this representation was created, see the example on the qtdecomp reference page.) Each black square represents a homogeneous block, and the white lines represent the boundaries between blocks. Notice how the blocks are smaller in areas corresponding to large changes in intensity in the image.

Image and a Representation of Its Quadtree Decomposition