Matlab histogram equilization without using built in function - image

Hello I am new at Matlab..I am trying to do histogram equilzation without using histeq...
but for some reason i always get an error of : ??? Index exceeds matrix dimensions.
here is my code..................................................Thanks for your help
clc
I = imread ('Machine-Edge.PNG');
I2 = rgb2gray(I);
colormap gray;
y = imhist(I2);
%using hist eq. built in fn
I3= histeq(I2);
z= imhist(I3);
%my equalization
r = size(I2,1);
c = size(I2,2);
A= zeros(1,256);
%counting number of pixels of the image and putting the count in Array A
for j=1:r
for x=1:c
v=I2(j,x);
A(v+1)=A(v+1)+1;
end
end
%pi=n/size
for y=1;256
pi(y)= ((A(y))/(r*c));
end
%calculate CI (cumulated pi )
ci(1)=pi(1);
for yy=2;256
ci(yy) = ci(yy-1)+ pi(yy);
end
%calculate T=range *Ci
for b=1;256
T(b)=ci(b)*255;
end
%equilization..replacing each pixel with T value
for j=1:r
for x=1:c
I4(j,x) =T(I2(j,x));
end
end
vv= imhist(I4);
figure
subplot(3,2,1)
imagesc(I2)
subplot(3,2,2)
plot(y)
subplot(3,2,3)
imagesc(I3)
subplot(3,2,4)
plot(z)
subplot(3,2,5)
imagesc(I4)
subplot(3,2,6)
plot(vv)

This is an old post but the OP used ; instead of : in their for loops (i.e. for y=1;256 should read for y=1:256). the corrected code is below:
clc
I = imread ('Machine-Edge.PNG');
I2 = rgb2gray(I);
colormap gray;
y = imhist(I2);
%using hist eq. built in fn
I3= histeq(I2);
z= imhist(I3);
%my equalization
r = size(I2,1);
c = size(I2,2);
A= zeros(1,256);
%counting number of pixels of the image and putting the count in Array A
for j=1:r
for x=1:c
v=I2(j,x);
A(v+1)=A(v+1)+1;
end
end
%pi=n/size
for y=1:256
pi(y)= ((A(y))/(r*c));
end
%calculate CI (cumulated pi )
ci(1)=pi(1);
for yy=2:256
ci(yy) = ci(yy-1)+ pi(yy);
end
%calculate T=range *Ci
for b=1:256
T(b)=ci(b)*255;
end
%equilization..replacing each pixel with T value
for j=1:r
for x=1:c
I4(j,x) =T(I2(j,x));
end
end
vv= imhist(I4);
figure
subplot(3,2,1)
imagesc(I2)
subplot(3,2,2)
plot(y)
subplot(3,2,3)
imagesc(I3)
subplot(3,2,4)
plot(z)
subplot(3,2,5)
imagesc(I4)
subplot(3,2,6)
plot(vv)

Related

making convolution in matlab manualy

I want to make convolution image processing in matlab without to use (conv2) command
I want to use (.^) command with 2 for loop
I make this code to make LoG 5x5 filter
but it not work in this line (I(r,c) =sum(sum( Mask.* I( (r-2):(c-2), (r+2):(c+2) ) ));)
clc
clear;
Img = imread ('11.jpg'); %reading Image
for x = 1:size(Img,1) % converting to Gray
for y =1:size(Img,2)
G (x,y)= (Img(x,y,1)*0.3 + Img(x,y,2)*0.59 + Img(x,y,1)* 0.11);
end
end
Mask = [0,0,-1,0,0;0,-1,-2,-1,0;-1,-2,16,-2,-1;0,-1,-2,-1,0;0,0,-1,0,0]; % the mask
I=double(G);Mask=double(Mask);
% I=conv2(G,Mask); % masking quickly
for r = 3: size(I,1)-2 %masking manualy
for c = 3: size(I,2)-2
I(r,c) =sum(sum( Mask.* I( (r-2):(c-2), (r+2):(c+2) ) ));
end
end
imshow(Img);title('Orginal Image');
figure,imshow(G);title('Gray Image');
figure,imshow(uint8(I));title('Proccessed Image');
Debug is a good way to solve some problems.
When c = 4, r = 3(The second loop in "for c = 3: size(I,2)-2")
I( (r-2):(c-2), (r+2):(c+2) ) is a 2 * 2 Matrix,
and Mask is a 5*5 Matrix.
So the error message is "Matrix dimensions must be consistent".

