Extracting image region within boundary - matlab

I have to do a project using 2D CT images and segment liver and tumor in it using Matlab(only). Initially i have to segment liver region alone. I use region growing for liver segmentation. It gets seed point as input.
The output is an image with a boundary for liver region. Now I need the region that is surrounded by the boundary alone.
My program has a main program and a regionGrowing.m function. As I'm a new user am not allowed to post images. If you do need images I will mail you. Kindly help me.
% mainreg.m
IR=imread('nfliver5.jpg');
figure, imshow(IR), hold all
poly = regionGrowing(IR,[],15,1200); % click somewhere inside the liver
plot(poly(:,1), poly(:,2), 'LineWidth', 2, 'Color', [1 1 1])
%regionGrowing.m
function [P, J] = regionGrowing(cIM, initPos, thresVal, maxDist, tfMean, tfFillHoles, tfSimplify)
% REGIONGROWING Region growing algorithm for 2D/3D grayscale images
%
% Syntax:
% P = regionGrowing();
% P = regionGrowing(cIM);
% P = regionGrowing(cIM, initPos)
% P = regionGrowing(..., thresVal, maxDist, tfMean, tfFillHoles, tfSimpl)
% [P, J] = regionGrowing(...);
%
% Inputs:
% cIM: 2D/3D grayscale matrix {current image}
% initPos: Coordinates for initial seed position {ginput position}
% thresVal: Absolute threshold level to be included {5% of max-min}
% maxDist: Maximum distance to the initial position in [px] {Inf}
% tfMean: Updates the initial value to the region mean (slow) {false}
% tfFillHoles: Fills enclosed holes in the binary mask {true}
% tfSimplify: Reduces the number of vertices {true, if dpsimplify exists}
%
% Outputs:
% P: VxN array (with V number of vertices, N number of dimensions)
% P is the enclosing polygon for all associated pixel/voxel
% J: Binary mask (with the same size as the input image) indicating
% 1 (true) for associated pixel/voxel and 0 (false) for outside
%
% Examples:
% % 2D Example
% load example
% figure, imshow(cIM, [0 1500]), hold all
% poly = regionGrowing(cIM, [], 300); % click somewhere inside the lungs
% plot(poly(:,1), poly(:,2), 'LineWidth', 2)
%
% % 3D Example
% load mri
% poly = regionGrowing(squeeze(D), [66,55,13], 60, Inf, [], true, false);
% plot3(poly(:,1), poly(:,2), poly(:,3), 'x', 'LineWidth', 2)
%
% Requirements:
% TheMathWorks Image Processing Toolbox for bwboundaries() and axes2pix()
% Optional: Line Simplification by Wolfgang Schwanghart to reduce the
% number of polygon vertices (see the MATLAB FileExchange)
%
% Remarks:
% The queue is not preallocated and the region mean computation is slow.
% I haven't implemented a preallocation nor a queue counter yet for the
% sake of clarity, however this would be of course more efficient.
%
% Author:
% Daniel Kellner, 2011, braggpeaks{}googlemail.com
% History: v1.00: 2011/08/14
% error checking on input arguments
if nargin > 7
error('Wrong number of input arguments!')
end
if ~exist('cIM', 'var')
himage = findobj('Type', 'image');
if isempty(himage) || length(himage) > 1
error('Please define one of the current images!')
end
cIM = get(himage, 'CData');
end
if ~exist('initPos', 'var') || isempty(initPos)
himage = findobj('Type', 'image');
if isempty(himage)
himage = imshow(cIM, []);
end
% graphical user input for the initial position
p = ginput(1);
% get the pixel position concerning to the current axes coordinates
initPos(1) = round(axes2pix(size(cIM, 2), get(himage, 'XData'), p(2)));
initPos(2) = round(axes2pix(size(cIM, 1), get(himage, 'YData'), p(1)));
end
if ~exist('thresVal', 'var') || isempty(thresVal)
thresVal = double((max(cIM(:)) - min(cIM(:)))) * 0.05;
end
if ~exist('maxDist', 'var') || isempty(maxDist)
maxDist = Inf;
end
if ~exist('tfMean', 'var') || isempty(tfMean)
tfMean = false;
end
if ~exist('tfFillHoles', 'var')
tfFillHoles = true;
end
if isequal(ndims(cIM), 2)
initPos(3) = 1;
elseif isequal(ndims(cIM),1) || ndims(cIM) > 3
error('There are only 2D images and 3D image sets allowed!')
end
[nRow, nCol, nSli] = size(cIM);
if initPos(1) < 1 || initPos(2) < 1 ||...
initPos(1) > nRow || initPos(2) > nCol
error('Initial position out of bounds, please try again!')
end
if thresVal < 0 || maxDist < 0
error('Threshold and maximum distance values must be positive!')
end
if ~isempty(which('dpsimplify.m'))
if ~exist('tfSimplify', 'var')
tfSimplify = true;
end
simplifyTolerance = 1;
else
tfSimplify = false;
end
% initial pixel value
regVal = double(cIM(initPos(1), initPos(2), initPos(3)));
% text output with initial parameters
disp(['RegionGrowing Opening: Initial position (' num2str(initPos(1))...
'|' num2str(initPos(2)) '|' num2str(initPos(3)) ') with '...
num2str(regVal) ' as initial pixel value!'])
% preallocate array
J = false(nRow, nCol, nSli);
% add the initial pixel to the queue
queue = [initPos(1), initPos(2), initPos(3)];
%%% START OF REGION GROWING ALGORITHM
while size(queue, 1)
% the first queue position determines the new values
xv = queue(1,1);
yv = queue(1,2);
zv = queue(1,3);
% .. and delete the first queue position
queue(1,:) = [];
% check the neighbors for the current position
for i = -1:1
for j = -1:1
for k = -1:1
if xv+i > 0 && xv+i <= nRow &&... % within the x-bounds?
yv+j > 0 && yv+j <= nCol &&... % within the y-bounds?
zv+k > 0 && zv+k <= nSli &&... % within the z-bounds?
any([i, j, k]) &&... % i/j/k of (0/0/0) is redundant!
~J(xv+i, yv+j, zv+k) &&... % pixelposition already set?
sqrt( (xv+i-initPos(1))^2 +...
(yv+j-initPos(2))^2 +...
(zv+k-initPos(3))^2 ) < maxDist &&... % within distance?
cIM(xv+i, yv+j, zv+k) <= (regVal + thresVal) &&...% within range
cIM(xv+i, yv+j, zv+k) >= (regVal - thresVal) % of the threshold?
% current pixel is true, if all properties are fullfilled
J(xv+i, yv+j, zv+k) = true;
% add the current pixel to the computation queue (recursive)
queue(end+1,:) = [xv+i, yv+j, zv+k];
if tfMean
regVal = mean(mean(cIM(J > 0))); % --> slow!
end
end
end
end
end
end
%%% END OF REGION GROWING ALGORITHM
% loop through each slice, fill holes and extract the polygon vertices
P = [];
for cSli = 1:nSli
if ~any(J(:,:,cSli))
continue
end
% use bwboundaries() to extract the enclosing polygon
if tfFillHoles
% fill the holes inside the mask
J(:,:,cSli) = imfill(J(:,:,cSli), 'holes');
B = bwboundaries(J(:,:,cSli), 8, 'noholes');
else
B = bwboundaries(J(:,:,cSli));
end
newVertices = [B{1}(:,2), B{1}(:,1)];
% simplify the polygon via Line Simplification
if tfSimplify
newVertices = dpsimplify(newVertices, simplifyTolerance);
end
% number of new vertices to be added
nNew = size(newVertices, 1);
% append the new vertices to the existing polygon matrix
if isequal(nSli, 1) % 2D
P(end+1:end+nNew, :) = newVertices;
else % 3D
P(end+1:end+nNew, :) = [newVertices, repmat(cSli, nNew, 1)];
end
end
% text output with final number of vertices
disp(['RegionGrowing Ending: Found ' num2str(length(find(J)))...
' pixels within the threshold range (' num2str(size(P, 1))...
' polygon vertices)!'])

