MATLAB: Local histogram equalization manually

image processingImage Processing Toolboxlocal histogram equalization

I am implementing local histogram equalization manually but the result is no satisfactory What i want and what i am getting is in picture …
here is code:
I=rgb2gray(imread('peppers.png'));
if (isa(I,'uint8'))
I=double(I)/255;
end
if (size(I,3)==3)
I=(I(:,:,1)+I(:,:,2)+I(:,:,3))/3; % average the RGB channels
end
windowsize=17;
% Create an empty array
Ieq = zeros(size(I,1),size(I,2));
% Apply this over a NxN region around each pixel (N is odd)
n = floor(windowsize/2); % <-- N is the half size of the region ie. [-N:N,-N:N]
for r=1+n:size(I,1)-n
for c=1+n:size(I,2)-n
% -- INSERT YOUR CODE BELOW ------------------------------------------
% NOTE: For pixels near the boundary, ensure the NxN neighbourhood is still
% inside the image (this means for pixels near the boundary the pixel may
% not be at the centre of the NxN neighbourhood).
if r-n <=1
fromrow=1;
torow=r+n;
else
fromrow=abs(r-n);
if n+r >= size(I,1)
torow=size(I,1);
else
torow=r+n;
end
end
if c-n <= 1
fromcol=1;
tocol=c+n;
else
fromcol=abs(c-n);
if c+n > size(I,2);
tocol=size(I,2);
else
tocol=c+n;
end
end
neighbour = I(fromrow:torow,fromcol:tocol);
lessoreq=neighbour(neighbour<=I(r,c));
sumofval=sum(lessoreq);
pixval=sumofval/(size(neighbour,1)*size(neighbour,2));
Ieq(r,c)=pixval;
% -- INSERT YOUR CODE ABOVE ------------------------------------------
end
end
imshow(Ieq);

Best Answer

I'm assuming this isn't your homework since you didn't label it as homework, so this will work, however you can do it much faster with adapthisteq() or by using intlut() to make up a look up table rather than using a double for loop.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
grayImage = rgb2gray(imread('peppers.png'));
subplot(1,2,1);
imshow(grayImage);
axis on;
drawnow;
if (isa(grayImage,'uint8'))
grayImage=double(grayImage)/255;
end
if (size(grayImage,3)==3)
grayImage=(grayImage(:,:,1)+grayImage(:,:,2)+grayImage(:,:,3))/3; % average the RGB channels
end
windowsize = 17;
% Create an empty array
Ieq = zeros(size(grayImage,1),size(grayImage,2));
% Apply this over a NxN region around each pixel (N is odd)
n = floor(windowsize/2); % <-- N is the half size of the region ie. [-N:N,-N:N]
for r=1+n:size(grayImage,1)-n
fprintf('Processing row #%d\n', r);
for c=1+n:size(grayImage,2)-n
% -- INSERT YOUR CODE BELOW ------------------------------------------
% NOTE: For pixels near the boundary, ensure the NxN neighbourhood is still
% inside the image (this means for pixels near the boundary the pixel may
% not be at the centre of the NxN neighbourhood).
if r-n <=1
fromrow=1;
torow=r+n;
else
fromrow=abs(r-n);
if n+r >= size(grayImage,1)
torow=size(grayImage,1);
else
torow=r+n;
end
end
if c-n <= 1
fromcol=1;
tocol=c+n;
else
fromcol=abs(c-n);
if c+n > size(grayImage,2);
tocol=size(grayImage,2);
else
tocol=c+n;
end
end
neighbors = grayImage(fromrow:torow, fromcol:tocol);
counts = imhist(neighbors, 256);
cdf = cumsum(counts);
cdf = cdf ./ cdf(end); % Normalize.
% Get the original value of the central pixel that we need to replace.
centerGrayLevel = grayImage(r, c);
% Now see what it gets mapped to.
index = ceil(256 * centerGrayLevel);
newPixelValue = cdf(index);
% Do the assignment
Ieq(r,c) = newPixelValue;
% -- INSERT YOUR CODE ABOVE ------------------------------------------
end
end
subplot(1,2,2);
imshow(Ieq, []);
axis on;
msgbox('Done');