Image Segmentation WIth Self Organizing Map in Matlab - matlab

i'm making image segmentation with self organizing map. the image segement by 3 cluster. Sample image is :
and i have type the matlab code like this bellow :
clear;
clc;
i=imread('DataSet/3.jpg');
I = imresize(i,0.5);
cform = makecform('srgb2lab');
lab_I = applycform(I,cform);
ab = double(lab_I(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);
a = ab(:,1);
b = ab(:,2);
normA = (a-min(a(:))) ./ (max(a(:))-min(a(:)));
normB = (b-min(b(:))) ./ (max(b(:))-min(b(:)));
ab = [normA normB];
newnRows = size(ab,1);
newnCols = size(ab,2);
cluster = 3;
% Max number of iteration
N = 90;
% initial learning rate
eta = 0.3;
% exponential decay rate of the learning rate
etadecay = 0.2;
%random weight
w = rand(2,cluster);
%initial D
D = zeros(1,cluster);
% initial cluster index
clusterindex = zeros(newnRows,1);
% start
for t = 1:N
for data = 1 : newnRows
for c = 1 : cluster
D(c) = sqrt(((w(1,c)-ab(data,1))^2) + ((w(2,c)-ab(data,2))^2));
end
%find best macthing unit
[~, bmuindex] = min(D);
clusterindex(data)=bmuindex;
%update weight
oldW = w(:,bmuindex);
new = oldW + eta * (reshape(ab(data,:),2,1)-oldW);
w(:,bmuindex) = new;
end
% update learning rate
eta= etadecay * eta;
end
%Label Every Pixel in the Image Using the Results from KMEANS
pixel_labels = reshape(clusterindex,nrows,ncols);
%Create Images that Segment the I Image by Color.
segmented_images = cell(1,3);
rgb_label = repmat(pixel_labels,[1 1 3]);
for k = 1:cluster
color = I;
color(rgb_label ~= k) = 0;
segmented_images{k} = color;
end
figure,imshow(segmented_images{1}), title('objects in cluster 1');
figure,imshow(segmented_images{2}), title('objects in cluster 2');
figure,imshow(segmented_images{3}), title('objects in cluster 3');
and after runing the matlab code, there is no image segmentation result. Matlab show 3 figure, Figure 1 show the full image, figure 2 blank, figure 3 blank .
please anyone help me to revise my matlab code, is any wrong code or something?

new = oldW + eta * (reshape(ab(data,:),2,1)-oldW);
This line looks suspicious to me, why you are subtracting old weights here, i dont think this makes any sense there, just remove oldW from there and check your results again.
Thank You

Related

How to compute a channel capacity formula using Matlab

I am trying to compute the following formula:enter image description here
Basically, I am provided with 2 vectors which contain the values of both cj (constellation elements) and p (probability of said constellation elements). With this information, the computation of the channel capacity should be straight forward employing my code:
clear all;
close all;
load('parametros.mat');
%Code
figure();
plot(elements_constellation,prob);
%Energy/2D of the code
Ec = (1/length(elements_constellation))*sum(elements_constellation.^2);
Es = 2*Ec;
%Define variance values here:
sigma = 0.1;
Q_y_cj = zeros(1,length(elements_constellation));
P_Y = zeros(1,length(elements_constellation));
Q_y_cjprime = zeros(1,length(elements_constellation));
resultsintegral = zeros(1,length(elements_constellation));
cap = 0;
P_Y = 0;
figure();
x=1;
for y = 1:length(elements_constellation)
for ii=-11:11
Q_y_cj(x) = ((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
x = x+1;
end
x=1;
hold on
plot(elements_constellation,Q_y_cj)
end
x=1;
figure();
for y = 1:length(elements_constellation)
for ii=-11:11
P_Y(x) = prob(y).*((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
x = x+1;
end
x=1;
hold on
plot(elements_constellation,P_Y)
end
figure();
Q_y_cj_1 = zeros(1,length(elements_constellation));
P_Y = 0;
for y = 1:length(elements_constellation)
x=1;
for ii=-11:11
Q_y_cj_1(x) = ((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
for s=1:length(elements_constellation)
P_Y = P_Y + prob(s).*((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(s)).^2));
end
Q_y_cjprime(x) = Q_y_cj_1(x)*log10(Q_y_cj_1(x)/P_Y); %% These values are being overwritten
x = x+1;
P_Y = 0;
end
hold on;
plot(elements_constellation,Q_y_cjprime);
resultsintegral(y) = trapz(Q_y_cjprime);
end
figure();
plot(elements_constellation,resultsintegral);
for j=1:length(prob)
cap = cap + prob(j)*resultsintegral(j);
end
However, I am not convinced by the results my code generates for the channel capacity. For low values of sigma (noise variance), the capacity should increase logarithmically, but it grows exponentially when executing my algorithm.
Any help or advice on how to improve the computation of this formula would be greatly appreciated.

How to use the new functions of PDE toolbox in image processing (Matlab R2015a)

I want to use the line new command of PDE toolbox as Matlab R2015 to restore a noisy image with gaussian noise.
The PDE is:
∇.(( ∇u)/(√(1+|∇u|2))) +(f2)/(u2) = 1 in Ω (∂u)/(∂n)=0 in ∂Ω
Where f is the noisy image and u the restored image.
I tried the following code:
clear
close all
clc
img = 'AA.jpg';
mInputImage = double(imread(img));
mInputImage = rgb2gray(mInputImage);
[numRows, numCols] = size(mInputImage);
Var = 0.04;
Mean = 0;
mInputImageNoisy = imnoise((mInputImage(:,:,1)),'gaussian',Mean, Var);
% reshape the input and noisy images to vectors
mInputImageVector = reshape(mInputImage,numRows*numCols,1);
mInputImageNoisyVector = reshape(mInputImageNoisy,numRows*numCols,1);
Residu1 = norm(mInputImageVector-mInputImageNoisyVector)/norm(mInputImageVector)
RegularisationCoefficient = 0.7*ones((numRows-1)*(numCols-1),1);
mOutputImageVector = mInputImageNoisyVector;
%a = (mInputImageNoisyVector.^2) ./ mOutputImageVector.^3;
f = 1;
rtol = 1e-1;
c = '1./sqrt(1+ux.^2+uy.^2)';
% Create a PDE Model with a single dependent variable
numberOfPDE = 1;
pdem = createpde(numberOfPDE);
g = #squareg;
geometryFromEdges(pdem,g);
% Plot the geometry and display the edge labels for use in the boundary
% condition definition.
figure;
pdegplot(pdem, 'edgeLabels', 'on');
%axis([0 numRows 0 numCols]);
axis([-2 2 -2 2]);
title 'Geometry With Edge Labels Displayed'
b2 = applyBoundaryCondition(pdem,'Edge',[1 2 3 4], 'u', 0);
[p,e,t] = poimesh(g,numRows, numCols);
numCols
pdemesh(p,e,t);
axis equal
for iter = 1: numRows*numRows,
mOutputImageVector(iter) = pdenonlin(pdem,c,...
(mInputImageNoisyVector(iter).^2) ./ mOutputImageVector(iter).^3,...
f,'tol',rtol);
SaveImageVector(iter) = mOutputImageVector;
end
mOutputImage = reshape(SaveImageVector,numRows,numRows);
mOutputImage = uint8(mOutputImage);
figure()
imshow(mOutputImage)

Improving Performance of Content-Based Image Retrieval using Color Histograms in MATLAB

I am working on Content-Based Image Retrieval and Precision-Recall graphs using Color Histograms in MATLAB. Since, I have 1000 images in my database. When i query input image it takes around 12 seconds to execute and show PR curve. I am curious to know that, How do I improve the performance?
Code:
% Dir: parent directory location for images folder c1, c2, c3
% inputImage: \c1\1.ppm
% For example to get P-R curve execute: CBIR('D:\visionImages','\c2\1.ppm');
function [ ] = demoCBIR( Dir,inputImage)
% Dir='D:\visionImages';
% inputImage='\c3\1.ppm';
tic;
S=strcat(Dir,inputImage);
Inp1=imread(S);
num_red_bins = 8;
num_green_bins = 8;
num_blue_bins = 8;
num_bins = num_red_bins*num_green_bins*num_blue_bins;
A = imcolourhist(Inp1, num_red_bins, num_green_bins, num_blue_bins);%input image histogram
srcFiles = dir(strcat(Dir,'\*.jpg'));
B = zeros(num_bins, 100); % hisogram of other 100 images in category 1
ptr=1;
for i = 1 : length(srcFiles)
filename = strcat(Dir,'\',srcFiles(i).name);
I = imread(filename);% filter image
B(:,ptr) = imcolourhist(I, num_red_bins, num_green_bins, num_blue_bins);
ptr=ptr+1;
end
%normal histogram intersection
a = size(A,2); b = size(B,2);
K = zeros(a, b);
for i = 1:a
Va = repmat(A(:,i),1,b);
K(i,:) = 0.5*sum(Va + B - abs(Va - B));
end
%PR curve creation
sims=K;
for i=1: 100 % number of relevant images for dir 1
relevant_IDs(i) = i;
end
num_relevant_images = numel(relevant_IDs);
[sorted_sims, locs] = sort(sims, 'descend');
locations_final = arrayfun(#(x) find(locs == x, 1), relevant_IDs);
locations_sorted = sort(locations_final);
precision = (1:num_relevant_images) ./ locations_sorted;
recall = (1:num_relevant_images) / num_relevant_images;
plot(recall, precision, 'b.-');
xlabel('Recall');
ylabel('Precision');
title('Precision-Recall Graph');
axis([0 1 0 1.05]);
grid;
toc;
end
Elapsed time is 12.700687 seconds.

spiral meshgrid in matlab

I'm trying to produce some computer generated holograms by using MATLAB. I used equally spaced mesh grid to initialize the spatial grid, and I got the following image
This pattern is sort of what I need except the center region. The fringe should be sharp but blurred. I think it might be the problem of the mesh grid. I tried generate a grid in polar coordinates and the map it into Cartesian coordinates by using MATLAB's pol2cart function. Unfortunately, it doesn't work as well. One may suggest that using fine grids. It doesn't work too. I think if I can generate a spiral mesh grid, perhaps the problem is solvable. In addition, the number of the spiral arms could, in general, be arbitrary, could anyone give me a hint on this?
I've attached the code (My final projects are not exactly the same, but it has a similar problem).
clc; clear all; close all;
%% initialization
tic
lambda = 1.55e-6;
k0 = 2*pi/lambda;
c0 = 3e8;
eta0 = 377;
scale = 0.25e-6;
NELEMENTS = 1600;
GoldenRatio = (1+sqrt(5))/2;
g = 2*pi*(1-1/GoldenRatio);
pntsrc = zeros(NELEMENTS, 3);
phisrc = zeros(NELEMENTS, 1);
for idxe = 1:NELEMENTS
pntsrc(idxe, :) = scale*sqrt(idxe)*[cos(idxe*g), sin(idxe*g), 0];
phisrc(idxe) = angle(-sin(idxe*g)+1i*cos(idxe*g));
end
phisrc = 3*phisrc/2; % 3 arms (topological charge ell=3)
%% post processing
sigma = 1;
polfilter = [0, 0, 1i*sigma; 0, 0, -1; -1i*sigma, 1, 0]; % cp filter
xboundl = -100e-6; xboundu = 100e-6;
yboundl = -100e-6; yboundu = 100e-6;
xf = linspace(xboundl, xboundu, 100);
yf = linspace(yboundl, yboundu, 100);
zf = -400e-6;
[pntobsx, pntobsy] = meshgrid(xf, yf);
% how to generate a right mesh grid such that we can generate a decent result?
pntobs = [pntobsx(:), pntobsy(:), zf*ones(size(pntobsx(:)))];
% arbitrary mesh may result in "wrong" results
NPNTOBS = size(pntobs, 1);
nxp = length(xf);
nyp = length(yf);
%% observation
Eobs = zeros(NPNTOBS, 3);
matlabpool open local 12
parfor nobs = 1:NPNTOBS
rp = pntobs(nobs, :);
Erad = [0; 0; 0];
for idx = 1:NELEMENTS
rs = pntsrc(idx, :);
p = exp(sigma*1i*2*phisrc(idx))*[1 -sigma*1i 0]/2; % simplified here
u = rp - rs;
r = sqrt(u(1)^2+u(2)^2+u(3)^2); %norm(u);
u = u/r; % unit vector
ut = [u(2)*p(3)-u(3)*p(2),...
u(3)*p(1)-u(1)*p(3), ...
u(1)*p(2)-u(2)*p(1)]; % cross product: u cross p
Erad = Erad + ... % u cross p cross u, do not use the built-in func
c0*k0^2/4/pi*exp(1i*k0*r)/r*eta0*...
[ut(2)*u(3)-ut(3)*u(2);...
ut(3)*u(1)-ut(1)*u(3); ...
ut(1)*u(2)-ut(2)*u(1)];
end
Eobs(nobs, :) = Erad; % filter neglected here
end
matlabpool close
Eobs = Eobs/max(max(sum(abs(Eobs), 2))); % normailized
%% source, gaussian beam
E0 = 1;
w0 = 80e-6;
theta = 0; % may be titled
RotateX = [1, 0, 0; ...
0, cosd(theta), -sind(theta); ...
0, sind(theta), cosd(theta)];
Esrc = zeros(NPNTOBS, 3);
for nobs = 1:NPNTOBS
rp = RotateX*[pntobs(nobs, 1:2).'; 0];
z = rp(3);
r = sqrt(sum(abs(rp(1:2)).^2));
zR = pi*w0^2/lambda;
wz = w0*sqrt(1+z^2/zR^2);
Rz = z^2+zR^2;
zetaz = atan(z/zR);
gaussian = E0*w0/wz*exp(-r^2/wz^2-1i*k0*z-1i*k0*0*r^2/Rz/2+1i*zetaz);% ...
Esrc(nobs, :) = (polfilter*gaussian*[1; -1i; 0]).'/sqrt(2)/2;
end
Esrc = [Esrc(:, 2), Esrc(:, 3), Esrc(:, 1)];
Esrc = Esrc/max(max(sum(abs(Esrc), 2))); % normailized
toc
%% visualization
fringe = Eobs + Esrc; % I'll have a different formula in my code
normEsrc = reshape(sum(abs(Esrc).^2, 2), [nyp nxp]);
normEobs = reshape(sum(abs(Eobs).^2, 2), [nyp nxp]);
normFringe = reshape(sum(abs(fringe).^2, 2), [nyp nxp]);
close all;
xf0 = linspace(xboundl, xboundu, 500);
yf0 = linspace(yboundl, yboundu, 500);
[xfi, yfi] = meshgrid(xf0, yf0);
data = interp2(xf, yf, normFringe, xfi, yfi);
figure; surf(xfi, yfi, data,'edgecolor','none');
% tri = delaunay(xfi, yfi); trisurf(tri, xfi, yfi, data, 'edgecolor','none');
xlim([xboundl, xboundu])
ylim([yboundl, yboundu])
% colorbar
view(0,90)
colormap(hot)
axis equal
axis off
title('fringe thereo. ', ...
'fontsize', 18)
I didn't read your code because it is too long to do such a simple thing. I wrote mine and here is the result:
the code is
%spiral.m
function val = spiral(x,y)
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r;
x = r*cos(a);
y = r*sin(a);
val = exp(-x*x*y*y);
val = 1/(1+exp(-1000*(val)));
endfunction
%show.m
n=300;
l = 7;
A = zeros(n);
for i=1:n
for j=1:n
A(i,j) = spiral( 2*(i/n-0.5)*l,2*(j/n-0.5)*l);
end
end
imshow(A) %don't know if imshow is in matlab. I used octave.
the key for the sharpnes is line
val = 1/(1+exp(-1000*(val)));
It is logistic function. The number 1000 defines how sharp your image will be. So lower it for more blurry image or higher it for sharper.
I hope this answers your question ;)
Edit: It is real fun to play with. Here is another spiral:
function val = spiral(x,y)
s= 0.5;
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r*r*r;
x = r*cos(a);
y = r*sin(a);
val = 0;
if (abs(x)<s )
val = s-abs(x);
endif
if(abs(y)<s)
val =max(s-abs(y),val);
endif
%val = 1/(1+exp(-1*(val)));
endfunction
Edit2: Fun, fun, fun! Here the arms do not get thinner.
function val = spiral(x,y)
s= 0.1;
r = sqrt( x*x + y*y);
a = atan2(y,x)*2+r*r; % h
x = r*cos(a);
y = r*sin(a);
val = 0;
s = s*exp(r);
if (abs(x)<s )
val = s-abs(x);
endif
if(abs(y)<s)
val =max(s-abs(y),val);
endif
val = val/s;
val = 1/(1+exp(-10*(val)));
endfunction
Damn your question I really need to study for my exam, arghhh!
Edit3:
I vectorised the code and it runs much faster.
%spiral.m
function val = spiral(x,y)
s= 2;
r = sqrt( x.*x + y.*y);
a = atan2(y,x)*8+exp(r);
x = r.*cos(a);
y = r.*sin(a);
val = 0;
s = s.*exp(-0.1*r);
val = r;
val = (abs(x)<s ).*(s-abs(x));
val = val./s;
% val = 1./(1.+exp(-1*(val)));
endfunction
%show.m
n=1000;
l = 3;
A = zeros(n);
[X,Y] = meshgrid(-l:2*l/n:l);
A = spiral(X,Y);
imshow(A)
Sorry, can't post figures. But this might help. I wrote it for experiments with amplitude spatial modulators...
R=70; % radius of curvature of fresnel lens (in pixel units)
A=0; % oblique incidence by linear grating (1=oblique 0=collinear)
B=1; % expanding by fresnel lens (1=yes 0=no)
L=7; % topological charge
Lambda=30; % linear grating fringe spacing (in pixels)
aspect=1/2; % fraction of fringe period that is white/clear
xsize=1024; % resolution (xres x yres number data pts calculated)
ysize=768; %
% define the X and Y ranges (defined to skip zero)
xvec = linspace(-xsize/2, xsize/2, xsize); % list of x values
yvec = linspace(-ysize/2, ysize/2, ysize); % list of y values
% define the meshes - matrices linear in one dimension
[xmesh, ymesh] = meshgrid(xvec, yvec);
% calculate the individual phase components
vortexPh = atan2(ymesh,xmesh); % the vortex phase
linPh = -2*pi*ymesh; % a phase of linear grating
radialPh = (xmesh.^2+ymesh.^2); % a phase of defocus
% combine the phases with appropriate scales (phases are additive)
% the 'pi' at the end causes inversion of the pattern
Ph = L*vortexPh + A*linPh/Lambda + B*radialPh/R^2;
% transmittance function (the real part of exp(I*Ph))
T = cos(Ph);
% the binary version
binT = T > cos(pi*aspect);
% plot the pattern
% imagesc(binT)
imagesc(T)
colormap(gray)

Average filter in matlab

I'm trying to compute the average of every pixel with just the left and right neighbors but at the end of my processing I get only a white image, I can't find where my error. Here's my code
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);
Any ideas?
Change the last line of your code to imagesc(imageOut) and you'll see that the image is not in fact white.
Your code is fine; the reason the image appears white using the imshow() function is because after applying your local average the range of pixel intensities is considerably smaller and the default scaling used by imshow() is insufficient to bring out the contrast of the image.
Read about the difference b/t imshow() and imagesc() and you'll see the confusion.
Why not just create a 2nd matrix which is a clone of the first, shift it over and then averate the two matrices?
imIn = imread('Prueba.jpg');
nx = size(d,1);
ny = size(d,2);
% Create temporary matrices padded with nan
tmp1 = [nan(ny,2), d];
tmp2 = [d, nan(ny,2)];
imOut = tmp1;
imOut(:,:,2) = tmp2;
% use nanmean so the mean is just the value of the 1 column
imOut = nanmean(imOut,3);
out = imOut(2:end-1,:);
Try to use this
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);