If I understand you correctly, you have a binary image of the boundary of the kidney and now need to set the inside of the boundary to 1s. To do this, you can use the imfill() function with the 'holes' setting on.
BW2 = imfill(BW,'holes');
EDIT: Looking at the code, it seems that it does what you want already.
% Outputs:
% J: Binary mask (with the same size as the input image) indicating
% 1 (true) for associated pixel/voxel and 0 (false) for outside
so you just need to get the second output as well:
IR=imread('nfliver5.jpg');
figure, imshow(IR), hold all
[poly im] = regionGrowing(IR,[],15,1200); % click somewhere inside the liver
imshow(im,[])
Now im is a binary image with your segmented region.
EDIT2:
Once you have the binary image im, you can simply use element-wise multiplication to remove all parts of the orignal image outside the segmented region.
SEG = IR.*im;
imshow(SEG,[])
EDIT3:
For 3D images, you need to specify the coordinates manually, and not by using the mouse. This is because the mouse only gives us 2 coordinates (x and y) and you need 3 (x,y and z). So just find the coordinates you need by looking at the image, and then choosing an appropriate z coordinate.
%Example coordinates,
coordinates = [100 100 5]
poly = regionGrowing(squeeze(IR), coordinates, 60, Inf, [], true, false);

Related

Looping my algorithm to plot for a different parameter value on the same graph(MATLAB)

