Image Processing — Basics (Part 1 of 3)

Sybernix
6 min readOct 30, 2021

--

In this series of 3 blogs, I will explain various techniques in image processing. The content is taken from the assignments I submitted for the module EN 2550 — Fundamentals of Image Processing and Machine Vision at the University of Moratuwa during my undergraduate studies. The module was taught by Dr. Ranga Rodrigo.

The code will be in Matlab, however, you can use Python as well with its syntax. In this first part, I will cover the following topics,

  1. Producing red, green, blue, and grayscale versions of an image.
  2. Gamma correction of an image.
  3. Histogram Equalization
  4. Gaussian Smoothing a Noisy Image
  5. Zooming on image.
  6. Rotating an image by given degrees

1) Producing red, green, blue, and grayscale versions of an image.

Method: Image is represented as a 3D array or three 2D arrays for each R G and B. We can extract each of these 2D arrays to produce 3 color versions.

testImage.png

Code snippet for extracting the red channel of an image:

im = imread('testImage.png');
imshow(im);
im(:,:,3)=0;
im(:,:,2)=0;
figure;
imshow(im);
imwrite(im,'imred.png')
Red channel of the testImage

Similar to above you can zero out the other channels and obtain green and blue images.

Blue and green channels of testImage

Grayscale is produced by taking an average of R G and B.

im = imread('testImage.png');
imshow(im);
imGray = im(:,:,1)./3 + im(:,:,2)./3 + im(:,:,3)./3
figure;
imshow(imgray);
imwrite(imgray, 'imgray.png')
Greyscale image of testImage

2) Gamma correction of an image.

Method: s = c*r^(gamma) where s is the pixels in the output image and r is that of the input, also c and gamma are constants.

testImage.png and its graph without gamma correction
image = imread('testImage.png');
image = im2double(image);
gamma = input('Enter gamma: ');
c=1/(1.0^gamma);
result = 255.0*c*((image/255.0).^gamma);
subplot(1,2,1)
imshow(image);
subplot(1,2,2)
imshow(result);
title('Processed')
imwrite(result, 'gammaCorrected.png')
testImage with a gamma > 1 correction
testImage with a gamma <1 correction

3) Histogram Equalization

Where sk is the brightness value of k th pixel on output image and L is the number of values for one color. M and N are equal to the height and width respectively.

img = imread('pout.tif');
%img = rgb2gray(im);
%imshow(im);
numBins = 256;
binBounds = linspace(0,255,numBins+1);
cumHist = zeros(numBins+1, 1);
for i = 2:numBins+1
cumHist(i) = sum(sum(img<=binBounds(i)));
end
hist = cumHist(2:end) - cumHist(1:end-1);
binCenters = (binBounds(2:end) + binBounds(1:end-1))/2;
t = zeros(numBins,1);
[m,n] = size(img);
for i = 1:numBins
tempsum=0;
for j = 1:i
tempsum = tempsum + hist(j);
end
t(i) = round(255.0*tempsum/(m*n));
end
s = t(img+1);
s=(mat2gray(s));
figure;
%subplot(1,2,1)
bar(binCenters,hist,0.2);
%subplot(1,2,2)
figure
imhist(im2double(s));
figure
%subplot(1,2,1)
imshow(img);
%subplot(1,2,2)
figure
imshow(s);
imwrite(s,'histogramEqualized.png')
Original image and it’s histogram
Histogram equalized image

4) Gaussian Smoothing a Noisy Image

Method: Convolving the image with a Gaussian function. The Gaussian kernel used is given below.

Gaussian kernel
hw = 3;
a = hw;
b = hw;
[Y,X] = meshgrid(-a:a, -b:b);
sigma = 2;
g = exp(-(X.^2 + Y.^2)/sigma^2);
surf(g)
f = imread('noisy.jpg');
f = rgb2gray(f);
figure,
imshow(f);
[h, w] = size(f);
f = im2double(f);
o = zeros(h, w);
for m=a+1:h-a
for n=b+1:w-b
o(m,n) = sum(sum(f(m-a:m+a, n-b:n+b).*g));
end
end
figure,
b = mat2gray(o);
imshow(b);
imwrite(b, 'gaussianSmooth.png');
sobelX = [-1, -2, -1; 0, 0, 0; 1, 2, 1];
sobelY = [-1, 0, 1; -2, 0, 2; -1, 0, 1];
outputImX = zeros(h, w);
outputImY = zeros(h, w);
for i = 2:h-1
for j = 2:w-1
outputImX(i,j) = (sum(sum(o(i-1:i+1, j-1:j+1).*sobelX)))/4;
end
end
figure;
outputImX = mat2gray(outputImX);
imshow(outputImX);
Original image (left) and Gaussian smoothed image (right)

