Segmenting cursive character (Arabic OCR) - matlab

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.

Related

Image Analysis of Flames trying to Detect Edge for Curve Fit not always working MatLab

I am trying to figure out how to make a program in Matlab to detect edges of flames so I can compare their flame shape. I have been able to get this program to work half of the time. The program reads the files, coverts it to black and white, and then I have been having issues with the bwboundaries function (I think).
It will work some times and not others depending on the picture, they can be seen below.
Any help anyone could give me would be appreciated. I am struggling here to figure out what I am doing wrong.
clear, clc , close all
%% Specify the folder where the files live.
%myFolder = 'D:\Try';
myFolder = 'D:\Try\PicNamed\SpTestTry\hope';
%% Check to make sure that folder actually exists.
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
%% Get a list of all files in the folder with the pattern
filePattern = fullfile(myFolder, '*.jpg'); % Change to whatever need.
theFiles = dir(filePattern);
line = cell(length(theFiles), 1) ;
rValue = cell(length(theFiles),1);
baseFileName = theFiles(1).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
% getting the rectanglur cords to crop the images
[I2, rect] = imcrop(imageArray);
%% Run Loop
for k = 1 : length(theFiles)
%Pulling in multiple Images from folder
baseFileName = theFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
%% Cropping Image with Rect Cords
Icrop = imcrop(imageArray,rect);
%% convert to bw
BW = im2bw(Icrop, graythresh(Icrop));
%% Get Boundries
boundaries = bwboundaries(BW);
% putting in x and y cord
x = boundaries{1}(:, 2);
y = boundaries{1}(:, 1);
%% Curve Fit
%pulling up picture of x,y plot to determing where base of flame is
figure
plot(x, y)
% cutting off bottom of flame edge so we can do curve fit
prompt = '(******) cut off line = ';
cutnum = input(prompt);
indices = find(abs(y)>cutnum);
y(indices) = NaN;
y(indices) = [];
x(indices) = [];
%% Looking for repate x values, averaging them together, and replacing with 1 x value
uc1 = unique( x ) ;
mc2 = accumarray( x, y, [], #mean ) ;
newData = [uc1, mc2(uc1)];
%% splitting AA into two sperate matricies, i.e. x/y cordinates
y = newData(:,2);
x = newData(:,1);
%% Creating a line Based off of the averaged x and y cords
[p,S] = polyfit(x,y,4); % 4th degree polynomail
line{k} = p;
rValue{k} = S.normr;
Rsquared{k}=1-S.normr^2/norm(y-mean(y))^2;
close all
clear BW
clear x
clear y
end

how to extract each characters from a image?with using this code

i have to extract each characters from a image here i am uploading the code it is segmenting the horizontal lines but not able to segment the each characters along with the horizontal line segmentation loop. some1 please help to correct the code
this is the previous code:
%%horizontal histogram
H = sum(rotatedImage, 2);
darkPixels = H < 100; % Threshold
% label
[labeledRegions, numberOfRegions] = bwlabel(darkPixels);
fprintf('Number of regions = %d\n', numberOfRegions);
% Find centroids
measurements = regionprops(labeledRegions, 'Centroid');
% Get them into an array
allCentroids = [measurements.Centroid];
xCentroids = int32(allCentroids(1:2:end));
yCentroids = int32(allCentroids(2:2:end));
% Now you can just crop out some line of text you're interested in, into a separate image:
hold off;
plotLocation = 8;
for band = 1 : numberOfRegions-1
row1 = yCentroids(band);
row2 = yCentroids(band+1);
thisLine = rotatedImage(row1 : row2, :);
subplot(7, 2, plotLocation)
imshow(thisLine, [])
%% Let's compute and display the histogram.
verticalProjection = sum(thisLine, 2);
set(gcf, 'NumberTitle', 'Off')
t = verticalProjection;
t(t==0) = inf;
mayukh=min(t);
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > mayukh;
% Find Rising and falling edges
d = diff(letterLocations);
startingRows = find(d>0);
endingRows = find(d<0);
% Extract each region
y=1;
for k = 1 : length(startingRows)
% Get sub image of just one character...
subImage = thisLine(:, startingRows(k):endingRows(k));
[L,num] = bwlabel(subImage);
for z= 1 : num
bw= ismember( L, z);
% Construct filename for this particular image.
baseFileName = sprintf('templates %d.png', y);
y=y+1;
% Prepend the folder to make the full file name.
fullFileName = fullfile('C:\Users\Omm\Downloads\', baseFileName);
% Do the write to disk.
imwrite(bw, fullFileName);
pause(2);
imshow(bw);
pause(5)
end;
y=y+2;
end;
plotLocation = plotLocation + 2;
end
but not segmenting the whole lines
Why don't you simply use regionprops with 'Image' property?
img = imread('http://i.stack.imgur.com/zpYa5.png'); %// read the image
bw = img(:,:,1) > 128; %// conver to mask
Use some minor morphological operations to handle spurious pixels
dbw = imdilate(bw, ones(3));
lb = bwlabel(dbw).*bw; %// label each character as a connected component
Now you can use regionprops to get each image
st = regionprops( lb, 'Image' );
Visualize the results
figure;
for ii=1:numel(st),
subplot(4,5,ii);
imshow(st(ii).Image,'border','tight');
title(num2str(ii));
end

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

To refresh imshow in Matlab?

I want to convert this answer's code to imshow.
It creates a movie in MOVIE2AVI by
%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
surf(sin(2*pi*k/20)*Z, Z)
mov(k) = getframe(gca);
end
close(gcf)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);
My pseudocode
%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
imshow(signal(:,k,:),[1 1 1]) % or simply imshow(signal(:,k,:))
drawnow
mov(k) = getframe(gca);
end
close(gcf)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);
However, this creates the animation in the screen, but it saves only a AVI -file which size is 0 kB. The file myPeaks1.avi is stored properly after running the surf command but not from imshow.
I am not sure about the command drawnow.
Actual case code
%% HSV 3rd version
% https://stackoverflow.com/a/29801499/54964
rgbImage = imread('http://i.stack.imgur.com/cFOSp.png');
% Extract blue using HSV
hsvImage=rgb2hsv(rgbImage);
I=rgbImage;
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
R((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
G((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
B((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
I2= cat(3, R, G, B);
% Binarize image, getting all the pixels that are "blue"
bw=im2bw(rgb2gray(I2),0.9999);
% The label most repeated will be the signal.
% So we find it and separate the background from the signal using label.
% Label each "blob"
lbl=bwlabel(~bw);
% Find the blob with the highes amount of data. That will be your signal.
r=histc(lbl(:),1:max(lbl(:)));
[~,idxmax]=max(r);
% Profit!
signal=rgbImage;
signal(repmat((lbl~=idxmax),[1 1 3]))=255;
background=rgbImage;
background(repmat((lbl==idxmax),[1 1 3]))=255;
%% Error Testing
comp_image = rgb2gray(abs(double(rgbImage) - double(signal)));
if ( sum(sum(comp_image(32:438, 96:517))) > 0 )
break;
end
%% Video
% 5001 units so 13.90 (= 4.45 + 9.45) seconds.
% In RGB, original size 480x592.
% Resize to 480x491
signal = signal(:, 42:532, :);
% Show 7 seconds (298 units) at a time.
% imshow(signal(:, 1:298, :));
%% Video VideoWriter
% movie2avi deprecated in Matlab
% https://stackoverflow.com/a/11054155/54964
% https://stackoverflow.com/a/29952648/54964
%# figure
hFig = figure('Menubar','none', 'Color','white');
Z = peaks;
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap parula; axis tight manual off;
set(gca, 'nextplot','replacechildren', 'Visible','off');
% set(gcf,'Renderer','zbuffer'); % on some Windows
%# preallocate
N = 40; % 491;
vidObj = VideoWriter('myPeaks3.avi');
vidObj.Quality = 100;
vidObj.FrameRate = 10;
open(vidObj);
%# create movie
for k=1:N
set(h, 'CData', signal(:,k:k+40,:))
% drawnow
writeVideo(vidObj, getframe(gca));
end
%# save as AVI file
close(vidObj);
How can you substitute the drawing function by imshow or corresponding?
How can you store the animation correctly?
Here is some code to try:
%// plot
hFig = figure('Menubar','none', 'Color','white');
Z = peaks;
%h = surf(Z);
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap jet
axis tight manual off
%// preallocate movie structure
N = 40;
mov = struct('cdata',cell(1,N), 'colormap',cell(1,N));
%// aninmation
for k=1:N
%set(h, 'ZData',sin(2*pi*k/N)*Z)
set(h, 'CData',sin(2*pi*k/N)*Z)
drawnow
mov(k) = getframe(hFig);
end
close(hFig)
%// save AVI movie, and open video file
movie2avi(mov, 'file.avi', 'Compression','none', 'Fps',10);
winopen('file.avi')
Result (not really the video, just a GIF animation):
Depending on the codecs installed on your machine, you can apply video compression, e.g:
movie2avi(mov, 'file.avi', 'Compression','XVID', 'Quality',100, 'Fps',10);
(assuming you have the Xvid encoder installed).
EDIT:
Here is my implementation of the code you posted:
%%// extract blue ECG signal
%// retrieve picture: http://stackoverflow.com/q/29800089
imgRGB = imread('http://i.stack.imgur.com/cFOSp.png');
%// detect axis lines and labels
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));
%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;
%%// create sliding-window video
len = 40;
signal = imgRGB2(:,42:532,:);
figure('Menubar','none', 'NumberTitle','off', 'Color','k')
hImg = imshow(signal(:,1:1+len,:), ...
'InitialMagnification',100, 'Border','tight');
vid = VideoWriter('signal.avi');
vid.Quality = 100;
vid.FrameRate = 60;
open(vid);
N = size(signal,2);
for k=1:N-len
set(hImg, 'CData',signal(:,k:k+len,:))
writeVideo(vid, getframe());
end
close(vid);
The result look like this:

Extracting image region within boundary

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);