Kahibaro
Discord Login Register

18.4 Basic Image Transformations

Working with Image Data for Transformations

In MATLAB, basic image transformations are operations that change the appearance, size, orientation, or brightness of an image, while still producing an image as output. You usually begin with an image stored as a matrix or array, then apply functions that operate on that array. Before applying transformations, make sure you already know how to read and display images, and how image data is represented numerically.

A typical workflow for a transformation is: read the image with imread, convert it to a convenient numeric type if needed, apply the transformation, then display or write the result using imshow or imwrite.

For example:

matlab
I = imread("peppers.png");      % read an image
Igray = rgb2gray(I);            % convert to grayscale
Irot = imrotate(Igray, 45);     % rotate 45 degrees
imshow(Irot);                   % display result

Geometric Transformations: Flips and Rotations

The simplest geometric image transformations are flips and 90 degree rotations. These change the position of pixels in a very structured way without changing the actual pixel values themselves.

Horizontal and vertical flips are done with fliplr and flipud:

matlab
I = imread("peppers.png");
I_left_right = fliplr(I);   % mirror image horizontally
I_up_down   = flipud(I);    % mirror image vertically
imshow(I_left_right);

A horizontal flip reverses the order of columns in the image matrix, while a vertical flip reverses the order of rows.

For rotations by multiples of 90 degrees you can use rot90:

matlab
I = imread("peppers.png");
I_90  = rot90(I);       % 90 degrees counterclockwise
I_180 = rot90(I, 2);    % 180 degrees
I_270 = rot90(I, 3);    % 270 degrees

For arbitrary angles, imrotate gives more flexibility:

matlab
I = imread("peppers.png");
I_rot45 = imrotate(I, 45);           % rotate 45 degrees CCW
I_rot45_crop = imrotate(I, 45, "bilinear", "crop");

By default, imrotate enlarges the output image so all rotated pixels are included. With the "crop" option, the output image size matches the input size and the image is rotated within that fixed frame. The interpolation method, for instance "nearest", "bilinear", or "bicubic", controls how pixel values are estimated at noninteger positions during rotation. Nearest neighbor is fastest but can look blocky, while bilinear and bicubic typically look smoother.

Another common geometric transformation is resizing, which changes the number of rows and columns:

matlab
I = imread("peppers.png");
I_half = imresize(I, 0.5);               % scale by factor 0.5
I_200_300 = imresize(I, [200 300]);      % explicit size [rows cols]

Resizing will often include interpolation similar to rotation, since new pixel values must be calculated when the image is scaled up or down.

Cropping and Extracting Regions

Cropping is the process of cutting out a rectangular region of interest from the image. Since an image is a matrix, one way to crop is directly through array indexing. You specify the rows and columns you want to keep:

matlab
I = imread("peppers.png");
% keep rows 51 to 150 and columns 101 to 250
I_crop = I(51:150, 101:250, :);
imshow(I_crop);

The : on the third dimension means keep all color channels.

MATLAB also provides the imcrop function, which can be more convenient, especially for interactive work:

matlab
I = imread("peppers.png");
% rectangle defined as [xmin ymin width height]
rect = [100 50 150 120];
I_crop = imcrop(I, rect);
imshow(I_crop);

If you call imcrop with only the image as input, a tool is opened in a figure window that lets you draw the crop region with the mouse, then returns the cropped image.

Cropping is particularly useful during data preparation, when you want to focus on a specific object or remove irrelevant borders and margins from an image.

Brightness and Contrast Adjustments

Brightness and contrast adjustments modify pixel values while leaving the spatial arrangement unchanged. These transformations are applied to the intensity values of grayscale images or to each channel in a color image.

A very simple brightness change is to add or subtract a constant:

matlab
I = imread("cameraman.tif");      % grayscale image
I_brighter = I + 50;
I_darker   = I - 50;

If I is of class uint8, values are clipped automatically to the valid range 0 to 255. This means pixels that would go above 255 are set to 255, and those that would go below 0 are set to 0. To have more explicit control, you can convert to double in the range \([0,1]\):

matlab
I = imread("cameraman.tif");
Id = im2double(I);             % convert to double in [0,1]
I_brighter = Id + 0.2;
I_darker   = Id - 0.2;
I_brighter = im2uint8(I_brighter);   % convert back

Contrast describes how spread out the pixel intensities are. Stretching the intensities across a larger range increases contrast. A simple linear contrast adjustment is:

$$
I_{\text{new}} = a \cdot I_{\text{old}} + b
$$

where \(a\) controls contrast, and \(b\) controls brightness. In MATLAB:

matlab
I = imread("cameraman.tif");
Id = im2double(I);
a = 1.5;   % contrast factor
b = -0.2;  % brightness offset
I_adj = a * Id + b;
I_adj = im2uint8(mat2gray(I_adj));  % re-scale and convert back
imshow(I_adj);

Here mat2gray rescales the values to the range \([0,1]\) before converting back to an integer class.

For many tasks, you will prefer ready functions that compute the scaling automatically. The function imadjust maps input intensities from specified ranges to new ranges:

matlab
I = imread("cameraman.tif");
% default: uses full data range and maps to [0 1]
J = imadjust(I);
% custom input and output ranges
J2 = imadjust(I, [0.3 0.7], [0 1]);

In the second example, input values below 0.3 are mapped to 0, those above 0.7 are mapped to 1, and values in between are stretched linearly across the whole range. This enhances contrast in a specific intensity band.

Histogram-Based Transformations

Histogram-based transformations look at how pixel intensities are distributed over their possible values, then apply a mapping to change that distribution. These methods are very useful when the image is too dark, too bright, or has poor contrast in general.