How to fix the undefined function or variable error?

I am working on Matlab 17.a program's image processing. My work is about histogram equalization. The code is as follows. But when I run the code "Undefined function or variable 'cumulavite_hist'." I get an error. How do I fix this problem? Thank you for your help.
The output will be the histogram next to the original image. Below it will be the changing picture and histogram. Thank you for your help.
>> img= imread ('C:\Users\emre.guzel\Desktop\homeworkimage.png');
if (size(img,3)>1)
img=rgb2gray(img);
end
max_r = size (img,1);
max_c =size (img,2);
histogram =zeros ([1 256]);
cumulative_hist = zeros ([1 256]);
for r=1:max_r
for c=1:max_c
for count =1:256
if(img(r,c) == count-1 )
histogram (count) =histogram (count)+ 1;
break ;
end
end
end
end
%find cumulative histogram
current_value = 0;
for count=1:256
current_value = current_value + histogram (count);
cumulative_hist(count) = current_value;
end
%find h =(cdf-cdf(min) / (MN - cdf (min) )) * 255
%this is the normalized cumulative histogram normalize dediğine bakma sen.
%histogram equalization formulu bu . aşağıda da bunu uygulamış.
normalized_hist = zeros ([1 256]);
cdf_min = min (cumulavite_hist) ;
for count = 1:256
normalized_hist(count) = cumulative_hist(count) - cdf_min;
normalized_hist(count) = normalized_hist (count) / ((max_r*max_c)- cdf_min);
normalized_hist(count) = round (normalized_hist (count) * 255);
end
%replace the values with given equalized values
equalized_image = zeros ([max_r max_c]);
for r =1:max_r
for c=1:max_c
for count = 1:256
if(img(r,c) ==(count-1))
%
%
equlized_img(r,c) = normalized_hist(count);
break;
end
end
end
end
subplot(2,2,1)
imshow(img);
title('Orijinal Image');
subplot (2,2,2);
imhist(img) ;
title ('Hist of Orijinal Image');
subplot(2,2,3) ;
imhist (uint8(equalized_img));
title('Histogram Equalized Image');
H = uint (equalized_img);
subplot(2,2,4) ;
imhist(H) ;
title ('Histogram of Histogram Equalized Image');
a = histeq(img);
figure
imshow(a)
You have cumulative_hist variable at line 10 and cumulavite_hist variable used in line 33. It's just wrong name in line 33. Fix it and program will work.

Annoying bug in MATLAB