I've implemented an algorithm for my physics project which does exactly what I want. The problem that I'm stuck which is not the Physics content itself hence I think it might be somewhat trivial to explain what my code does. I'm mainly stuck with the way MATLAB's plotting works if I was to loop over the same algorithm to produce similar graphs with a slight change of a value of my parameter. Here's my code below:
clear; clc; close all;
% Parameters:
z_nn = 4; % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4; % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40; % Number of sites along x-axis.
Ly = 40; % Number of sites along y-axis.
sigma = 1; % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = -2.53; % Chemical potential mu/epsilon.
mu_2 = -2.67; % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 11, 11);%J points for the line graph plot
potential = zeros(Ly);
attract = 1.6; %wall attraction constant
k = 1; %wall depth
rho_0 = 0.4; % Initial density.
tol = 1e-12; % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha = 0.01; % Mixing parameter.
conv = 1; cnt = 1; % Convergence value and counter.
rho = rho_0*ones(Ly); % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly); % Initialise rho_new to zeros.
% Solve equations iteratively:
while conv>=tol && cnt<count
cnt = cnt + 1; % Increment counter.
% Loop over all lattice sites:
for j=1:Ly
%Defining the Lennard-Jones potential
if j<k
potential(j) = 1000000000;
else
potential(j) = -attract*(j-k)^(-3);
end
% Handle the periodic boundaries for x and y:
%left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
%right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
if j<k+1 %depth of wall
rho_rhs(j) = 0;
rho(j) = 0;
elseif j<(20+k)
rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + mu) - potential(j)));
else
rho_rhs(j) = rho_rhs(j-1);
end
end
conv = sum(sum((rho - rho_rhs).^2)); % Convergence value is the sum of the differences between new and current solution.
rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.
end
% disp(['conv = ' num2str(conv_2) ' cnt = ' num2str(cnt)]); % Display final answer.
% figure(2);
% pcolor(rho_2);
figure(1);
plot(J, rho(1:11));
hold on;
% plot(J, rho_2(1,1:11));
hold off;
disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
figure(3);
pcolor(rho);
Running this code should give you a graph like this
Now I want to produce a similar graph but with one of the variable's value changed and plotted on the same graph. My approach that I've tried is below:
clear; clc; close all;
% Parameters:
z_nn = 4; % Number of nearest-neighbour in lattice (square = 4).
z_nnn = 4; % Number of next-nearest-neighbours in lattice (square = 4).
Lx = 40; % Number of sites along x-axis.
Ly = 40; % Number of sites along y-axis.
sigma = 1; % Size of a site (defines our units of length).
beta = 1.2; % Inverse temperature beta*epsilon.
mu = [-2.53,-2.67]; % Chemical potential mu/epsilon.
mu_2 = -2.67; % Chemical potential mu/epsilon for 2nd line.
J = linspace(1, 10, 10);%J points for the line graph plot
potential = zeros(Ly, length(mu));
gamma = zeros(Ly, length(mu));
attract = 1.6; %wall attraction constant
k = 1; %wall depth
rho_0 = 0.4; % Initial density.
tol = 1e-12; % Convergence tolerance.
count = 30000; % Upper limit for iterations.
alpha = 0.01; % Mixing parameter.
conv = 1; cnt = 1; % Convergence value and counter.
rho = rho_0*[Ly,length(mu)]; % Initialise rho to the starting guess(i-th rho_old) in Eq(47)
rho_rhs = zeros(Ly,length(mu)); % Initialise rho_new to zeros.
figure(3);
hold on;
% Solve equations iteratively:
while conv>=tol && cnt<count
cnt = cnt + 1; % Increment counter.
% Loop over all lattice sites:
for j=1:Ly
for i=1:length(mu)
y = 1:Ly;
MU = mu(i).*ones(Ly)
%Defining the Lennard-Jones potential
if j<k
potential(j) = 1000000000;
else
potential(j) = -attract*(j-k).^(-3);
end
% Handle the periodic boundaries for x and y:
%left = mod((i-1)-1,Lx) + 1; % i-1, maps 0 to Lx.
%right = mod((i+1)-1,Lx) + 1; % i+1, maps Lx+1 to 1.
if j<k+1 %depth of wall
rho_rhs(j) = 0;
rho(j) = 0;
elseif j<(20+k)
rho_rhs(j) = (1 - rho(j))*exp((beta*((3/2)*rho(j-1) + (3/2)*rho(j+1) + 2*rho(j) + MU - potential(j)));
else
rho_rhs(j) = rho_rhs(j-1);
end
end
end
conv = sum(sum((rho - rho_rhs).^2)); % Convergence value is the sum of the differences between new and current solution.
rho = alpha*rho_rhs + (1 - alpha)*rho; % Mix the new and current solutions for next iteration.
disp(['conv = ' num2str(conv) ' cnt = ' num2str(cnt)]); % Display final answer.
figure(1);
pcolor(rho);
plot(J, rho(1:10));
end
hold off;
The only variable that I'm changing here is mu. I would like to loop my first code so that I can enter an arbitrary amount of different values of mu and plot them on the same graph. Naturally I had to change all of the lists dimension from (1 to size of Ly) to (#of mu(s) to size of Ly), such that when the first code is being looped, the i-th mu value in that loop is being turned into lists with dimension as long as Ly. So I thought I would do the plotting within the loop and use "hold on" encapsulating the whole loop so that every plot that was generated in each loop won't be erased. But I've been spending hours on trying to figure out the semantics of MATLAB but ultimately I can't figure out what to do. So hopefully I can get some help on this!
hold on only applies to the active figure, it is not a generic property shared among all figures. What is does is changing the value of the current figure NextPlot property, which governs the behavior when adding plots to a figure.
hold on is equivalent to set(gcf,'NextPlot','add');
hold off is equivalent to set(gcf,'NextPlot','replace');
In your code you have:
figure(3); % Makes figure 3 the active figure
hold on; % Sets figure 3 'NextPlot' property to 'add'
% Do some things %
while conv>=tol && cnt<count
% Do many things %
figure(1); % Makes figure 1 the active figure; 'hold on' was not applied to that figure
plot(J, rho(1:10)); % plots rho while erasing the previous plot
end
You should try to add another hold on statement after figure(1)
figure(1);
hold on
plot(J, rho(1:10));

Segmenting cursive character (Arabic OCR)

I want to segment an Arabic word into single characters. Based on the histogram/profile, I assume that I can do the segmentation process by cut/segment the characters based on it's baseline (it have similar pixel values).
But, unfortunately, I still stuck to build the appropriate code, to make it works.
% Original Code by Soumyadeep Sinha
% Saving each single segmented character as one file
function [segm] = trysegment (a)
myFolder = 'D:\1. Thesis FINISH!!!\Data set\trial';
level = graythresh (a);
bw = im2bw (a, level);
b = imcomplement (bw);
i= padarray(b,[0 10]);
verticalProjection = sum(i, 1);
set(gcf, 'Name', 'Trying Segmentation for Cursive', 'NumberTitle', 'Off')
subplot(2, 2, 1);imshow(i);
subplot(2,2,3);
plot(verticalProjection, 'b-'); %histogram show by this code
% hist(reshape(input,[],3),1:max(input(:)));
grid on;
% % t = verticalProjection;
% % t(t==0) = inf;
% % mayukh = min(t)
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
% Extract each region
y=1;
for k = 1 : length(startingColumns)
% Get sub image of just one character...
subImage = i(:, startingColumns(k):endingColumns(k));
% se = strel('rectangle',[2 4]);
% dil = imdilate(subImage, se);
th = bwmorph(subImage,'thin',Inf);
n = imresize (th, [64 NaN], 'bilinear');
figure, imshow (n);
[L,num] = bwlabeln(n);
for z= 1 : num
bw= ismember(L, z);
% Construct filename for this particular image.
baseFileName = sprintf('char %d.png', y);
y=y+1;
% Prepend the folder to make the full file name.
fullFileName = fullfile(myFolder, baseFileName);
% Do the write to disk.
imwrite(bw, fullFileName);
% subplot(2,2,4);
% pause(2);
% imshow(bw);
end
% y=y+1;
end;
segm = (n);
Word image is as follow:
Why the code isn't work?
do you have any recommendation of another codes?
or suggested algorithm to make it works, to do a good segmentation on cursive character?
Thanks before.
Replace this code part from the posted code
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
with the new code part
threshold=max(verticalProjection)/3;
thresholdedProjection=verticalProjection > threshold;
count=0;
startingColumnsIndex=0;
for i=1:length(thresholdedProjection)
if thresholdedProjection(i)
if(count>0)
startingColumnsIndex=startingColumnsIndex+1;
startingColumns(startingColumnsIndex)= i-floor(count/2);
count=0;
end
else
count=count+1;
end
end
endingColumns=[startingColumns(2:end)-1 i-floor(count/2)];
No changes needed for the rest of the code.

connected component analysis in MATLAB

I want to apply connected component analysis on a grey scale image with considering pixels whose grey level is more than a threshold. then, I want to remove those connected components whose length is less than a threshold. please help me? I wrote following code in MATLAB, is it efficient?
thank you in advance.
%im = input image;
% alpha1 = 0.0001;
% alpha2 = 0.0001;
% [row col] = size(im);
%
%
% thr1 = mean(mean(im))-alpha1*std(std(im));
% BW = zeros(size(im));
%
% for rr = 1:row
% for cc = 1:col
% if im(rr,cc)>thr2
% BW(rr,cc) = 1;
% else
% BW(rr,cc) = 0;
% end
% end
% end
%
% CC = bwconncomp(BW);
% area_in_pixels = cellfun(#length,CC.PixelIdxList);
% thr2 = mean(area_in_pixels)-alpha2*std(area_in_pixels);
% idx = find(area_in_pixels <= thr3);
% for kk = 1:length(idx)
% aaa = idx(kk);
% BW(CC.PixelIdxList{aaa})=0;
% end
You can try regionprops instead to extract all objects in your image. With the code below you get the positions of all objects smaller than a threshold which you can manipulate or do what you need to do afterwards...
Comparably you can go through the different objects and extract the grey level and if it is below a threshold manipulate them.
% Threshold for the size in pixels that you want
threshold = 100;
% read your image
rawimage = imread('yourimage.jpg');
% create a 2D field by summing
im = sum(rawimage,3);
% label all objects that have 8 neighbours
IMAGE_labeled = bwlabel(im,8);
% get the properties of all elements
shapedata=regionprops (IMAGE_labeled,'all');
% get those elements that are smaller in size (area) than the threshold
index = find(cell2mat({shapedata(:).Area})<=threshold);
% make a contourplot of im
figure
contourf(im)
hold on
% creation of colormap with the size of all identified objects below the thres
mycolormap = jet(size(index,2));
% loop over all small objects, extraction of their position in the original file, plotting circles with different colors at the position of each small object
imap = 1;
mean_of_red = zeros(length(index),1);
for i = index
plot (shapedata(i).PixelList(:,1),shapedata(i).PixelList(:,2),'o','MarkerFaceColor',mycolormap(imap,:))
mean_of_red(i) = mean(mean(im(shapedata(i).PixelList(:,1),shapedata(i).PixelList(:,1),1)));
imap=imap+1;
end

MATLAB adding slider on a figure

I have a 576x576x150 matrix. Each 576x576 set represents an image. When I want to plot one frame I do it by using the plot command:
figure(1);
imshow(B(:,:,45),[]) % plots frame 45
title('45') % tells frame number
However I would like to add a slider to the plot, so I can move from 1-150 frame within the figure.I've seen examples of people using uicontrol but I don't know how to code it. In addition to that, I would like to have a title on top of the figure telling me the frame number.
Here is how I do it. I like to keep a single function that does the plotting so you don't recycle commands elsewhere. You could replace the first two lines by function test(B) to use you own B matrix. This code is pretty easy to extend. You will also want to play with the layout to suit your purpose.
function test
B=rand(576,576,150);
fig=figure(100);
set(fig,'Name','Image','Toolbar','figure',...
'NumberTitle','off')
% Create an axes to plot in
axes('Position',[.15 .05 .7 .9]);
% sliders for epsilon and lambda
slider1_handle=uicontrol(fig,'Style','slider','Max',150,'Min',1,...
'Value',2,'SliderStep',[1/(150-1) 10/(150-1)],...
'Units','normalized','Position',[.02 .02 .14 .05]);
uicontrol(fig,'Style','text','Units','normalized','Position',[.02 .07 .14 .04],...
'String','Choose frame');
% Set up callbacks
vars=struct('slider1_handle',slider1_handle,'B',B);
set(slider1_handle,'Callback',{#slider1_callback,vars});
plotterfcn(vars)
% End of main file
% Callback subfunctions to support UI actions
function slider1_callback(~,~,vars)
% Run slider1 which controls value of epsilon
plotterfcn(vars)
function plotterfcn(vars)
% Plots the image
imshow(vars.B(:,:,get(vars.slider1_handle,'Value')));
title(num2str(get(vars.slider1_handle,'Value')));
The idea is to use uicontrol() to enable sliding/scrolling.
The following code is for scrolling (created by Evan Brooks, you can modify it to sliding):
function scrollfigdemo
% create new figure window
f = figure;
set(f,'doublebuffer', 'on', 'resize', 'off')
% set columns of plots
cols = 2;
% create 5 data sets to plot
x=0:1e-2:2*pi;
y{1}=sin(x);
y{2}=cos(x);
y{3}=tan(x);
y{4}=x.^2;
y{5}=x.^3;
% determine required rows of plots
rows = ceil(length(y)/cols);
% increase figure width for additional axes
fpos = get(gcf, 'position');
scrnsz = get(0, 'screensize');
fwidth = min([fpos(3)*cols, scrnsz(3)-20]);
fheight = fwidth/cols*.75; % maintain aspect ratio
set(gcf, 'position', [10 fpos(2) fwidth fheight])
% setup all axes
buf = .15/cols; % buffer between axes & between left edge of figure and axes
awidth = (1-buf*cols-.08/cols)/cols; % width of all axes
aidx = 1;
rowidx = 0;
while aidx <= length(y)
for i = 0:cols-1
if aidx+i <= length(y)
start = buf + buf*i + awidth*i;
apos{aidx+i} = [start 1-rowidx-.92 awidth .85];
a{aidx+i} = axes('position', apos{aidx+i});
end
end
rowidx = rowidx + 1; % increment row
aidx = aidx + cols; % increment index of axes
end
% make plots
axes(a{1}), plot(x,y{1}), title('sine'), xlabel('x'), ylabel('sin(x)')
axes(a{2}), plot(x,y{2}), title('cosine'), xlabel('x'), ylabel('cos(x)')
axes(a{3}), plot(x,y{3}), title('tangent'), xlabel('x'), ylabel('tan(x)')
axes(a{4}), plot(x,y{4}), title('x^2'), xlabel('x'), ylabel('x^2')
axes(a{5}), plot(x,y{5}), title('x^3'), xlabel('x'), ylabel('x^3')
% determine the position of the scrollbar & its limits
swidth = max([.03/cols, 16/scrnsz(3)]);
ypos = [1-swidth 0 swidth 1];
ymax = 0;
ymin = -1*(rows-1);
% build the callback that will be executed on scrolling
clbk = '';
for i = 1:length(a)
line = ['set(',num2str(a{i},'%.13f'),',''position'',[', ...
num2str(apos{i}(1)),' ',num2str(apos{i}(2)),'-get(gcbo,''value'') ', num2str(apos{i}(3)), ...
' ', num2str(apos{i}(4)),'])'];
if i ~= length(a)
line = [line,','];
end
clbk = [clbk,line];
end
% create the slider
uicontrol('style','slider', ...
'units','normalized','position',ypos, ...
'callback',clbk,'min',ymin,'max',ymax,'value',0);

Regarding visualization of movement of the data points in training of the Self-Organizing Map (SOM) using Simulink

I have implemented the Self-Organizing Map(SOM) algorithm in MATLAB. Suppose each of the data points are represented in 2-dimensional space. The problem is that I want to visualize the movement of each of the data points in the training phase i.e. I want to see how the points are moving and eventually forming clusters as the algorithm is in progress say at every fix duration. I believe that this can be done through Simulation in MATLAB,but I don't know how to incorporate my MATLAB code for visualization?
I developed a code example to visualize clustering data with multiple dimensions using all possible data projection in 2-D. It may not be the best idea for visualization (there are techniques developed for this, as SOM itself may be used for this need), specially for a higher dimension numbers, but when the number of possible projections (n-1)! is not that high it is a quite good visualizer.
Cluster Algorithm 
Since I needed access to the code so that I could save the cluster means and cluster labels for each iteration, I used a fast kmeans algorithm available at FEX by Mo Chen, but I had to adapt it so I could have this access. The adapted code is the following:
function [label,m] = litekmeans(X, k)
% Perform k-means clustering.
% X: d x n data matrix
% k: number of seeds
% Written by Michael Chen (sth4nth#gmail.com).
n = size(X,2);
last = 0;
iter = 1;
label{iter} = ceil(k*rand(1,n)); % random initialization
checkLabel = label{iter};
m = {};
while any(checkLabel ~= last)
[u,~,checkLabel] = unique(checkLabel); % remove empty clusters
k = length(u);
E = sparse(1:n,checkLabel,1,n,k,n); % transform label into indicator matrix
curM = X*(E*spdiags(1./sum(E,1)',0,k,k)); % compute m of each cluster
m{iter} = curM;
last = checkLabel';
[~,checkLabel] = max(bsxfun(#minus,curM'*X,dot(curM,curM,1)'/2),[],1); % assign samples to the nearest centers
iter = iter + 1;
label{iter} = checkLabel;
end
% Get last clusters centers
m{iter} = curM;
% If to remove empty clusters:
%for k=1:iter
% [~,~,label{k}] = unique(label{k});
%end
Gif Creation
I also used #Amro's Matlab video tutorial for the gif creation.
Distinguishable Colors
I used this great FEX by Tim Holy for making the cluster colors easier to distinguish.
Resulting code
My resulting code is as follows. I had some issues because the number of clusters would change for each iteration which would cause scatter plot update to delete all cluster centers without giving any errors. Since I didn't noticed that, I was trying to workaround the scatter function with any obscure method that I could find the web (btw, I found a really nice scatter plot alternative here), but fortunately I got what was happening going back to this today. Here is the code I did for it, you may feel free to use it, adapt it, but please keep my reference if you use it.
function varargout=kmeans_test(data,nClusters,plotOpts,dimLabels,...
bigXDim,bigYDim,gifName)
%
% [label,m,figH,handles]=kmeans_test(data,nClusters,plotOpts,...
% dimLabels,bigXDim,bigYDim,gifName)
% Demonstrate kmeans algorithm iterative progress. Inputs are:
%
% -> data (rand(5,100)): the data to use.
%
% -> nClusters (7): number of clusters to use.
%
% -> plotOpts: struct holding the following fields:
%
% o leftBase: the percentage distance from the left
%
% o rightBase: the percentage distance from the right
%
% o bottomBase: the percentage distance from the bottom
%
% o topBase: the percentage distance from the top
%
% o FontSize: FontSize for axes labels.
%
% o widthUsableArea: Total width occupied by axes
%
% o heigthUsableArea: Total heigth occupied by axes
%
% -> bigXDim (1): the big subplot x dimension
%
% -> bigYDim (2): the big subplot y dimension
%
% -> dimLabels: If you want to specify dimensions labels
%
% -> gifName: gif file name to save
%
% Outputs are:
%
% -> label: Sample cluster center number for each iteration
%
% -> m: cluster center mean for each iteration
%
% -> figH: figure handle
%
% -> handles: axes handles
%
%
% - Creation Date: Fri, 13 Sep 2013
% - Last Modified: Mon, 16 Sep 2013
% - Author(s):
% - W.S.Freund <wsfreund_at_gmail_dot_com>
%
% TODO List (?):
%
% - Use input parser
% - Adapt it to be able to cluster any algorithm function.
% - Use arrows indicating cluster centers movement before moving them.
% - Drag and drop small axes to big axes.
%
% Pre-start
if nargin < 7
gifName = 'kmeansClusterization.gif';
if nargin < 6
bigYDim = 2;
if nargin < 5
bigXDim = 1;
if nargin < 4
nDim = size(data,1);
maxDigits = numel(num2str(nDim));
dimLabels = mat2cell(sprintf(['Dim %0' num2str(maxDigits) 'd'],...
1:nDim),1,zeros(1,nDim)+4+maxDigits);
if nargin < 3
plotOpts = struct('leftBase',.05,'rightBase',.02,...
'bottomBase',.05,'topBase',.02,'FontSize',10,...
'widthUsableArea',.87,'heigthUsableArea',.87);
if nargin < 2
nClusters = 7;
if nargin < 1
center1 = [1; 0; 0; 0; 0];
center2 = [0; 1; 0; 0; 0];
center3 = [0; 0; 1; 0; 0];
center4 = [0; 0; 0; 1; 0];
center5 = [0; 0; 0; 0; 1];
center6 = [0; 0; 0; 0; 1.5];
center7 = [0; 0; 0; 1.5; 1];
data = [...
bsxfun(#plus,center1,.5*rand(5,20)) ...
bsxfun(#plus,center2,.5*rand(5,20)) ...
bsxfun(#plus,center3,.5*rand(5,20)) ...
bsxfun(#plus,center4,.5*rand(5,20)) ...
bsxfun(#plus,center5,.5*rand(5,20)) ...
bsxfun(#plus,center6,.2*rand(5,20)) ...
bsxfun(#plus,center7,.2*rand(5,20)) ...
];
end
end
end
end
end
end
end
% NOTE of advice: It seems that Matlab does not test while on
% refreshdata if the dimension of the inputs are equivalent for the
% XData, YData and CData while using scatter. Because of this I wasted
% a lot of time trying to debug what was the problem, trying many
% workaround since my cluster centers would disappear for no reason.
% Draw axes:
nDim = size(data,1);
figH = figure;
set(figH,'Units', 'normalized', 'Position',...
[0, 0, 1, 1],'Color','w','Name',...
'k-means example','NumberTitle','Off',...
'MenuBar','none','Toolbar','figure',...
'Renderer','zbuffer');
% Create dintinguishable colors matrix:
colorMatrix = distinguishable_colors(nClusters);
% Create axes, deploy them on handles matrix more or less how they
% will be positioned:
[handles,horSpace,vertSpace] = ...
createAxesGrid(5,5,plotOpts,dimLabels);
% Add main axes
bigSubSize = ceil(nDim/2);
bigSubVec(bigSubSize^2) = 0;
for k = 0:nDim-bigSubSize
bigSubVec(k*bigSubSize+1:(k+1)*bigSubSize) = ...
... %(nDim-bigSubSize+k)*nDim+1:(nDim-bigSubSize+k)*nDim+(nDim-bigSubSize+1);
bigSubSize+nDim*k:nDim*(k+1);
end
handles(bigSubSize,bigSubSize) = subplot(nDim,nDim,bigSubVec,...
'FontSize',plotOpts.FontSize,'box','on');
bigSubplotH = handles(bigSubSize,bigSubSize);
horSpace(bigSubSize,bigSubSize) = bigSubSize;
vertSpace(bigSubSize,bigSubSize) = bigSubSize;
set(bigSubplotH,'NextPlot','add',...
'FontSize',plotOpts.FontSize,'box','on',...
'XAxisLocation','top','YAxisLocation','right');
% Squeeze axes through space to optimize space usage and improve
% visualization capability:
[leftPos,botPos,subplotWidth,subplotHeight]=setCustomPlotArea(...
handles,plotOpts,horSpace,vertSpace);
pColorAxes = axes('Position',[leftPos(end) botPos(end) ...
subplotWidth subplotHeight],'Parent',figH);
pcolor([1:nClusters+1;1:nClusters+1])
% image(reshape(colorMatrix,[1 size(colorMatrix)])); % Used image to
% check if the upcoming buggy behaviour would be fixed. I was not
% lucky, though...
colormap(pColorAxes,colorMatrix);
% Change XTick positions to its center:
set(pColorAxes,'XTick',.5:1:nClusters+.5);
set(pColorAxes,'YTick',[]);
% Change its label to cluster number:
set(pColorAxes,'XTickLabel',[nClusters 1:nClusters-1]); % FIXME At
% least on my matlab I have to use this buggy way to set XTickLabel.
% Am I doing something wrong? Since I dunno why this is caused, I just
% change the code so that it looks the way it should look, but this is
% quite strange...
xlabel(pColorAxes,'Clusters Colors','FontSize',plotOpts.FontSize);
% Now iterate throw data and get cluster information:
[label,m]=litekmeans(data,nClusters);
nIters = numel(m)-1;
scatterColors = colorMatrix(label{1},:);
annH = annotation('textbox',[leftPos(1),botPos(1) subplotWidth ...
subplotHeight],'String',sprintf('Start Conditions'),'EdgeColor',...
'none','FontSize',18);
% Creates dimData_%d variables for first iteration:
for curDim=1:nDim
curDimVarName = genvarname(sprintf('dimData_%d',curDim));
eval([curDimVarName,'= m{1}(curDim,:);']);
end
% clusterColors will hold the colors for the total number of clusters
% on each iteration:
clusterColors = colorMatrix;
% Draw cluster information for first iteration:
for curColumn=1:nDim
for curLine=curColumn+1:nDim
% Big subplot data:
if curColumn == bigXDim && curLine == bigYDim
curAxes = handles(bigSubSize,bigSubSize);
curScatter = scatter(curAxes,data(curColumn,:),...
data(curLine,:),16,'filled');
set(curScatter,'CDataSource','scatterColors');
% Draw cluster centers
curColumnVarName = genvarname(sprintf('dimData_%d',curColumn));
curLineVarName = genvarname(sprintf('dimData_%d',curLine));
eval(['curScatter=scatter(curAxes,' curColumnVarName ',' ...
curLineVarName ',100,colorMatrix,''^'',''filled'');']);
set(curScatter,'XDataSource',curColumnVarName,'YDataSource',...
curLineVarName,'CDataSource','clusterColors')
end
% Small subplots data:
curAxes = handles(curLine,curColumn);
% Draw data:
curScatter = scatter(curAxes,data(curColumn,:),...
data(curLine,:),16,'filled');
set(curScatter,'CDataSource','scatterColors');
% Draw cluster centers
curColumnVarName = genvarname(sprintf('dimData_%d',curColumn));
curLineVarName = genvarname(sprintf('dimData_%d',curLine));
eval(['curScatter=scatter(curAxes,' curColumnVarName ',' ...
curLineVarName ',100,colorMatrix,''^'',''filled'');']);
set(curScatter,'XDataSource',curColumnVarName,'YDataSource',...
curLineVarName,'CDataSource','clusterColors');
if curLine==nDim
xlabel(curAxes,dimLabels{curColumn});
set(curAxes,'XTick',xlim(curAxes));
end
if curColumn==1
ylabel(curAxes,dimLabels{curLine});
set(curAxes,'YTick',ylim(curAxes));
end
end
end
refreshdata(figH,'caller');
% Preallocate gif frame. From Amro's tutorial here:
% https://stackoverflow.com/a/11054155/1162884
f = getframe(figH);
[f,map] = rgb2ind(f.cdata, 256, 'nodither');
mov = repmat(f, [1 1 1 nIters+4]);
% Add one frame at start conditions:
curFrame = 1;
% Add three frames without movement at start conditions
f = getframe(figH);
mov(:,:,1,curFrame) = rgb2ind(f.cdata, map, 'nodither');
for curIter = 1:nIters
curFrame = curFrame+1;
% Change label text
set(annH,'String',sprintf('Iteration %d',curIter));
% Update cluster point colors
scatterColors = colorMatrix(label{curIter+1},:);
% Update cluster centers:
for curDim=1:nDim
curDimVarName = genvarname(sprintf('dimData_%d',curDim));
eval([curDimVarName,'= m{curIter+1}(curDim,:);']);
end
% Update cluster colors:
nClusterIter = size(m{curIter+1},2);
clusterColors = colorMatrix(1:nClusterIter,:);
% Update graphics:
refreshdata(figH,'caller');
% Update cluster colors:
if nClusterIter~=size(m{curIter},2) % If number of cluster
% of current iteration differs from previous iteration (or start
% conditions in case we are at first iteration) we redraw colors:
pcolor([1:nClusterIter+1;1:nClusterIter+1])
% image(reshape(colorMatrix,[1 size(colorMatrix)])); % Used image to
% check if the upcomming buggy behaviour would be fixed. I was not
% lucky, though...
colormap(pColorAxes,clusterColors);
% Change XTick positions to its center:
set(pColorAxes,'XTick',.5:1:nClusterIter+.5);
set(pColorAxes,'YTick',[]);
% Change its label to cluster number:
set(pColorAxes,'XTickLabel',[nClusterIter 1:nClusterIter-1]);
xlabel(pColorAxes,'Clusters Colors','FontSize',plotOpts.FontSize);
end
f = getframe(figH);
mov(:,:,1,curFrame) = rgb2ind(f.cdata, map, 'nodither');
end
set(annH,'String','Convergence Conditions');
for curFrame = nIters+1:nIters+3
% Add three frames without movement at start conditions
f = getframe(figH);
mov(:,:,1,curFrame) = rgb2ind(f.cdata, map, 'nodither');
end
imwrite(mov, map, gifName, 'DelayTime',.5, 'LoopCount',inf)
varargout = cell(1,nargout);
if nargout > 0
varargout{1} = label;
if nargout > 1
varargout{2} = m;
if nargout > 2
varargout{3} = figH;
if nargout > 3
varargout{4} = handles;
end
end
end
end
end
function [leftPos,botPos,subplotWidth,subplotHeight] = ...
setCustomPlotArea(handles,plotOpts,horSpace,vertSpace)
%
% -> handles: axes handles
%
% -> plotOpts: struct holding the following fields:
%
% o leftBase: the percentage distance from the left
%
% o rightBase: the percentage distance from the right
%
% o bottomBase: the percentage distance from the bottom
%
% o topBase: the percentage distance from the top
%
% o widthUsableArea: Total width occupied by axes
%
% o heigthUsableArea: Total heigth occupied by axes
%
% -> horSpace: the axes units size (integers only) that current axes
% should occupy in the horizontal (considering that other occupied
% axes handles are empty)
%
% -> vertSpace: the axes units size (integers only) that current axes
% should occupy in the vertical (considering that other occupied
% axes handles are empty)
%
nHorSubPlot = size(handles,1);
nVertSubPlot = size(handles,2);
if nargin < 4
horSpace(nHorSubPlot,nVertSubPlot) = 0;
horSpace = horSpace+1;
if nargin < 3
vertSpace(nHorSubPlot,nVertSubPlot) = 0;
vertSpace = vertSpace+1;
end
end
subplotWidth = plotOpts.widthUsableArea/nHorSubPlot;
subplotHeight = plotOpts.heigthUsableArea/nVertSubPlot;
totalWidth = (1-plotOpts.rightBase) - plotOpts.leftBase;
totalHeight = (1-plotOpts.topBase) - plotOpts.bottomBase;
gapHeigthSpace = (totalHeight - ...
plotOpts.heigthUsableArea)/(nVertSubPlot);
gapWidthSpace = (totalWidth - ...
plotOpts.widthUsableArea)/(nHorSubPlot);
botPos(nVertSubPlot) = plotOpts.bottomBase + gapWidthSpace/2;
leftPos(1) = plotOpts.leftBase + gapHeigthSpace/2;
botPos(nVertSubPlot-1:-1:1) = botPos(nVertSubPlot) + (subplotHeight +...
gapHeigthSpace)*(1:nVertSubPlot-1);
leftPos(2:nHorSubPlot) = leftPos(1) + (subplotWidth +...
gapWidthSpace)*(1:nHorSubPlot-1);
for curLine=1:nHorSubPlot
for curColumn=1:nVertSubPlot
if handles(curLine,curColumn)
set(handles(curLine,curColumn),'Position',[leftPos(curColumn)...
botPos(curLine) horSpace(curLine,curColumn)*subplotWidth ...
vertSpace(curLine,curColumn)*subplotHeight]);
end
end
end
end
function [handles,horSpace,vertSpace] = ...
createAxesGrid(nLines,nColumns,plotOpts,dimLabels)
handles = zeros(nLines,nColumns);
% Those hold the axes size units:
horSpace(nLines,nColumns) = 0;
vertSpace(nLines,nColumns) = 0;
for curColumn=1:nColumns
for curLine=curColumn+1:nLines
handles(curLine,curColumn) = subplot(nLines,...
nColumns,curColumn+(curLine-1)*nColumns);
horSpace(curLine,curColumn) = 1;
vertSpace(curLine,curColumn) = 1;
curAxes = handles(curLine,curColumn);
if feature('UseHG2')
colormap(handle(curAxes),colorMatrix);
end
set(curAxes,'NextPlot','add',...
'FontSize',plotOpts.FontSize,'box','on');
if curLine==nLines
xlabel(curAxes,dimLabels{curColumn});
else
set(curAxes,'XTick',[]);
end
if curColumn==1
ylabel(curAxes,dimLabels{curLine});
else
set(curAxes,'YTick',[]);
end
end
end
end
Example
Here is an example using 5 dimensions, using the code:
center1 = [1; 0; 0; 0; 0];
center2 = [0; 1; 0; 0; 0];
center3 = [0; 0; 1; 0; 0];
center4 = [0; 0; 0; 1; 0];
center5 = [0; 0; 0; 0; 1];
center6 = [0; 0; 0; 0; 1.5];
center7 = [0; 0; 0; 1.5; 1];
data = [...
bsxfun(#plus,center1,.5*rand(5,20)) ...
bsxfun(#plus,center2,.5*rand(5,20)) ...
bsxfun(#plus,center3,.5*rand(5,20)) ...
bsxfun(#plus,center4,.5*rand(5,20)) ...
bsxfun(#plus,center5,.5*rand(5,20)) ...
bsxfun(#plus,center6,.2*rand(5,20)) ...
bsxfun(#plus,center7,.2*rand(5,20)) ...
];
[label,m,figH,handles]=kmeans_test(data,20);