The intensity histogram of a grayscale image shows how many pixels have each possible intensity value. To compute it, you can use imhist:

matlab
I = imread("cameraman.tif");
figure;
imhist(I);

If most bars in the histogram cluster near the low end, the image is mostly dark. If they cluster near the high end, it is mostly bright. If they occupy only a narrow range, the image has low contrast.

Histogram equalization is a common transformation that tries to spread intensities more evenly across the available range, which usually increases overall contrast. In MATLAB you can use histeq:

matlab
I = imread("pout.tif");
J = histeq(I);
imshowpair(I, J, "montage");

The output J often appears to have more visible detail in darker or lighter regions. histeq works best for images where many pixels share similar intensities and important details are compressed into a small part of the intensity range. It is not always suitable for every type of image, for example medical images or images where the original intensity relationships are critical.

Another useful function is adapthisteq, which applies contrast-limited adaptive histogram equalization. Instead of using a single transformation for the entire image, it computes transformations for small regions and then combines them. This can improve local contrast and reveal details in different parts of the image:

matlab
I = imread("pout.tif");
J = adapthisteq(I);
imshowpair(I, J, "montage");

Here, adapthisteq tries to prevent overamplification of noise by limiting the contrast enhancement within each region.

Color Image Adjustments

Color images contain multiple channels, typically red, green, and blue. Transformations can be applied independently to each channel, or you can convert the image to a different color space where brightness is separated from color, adjust it there, and convert back.

To work directly with channels, you can index the third dimension of the image:

matlab
I = imread("peppers.png");
R = I(:, :, 1);
G = I(:, :, 2);
B = I(:, :, 3);
R_adj = imadjust(R);
G_adj = imadjust(G);
B_adj = imadjust(B);
J = cat(3, R_adj, G_adj, B_adj);
imshow(J);

This adjusts contrast separately for each channel. Since each channel may have a different distribution, this sometimes shifts colors. For more natural results, you can use color-specific functions like rgb2hsv and hsv2rgb. In HSV space, the V component describes brightness, while H and S describe hue and saturation:

matlab
I = imread("peppers.png");
I_hsv = rgb2hsv(I);
H = I_hsv(:, :, 1);
S = I_hsv(:, :, 2);
V = I_hsv(:, :, 3);
V_adj = imadjust(V);         % adjust only brightness channel
I_hsv_adj = cat(3, H, S, V_adj);
J = hsv2rgb(I_hsv_adj);
imshow(J);

Here, the transformation affects brightness without altering hue and saturation as much, so colors tend to remain more consistent.

Gamma correction is another important brightness transformation. It applies a power law to intensities:

$$
I_{\text{out}} = I_{\text{in}}^{\gamma}
$$

with \( \gamma > 0 \). When \( \gamma < 1 \), dark regions become brighter. When \( \gamma > 1 \), bright regions are suppressed and dark regions are emphasized less. In MATLAB you can specify a gamma value in imadjust:

matlab
I = imread("cameraman.tif");
Id = im2double(I);
gamma = 0.5;           % brighten dark areas
J = imadjust(Id, [], [], gamma);
imshow(J);

Smoothing and Sharpening as Simple Transformations

Although more advanced processing involves filtering and frequency transforms, there are simple smoothing and sharpening transformations that can be used by beginners to improve images.

Smoothing reduces noise and small variations in intensity, often at the cost of some blurring. MATLAB provides imgaussfilt for Gaussian smoothing:

matlab
I = imread("cameraman.tif");
I_smooth = imgaussfilt(I, 2);     % sigma = 2
imshowpair(I, I_smooth, "montage");

Here, the second argument controls the standard deviation of the Gaussian kernel. Larger values produce stronger smoothing and more blur.

Sharpening emphasizes edges and quickly varying details. MATLAB provides imsharpen:

matlab
I = imread("pout.tif");
I_sharp = imsharpen(I);
imshowpair(I, I_sharp, "montage");

This increases local contrast around edges, making them appear more defined. Excessive sharpening can create halos or enhance noise, so it is best used moderately.

Combining Transformations in a Workflow

In practice, you often apply several transformations in sequence. For example, you might crop an image, resize it, and then adjust its brightness and contrast:

matlab
I = imread("peppers.png");
% crop
I_crop = I(51:250, 101:350, :);
% resize
I_resize = imresize(I_crop, [200 200]);
% adjust brightness and contrast
I_double = im2double(I_resize);
I_adj = imadjust(I_double, [0.2 0.8], [0 1]);
imshow(I_adj);

The order of operations matters. Cropping before resizing preserves more detail in the region of interest, while adjusting brightness and contrast after resizing applies the transformation to the final pixel values, which can sometimes give better visual results.

When combining transformations, keep an eye on the image class and value range. Some functions expect data in the range \([0,1]\) for double, while others work directly on integer classes such as uint8. Functions like im2double, im2uint8, and mat2gray help you convert between these representations when needed.

Important points to remember:

  1. Use flips, rotations, and resizing to change geometry of images without altering pixel content.
  2. Crop images by indexing or imcrop to focus on regions of interest.
  3. Adjust brightness and contrast carefully, and watch the data type and value range.
  4. Use histogram-based methods like histeq and adapthisteq to improve contrast, especially in low contrast images.
  5. For color images, consider working in color spaces that separate brightness from color, such as HSV.
  6. Smoothing can reduce noise but also blur details, while sharpening enhances edges but can amplify noise.
  7. Combine transformations in a sensible order, and always check the visual result after each main step.

Views: 51

Comments

Please login to add a comment.

Don't have an account? Register now!