I'm doing a project and i needed to write two functions. The first is mk_key and its job is to convert a 24 RGB image into a vector consisting of consecutive bytes followed by a trailer consisting of 4 bytes that hold the dimensions of the image for reconstructing (so the vector size is [1 m*n*3+4]) then the elements of that vector are shuffled randomly according to a seed value (acting like a password) and finally the vector is saved to a file using hexa bytes; the other function is use_key and it is used to reconstruct the image from the key file, this is done by re-arranging the vector elements back into their positions and then using the data at the trailer to reconstruct the full RGB image. The only problem i have is that the reconstructed image has most of it's pixels lost and it only shows about 1/6 of the image and only at the red plane, the bytes at the other planes appear gray.
mk_key:
function mk_key(img, dest_file, seed)
s=size(img);
m=s(1);
n=s(2);
rg = zeros([1 m*n 3],'uint8');
for i=drange(1:m)
for j=drange(1:n)
rg(1,n*i+j-n,:)=img(i,j,:); %convert rectangular image matrix into row image
end
end
rgf = zeros([1 (m*n*3)+4],'uint8');
for x=drange(1:3)
rgf(1,(m*n*(x-1))+1:m*n*x)=rg(1,1:m*n,x);
end
mm=uint16(m);
nn=uint16(n);
rgf(1,(m*n*3)+1)=uint8(bitand(mm,hex2dec('00ff')));
rgf(1,(m*n*3)+2)=uint8(bitshift(bitand(mm,hex2dec('ff00')),-8));
rgf(1,(m*n*3)+3)=uint8(bitand(nn,hex2dec('00ff')));
rgf(1,(m*n*3)+4)=uint8(bitshift(bitand(nn,hex2dec('ff00')),-8));
rng(seed);
idxs = randperm(((m*n*3)+4)); % generate a random sequence representing byte locations
sg = zeros([1 ((m*n*3)+4)],'uint8');
for i=drange(1:((m*n*3)+4))
sg(1,i)=rgf(1,idxs(i));
end
f = fopen(dest_file, 'w');
for i=drange(1:((m*n*3)+4))
fprintf(f, '%x %x', sg(1,i));
end
fclose('all');
end
use_key:
function [img]=use_key(source_file, seed)
key_file=fopen(source_file);
key=fscanf(key_file,'%x %x');
key=key'; %Transpose column vector into row vector
key=uint8(key);
s=size(key);
rng(seed);
idxs = randperm(s(2)); % generate a random sequence representing byte locations
mgf = zeros([1 s(2)],'uint8');
for i=drange(1:s(2))
mgf(1,idxs(i))=key(1,i);
end
m=uint16(mgf(1,s(2)-3))+uint16(mgf(1,s(2)-2))*(16^2);
n=uint16(mgf(1,s(2)-1))+uint16(mgf(1,s(2)))*(16^2);
img = zeros([m n 3],'uint8');
for x=drange(1:3)
for i=drange(1:m)
for j=drange(1:n)
img(i,j,x)=mgf(1,(n*i+j-n)+(m*n)*(x-1));%convert row matrix into rectangular image matrix
end
end
end
fclose('all');
end
Whatever the bug is, it's somewhere in those horrible nested loops. Rather than attempt to fix what looks like a direct port of C code, I started cleaning up all the confusing and needlessly overcomplicated bits so I could make sense of it; by the time I'd finished, there wasn't much left:
function mk_key(img, dest_file, seed)
s = uint16(size(img));
s = typecast(s(1:2), 'uint8');
rg = reshape(img, 1, []);
rgf = [rg s];
rng(seed);
idxs = randperm(numel(rgf));
sg = rgf(idxs);
f = fopen(dest_file, 'w');
fprintf(f, '%x ', sg);
fclose(f);
end
and correspondingly:
function [img] = use_key(source_file, seed)
key_file = fopen(source_file);
key = fscanf(key_file,'%x');
fclose(key_file);
rng(seed);
idxs = randperm(numel(key));
mgf = zeros(1, numel(key), 'uint8');
mgf(idxs) = key;
s = typecast(mgf(end-3:end), 'uint16');
img = reshape(mgf(1:end-4), s(1), s(2), 3);
end
Whilst the ordering from reshape is different compared to your loops, that makes no practical difference given that the vector then gets shuffled - it's more robust, works as expected and is considerably quicker.

Discrete cosine transform (DCT) of an image

