Harmonic Notes on MATLAB and Image Processing

Concepts, examples, new code, tutorials, tips, stories, history, etc.

« History of Image...

Image Processing Example: Processing a Lake Image

Steve Eddins
September 14, 2025

Contents

image_0.png

This past week, I was using MATLAB and Image Processing Toolbox functions to make a thumbnail image of a lake. I thought this would make a good example of putting a variety of image processing operations to good use.

The Task

The task is to create a $128\times 128$ two-color lake thumbnail, shown above, starting from this GIS (geographic information system) map image.

lake = imread("nh-lake.png");
imshow(lake)

figure_0.png

I got the original image above from the New Hampshire Department of Environmental Service’s Lake Information Mapper. It shows roads, topographical features, and lake depths.

imshow(lake)
xlim([318 1180])
ylim([413 1621])

figure_1.png

The task is to show just one color for the lake, another color for outside the lake, remove the islands, make the result be $128\times 128$ square. The solution shown here uses the image type conversion function, rgb2ind, and some morphological image processing functions, including imopen, imclose, imrecontruct, imfill, imresize, and strel.

Convert the Image to Indexed with Two Colors

Since the image is already close to being just two colors, one way to start is to convert the image to an indexed image with two colors. I’ll use rgb2ind with the "nodither".

num_colors = 2;
[X,map] = rgb2ind(lake,num_colors,"nodither");
imshow(X,map)

figure_2.png

Remove Street Names Using Opening by Reconstruction

The output of rgb2ind is close, but there is more work to be done. Zooming in shows that some of the street names have the same color as the lake.

imshow(X,map)
xlim([1073 1494])
ylim([92 682])

figure_3.png

Use binary image processing for the next few steps.

bw = ~logical(X);
imshow(bw)

figure_4.png

imshow(bw)

xlim([1073 1494])
ylim([92 682])

figure_5.png

I’ll erode the image to get rid of the small objects, such as the letters in the road signs. Then, I’ll use morphological reconstruction to restore the full shape of the lake. This is called opening by reconstruction. See my 14-Jul-2008 MATLAB Central blog post about opening by reconstruction.

bw2 = imerode(bw,strel("disk",5));
bw3 = imreconstruct(bw2,bw);
imshow(bw3)
title("Opening by reconstruction")

figure_6.png

Remove Islands by Filling Holes

Use imfill to get rid of the islands.

bw4 = imfill(bw3,"holes");
imshow(bw4)
title("Islands removed")

figure_7.png

Remove the Stream

There is still a small stream showing at the southern end of the lake.

imshow(bw4)
xlim([549 1094])
ylim([1813 2229])

figure_8.png

An small opening followed by a closing gets of the stream, while having only a small effect on the outline of the lake.

bw5 = imclose(imopen(bw4,ones(3,3)),ones(3,3));
imshow(bw5)
title("Stream removed")

figure_9.png

Make the Image Square

[M,N] = size(bw5)
M = 2228
N = 1588
M - N
ans = 640
Np = ans/2
Np = 320
bw6 = [zeros(M,Np) bw5 zeros(M,Np)];
imshow(bw6)
title("Square image")

figure_10.png

Tweak the Colors

Now let’s put this processed image back together with the colors produced by rgb2ind.

X2 = uint8(~bw6);
imshow(X2,map)

figure_11.png

I’d like to have more contrast and saturation. After some experimentation, I chose these colors:

map2 = [0 24 168 ; 172 220 220]/255
map2 = 2x3

0         0.0941    0.6588    
0.6745    0.8627    0.8627    

imshow(X2,map2)
title("New colors")

figure_12.png

Resize the Image

Use imresize to get a $128\times 128$ result, specifying some options that are specific to resizing indexed images. I want the same colormap, and I don’t want dithering.

[X3,map3] = imresize(X2,map2,[128 128],"bicubic",...
    Colormap = "original", Dither = false);
imshow(X3,map3,InitialMagnification = 100)

figure_13.png

Save the Image

Write the result as a PNG file.

imwrite(X3,map3,"nh-lake-2-color-128x128.png")