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,
- Producing red, green, blue, and grayscale versions of an image.
- Gamma correction of an image.
- Histogram Equalization
- Gaussian Smoothing a Noisy Image
- Zooming on image.
- 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.
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')
Similar to above you can zero out the other channels and obtain green and blue images.
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')
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.
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')
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')
4) Gaussian Smoothing a Noisy Image
Method: Convolving the image with a Gaussian function. The Gaussian kernel used is given below.
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
endfigure,
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);
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-1ssd1 = 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(:));
endif( 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
endfigure,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' )