I work on a function in Matlab that calculates the DCT (discrete cosine transform) of an image. I don't know what is not working in my code, but I got an output image with the same number. I want to use this formula for my DCT.
Any ideas please.
function image_comp = dctII(image, b)
[h w] = size(image);
image = double(image) - 128;
block = zeros(b,b);
image_t=zeros(size(image));
for k=1:b:h
for l=1:b:w
image_t(k:k+b-1,l:l+b-1)= image(k:k+b-1,l:l+b-1);
for u=1:b
for v=1:b
if u == 0
Cu = 1/sqrt(2);
else
Cu = 1;
end
if v == 0
Cv = 1/sqrt(2);
else
Cv = 1;
end
Res_sum=0;
for x=1:b;
for y=1:b
Res_sum = Res_sum + ((image_t(x,y))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
end
end
dct= (1/4)*Cu*Cv*Res_sum;
block(u,v) = dct;
end
end
image_comp(k:k+b-1,l:l+b-1)=block(u,v);
end
end
end
In the inner loop over x and y, you are not reading from the correct place in image_t. You have copied the local block into a location with k,l as the upper left corner for use in processing, but in the inner loop you are always reading from the same block that starts at 1,1 as the upper left corner in image_t.

How to make a Gaussian filter in Matlab

I have tried to make a Gaussian filter in Matlab without using imfilter() and fspecial().
I have tried this but result is not like the one I have with imfilter and fspecial.
Here is my codes.
function Gaussian_filtered = Gauss(image_x, sigma)
% for single axis
% http://en.wikipedia.org/wiki/Gaussian_filter
Gaussian_filtered = exp(-image_x^2/(2*sigma^2)) / (sigma*sqrt(2*pi));
end
for 2D Gaussian,
function h = Gaussian2D(hsize, sigma)
n1 = hsize;
n2 = hsize;
for i = 1 : n2
for j = 1 : n1
% size is 10;
% -5<center<5 area is covered.
c = [j-(n1+1)/2 i-(n2+1)/2]';
% A product of both axes is 2D Gaussian filtering
h(i,j) = Gauss(c(1), sigma)*Gauss(c(2), sigma);
end
end
end
and the final one is
function Filtered = GaussianFilter(ImageData, hsize, sigma)
%Get the result of Gaussian
filter_ = Gaussian2D(hsize, sigma);
%check image
[r, c] = size(ImageData);
Filtered = zeros(r, c);
for i=1:r
for j=1:c
for k=1:hsize
for m=1:hsize
Filtered = Filtered + ImageData(i,j).*filter_(k,m);
end
end
end
end
end
But the processed image is almost same as the input image. I wonder the last function GaussianFiltered() is problematic...
Thanks.
here's an alternative:
Create the 2D-Gaussian:
function f=gaussian2d(N,sigma)
% N is grid size, sigma speaks for itself
[x y]=meshgrid(round(-N/2):round(N/2), round(-N/2):round(N/2));
f=exp(-x.^2/(2*sigma^2)-y.^2/(2*sigma^2));
f=f./sum(f(:));
Filtered image, given your image is called Im:
filtered_signal=conv2(Im,gaussian2d(N,sig),'same');
Here's some plots:
imagesc(gaussian2d(7,2.5))
Im=rand(100);subplot(1,2,1);imagesc(Im)
subplot(1,2,2);imagesc(conv2(Im,gaussian2d(7,2.5),'same'));
This example code is slow because of the for-loops. In matlab you can better use conv2, as suggested by user:bla, or just use filter2.
I = imread('peppers.png'); %load example data
I = I(:,:,1);
N=5; %must be odd
sigma=1;
figure(1);imagesc(I);colormap gray
x=1:N;
X=exp(-(x-((N+1)/2)).^2/(2*sigma^2));
h=X'*X;
h=h./sum(h(:));
%I=filter2(h,I); %this is faster
[is,js]=size(I);
Ib = NaN(is+N-1,js+N-1); %add borders
b=(N-1)/2 +1;
Ib(b:b+is-1,b:b+js-1)=I;
I=zeros(size(I));
for i = 1:is
for j = 1:js
I(i,j)=sum(sum(Ib(i:i+N-1,j:j+N-1).*h,'omitnan'));
end
end
figure(2);imagesc(I);colormap gray

Resources