5) Zooming on image.

Method 1: Nearest-neighbor method. Copying the pixel value to a grid of size of the factor specified and generating an image with the copied pixels.

[m,n,d] = size(imageInput);
zoomedImage = zeros(m*factor, n*factor,d);
for i = 1:m*factor
for j = 1:n*factor
zoomedImage(i,j,:) = imageInput(ceil(i/factor),ceil(j/factor),:);
end
end

Method 2: Bilinear Interpolation. Taking a quadratic weighted average of surrounding pixel values in 2D grid.

image='g.jpg';
factor=4; %zooming factor
a=imread(image); %import image"y.jpg"
[m, n, d] = size(a); %3 dimentional array
rows=factor*m;
columns=factor*n;
for i=1:rows-1
x=i/factor;
x1=floor(x);
x2=ceil(x);
if x1==0
x1=1;
end
xrem=rem(x,1);
for j=1:columns
y=j/factor;

y1=floor(y);
y2=ceil(y);
if y1==0
y1=1;
end
yrem=rem(y,1);

BottomLeft=a(x1,y1,:);
TopLeft=a(x1,y2,:);
BottomRight=a(x2,y1,:);
TopRight=a(x2,y2,:);

R1=BottomRight*yrem+BottomLeft*(1-yrem);
R2=TopRight*yrem+TopLeft*(1-yrem);

im_zoom(i,j,:)=R1*xrem+R2*(1-xrem);
end
end
size(im_zoom)
imwrite(im_zoom,'bilinear zoom.png');
imshow(im_zoom);

Calculating sum squared difference (SSD)

imageBig = imread('g4.jpg');
nearestNeighbor = imread('bilinear zoom.png');
[a,b,c] = size(nearestNeighbor);
a=a-1
ssd1 = 0;
imageBig2 = im2double(imageBig);
nearestNeighbor2 = im2double(nearestNeighbor);
count = 0;
for k =1:3
for i = 1:a
for j = 1:b
%count = count +1
%i
diff = (imageBig2(i,j,k) - nearestNeighbor2(i+1,j,k));
%diff
diff = diff*255;
diff
ssd1 = ssd1 + diff^2;
%ssd1
end
end
end
%print ssd1;

5) Rotating an image by given degrees

Method: Mapping the Cartesian co-ordinates of the image pixels to polar and rotating by certain degree and re- mapping to Cartesian. Nearest neighbor method is used to fill the gaps.

A=imread('android.jpg');%Specify the degree
deg=45;
%Find the midpoint
if(deg>155)
midx = ceil((size(A,1))/2);
midy = ceil((size(A,2))/2);
else
midx = ceil((size(A,2))/2);
midy = ceil((size(A,1))/2);
end
[y,x] = meshgrid(1:size(A,2), 1:size(A,1));
[t,r] = cart2pol(x-midx,y-midy);
t1 = radtodeg(t)+deg;
%Convert from degree to radians
t = degtorad(t1);
%Convert to Cartesian Co-ordinates
[x,y] = pol2cart(t,r);
tempx = round(x+midx);
tempy = round(y+midy);
if ( min(tempx ( : ) ) < 0 )

newx = max(tempx(:))+abs(min(tempx(:)))+1;
tempx = tempx+abs(min(tempx(:)))+1;
else
newx = max(tempx(:));
end
if( min(tempy ( : ) ) < 0 )

newy = max(tempy(:)) + abs(min(tempy(:)))+1;
tempy = tempy + abs(min(tempy(:)))+1;
else
newy = max(tempy(:));
end
tempy(tempy==0) = 1;
tempx(tempx==0) = 1;
C = uint8(zeros([newx newy 3]));
for i = 1:size(A,1)
for j = 1:size(A,2)

C( tempx(i,j),tempy(i,j) ,:) = A(i,j,:);


end

end
figure,imshow(C);
imwrite(C,'rot.jpg')
Output=C;
%FILL THE HOLES OR GAPS - NEAREST NEIGHBOR
for i = 2:size(C,1)-1
for j = 2:size(C,2)-1

temp = C(i-1:i+1,j-1:j+1,:);
if(temp(5)==0 && sum(temp(:))~=0)

pt = find(temp(:,:,1)~=0);
[~,pos] = sort(abs(pt-5));

temp = C(i-1:i+1,j-1:j+1,1);
Output(i,j,1) = temp(pt(pos(1)));

temp = C(i-1:i+1,j-1:j+1,2);
Output(i,j,2) = temp(pt(pos(1)));

temp = C(i-1:i+1,j-1:j+1,3);
Output(i,j,3) = temp(pt(pos(1)));
end

end
end
figure, imshow(Output);
imwrite(Output, 'rot2.jpg' )

--

--

No responses yet