Ron Bakker/MathLabHelp
Open MathLab ↗

Tutorial · Intermediate · 10 min

Working with images

Read an image, look at its pixels and colour channels, clean it up with filters, find edges, fix its contrast and count the objects in it.

  1. An image is an array

    A colour image is rows × columns × 3: red, green and blue layers of whole numbers from 0 to 255 (uint8). testimage gives built-in pictures to practise on; your own photos come in with Import and imread.

    I = testimage('shapes');
    size(I)
    class(I)
    pixel = I(40, 70, :)          % one pixel: red, green, blue
    imshow(I)
    Try it ↗

    Tip: Import a JPEG or PNG with the Import button, then I = imread('yourphoto.jpg'). Web images work too: imread('https://…/picture.png').

  2. Grey levels and arithmetic

    rgb2gray combines the channels into one grey layer. Arithmetic on uint8 stays between 0 and 255, so I + 80 brightens without overflowing; im2double switches to 0–1 for calculations.

    G = rgb2gray(testimage('shapes'));
    subplot(1, 3, 1), imshow(G), title('grey')
    subplot(1, 3, 2), imshow(G + 80), title('G + 80')
    subplot(1, 3, 3), imshow(im2double(G).^3), title('im2double(G).^3')
    Try it ↗
  3. Filters

    A filter replaces every pixel by a weighted mix of its neighbours. fspecial makes common kernels, imfilter applies them; medfilt2 takes the median instead, which removes speckles but keeps edges.

    rng(2)
    G = imnoise(rgb2gray(testimage('shapes')), 'salt & pepper', 0.05);
    subplot(1, 3, 1), imshow(G), title('noisy')
    subplot(1, 3, 2), imshow(imfilter(G, fspecial('gaussian', 7, 1.5))), title('Gaussian')
    subplot(1, 3, 3), imshow(medfilt2(G)), title('median')
    Try it ↗
  4. Edges

    edge marks where brightness changes quickly. Sobel is fast; Canny smooths first, thins the edges to one pixel and links them, so it gives cleaner outlines.

    G = rgb2gray(testimage('noisy'));
    subplot(1, 2, 1), imshow(edge(G, 'sobel')), title('Sobel')
    subplot(1, 2, 2), imshow(edge(G, 'canny')), title('Canny')
    Try it ↗
  5. Histogram and contrast

    imhist counts how many pixels have each grey level. A narrow histogram means low contrast; imadjust stretches it, histeq flattens it.

    G = imgaussfilt(rgb2gray(testimage('noisy')), 1);
    dull = uint8(100 + 0.25 * double(G));
    subplot(2, 2, 1), imshow(dull), title('dull')
    subplot(2, 2, 2), imshow(imadjust(dull)), title('imadjust')
    subplot(2, 2, 3), imhist(dull)
    subplot(2, 2, 4), imhist(imadjust(dull))
    Try it ↗
  6. Count and measure

    Threshold to black and white (imbinarize), tidy up with morphology (imopen, imfill), then bwlabel numbers the regions and regionprops measures them. In MathLab each measurement is a column: s.Area, s.Centroid.

    rng(5)
    BW = imfill(imopen(imbinarize(testimage('blobs')), strel('disk', 2)), 'holes');
    s = regionprops(BW, 'Area', 'Centroid');
    imshow(BW), hold on
    plot(s.Centroid(:, 1), s.Centroid(:, 2), 'r+', 'MarkerSize', 10), hold off
    title(sprintf('%d regions, median area %.0f pixels', s.Count, median(s.Area)))
    Try it ↗