- You will see updates in your activity feed.
- You may receive emails, depending on your notification preferences.

22 views (last 30 days)

Show older comments

from give matrix (attached), i am using following code to close the surface and to make a boundary but i am getting errors that indexing is out of bound.

m = zeros(28)

m = load('Matrix_Boundary_fills_3s_only.txt');

[rows, colms] = size(m);

mOut = m;

for row = 2 : rows

%

for colm = 1:colms

if m(row-1, colm) == 3

mOut(row, colm+1) = 3;

end

if m(row-1, colm) == 3 || m(row-1,colm+2) == 3

mOut(row, colm+1) = 3;

end

if m(row-1, colm + 1) == 3

mOut(row, colm+1) = 3;

end

end

end

% end

disp(mOut)

thanks for all cooperation in advance.

Image Analyst
on 16 Aug 2019

Edited: Image Analyst
on 16 Aug 2019

Is the data (circle) expected to be convex? If so the ultra-easy way is to just use bwconvhull() followed by bwboundaries(), poly2mask(), and bwperim() like the code below. If not, you'll have to follow my answer to your other question where I tell you how to connect each endpoint to the closest other endpoint.

% Get and display original data.

[numbers, strings, raw] = xlsread('matrix.xlsx');

m = uint8(numbers);

subplot(2, 2, 1);

imshow(m, [], 'InitialMagnification', 800);

axis('on', 'image');

title('Original Data', 'FontSize', 20);

% Get convex hull.

chImage = bwconvhull(m);

subplot(2, 2, 2);

imshow(chImage, [], 'InitialMagnification', 800);

axis('on', 'image');

boundary = bwboundaries(chImage);

boundary = boundary{1}; % Extract the outermost boundary from the cell.

x = boundary(:, 2);

y = boundary(:, 1);

title('Convex Hull', 'FontSize', 20);

% Show results.

subplot(2, 2, 3);

imshow(m, [], 'InitialMagnification', 800);

axis('on', 'image');

hold on;

plot(x, y, 'r.-', 'LineWidth', 2, 'MarkerSize', 15);

title('Original Data with Boundary Overlaid', 'FontSize', 20);

% Get the perimeter

[rows, columns] = size(m);

mask = poly2mask(x, y, rows, columns); % Create a solid mask.

% Get the perimeter only.

perimImage = bwperim(mask);

% Show results.

subplot(2, 2, 4);

imshow(perimImage, [], 'InitialMagnification', 800);

axis('on', 'image');

title('New, Convex Perimeter', 'FontSize', 20);

%------------------------------------------------------------------------------

% Set up figure properties:

% Enlarge figure to full screen.

set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);

% Get rid of tool bar and pulldown menus that are along top of figure.

% set(gcf, 'Toolbar', 'none', 'Menu', 'none');

% Give a name to the title bar.

set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')

If you don't want the x,y coordinates and only want the matrix, you can skip calling bwboundaries() and just call bwperim() directly on the convex hull image.

perimImage = bwperim(chImage);

M.S. Khan
on 17 Aug 2019

Very very thankful Dear Image Analyst for such a detalied professional feedback and guidance.

kindly could you please guide me, lets suppose its not circular, how can we deal that situation.

lets see the Attached file matrix is not circular.

is it possible to follow the boundary the same as it is, instead converting it into circle.

Your cooperation is highly appreciated.

Thanks for all professional stafff of Mathworks for such a great collaboration and coodination in knowledge sharing and guidance.

M.S. Khan
on 17 Aug 2019

if you see the stem of shape, its gives overestimation. plz help me how to follow the exact boundary of the shape to find exact calculations as per shape.

Thanks in advance.

Image Analyst
on 17 Aug 2019

M.S. Khan
on 17 Aug 2019

M.S. Khan
on 18 Aug 2019

Dear fellow image analyst as your per your remarks:

% Your data has 3 endpoints.

% Explain in words a rule for what you want to do.

% For example "I'd like to connect any endpoints that are within a

% separation of 5 pixels with a line connecting them" or something like that.

is it possible to follow the boundary as it is and where ever there is a hole inside boudary for shape preserving, we will fill it.

Thanks for all cooperation

Image Analyst
on 24 Aug 2019

M.S. Khan
on 25 Aug 2019

Dear Image Analyst, thanks for reply. is it not possilbe to do scalling of own choice?plz. In the pics above, its like 5 10 15 ....

Can we make it like x-axis: -10 0 10 20 .....

Thanks in advance for cooperation

Image Analyst
on 25 Aug 2019

M.S. Khan
on 26 Aug 2019

Thanks for reply. Image Analyst,

i means the the x-axis and y-axis labelling and scalling.

The X-axis that you have given on x-axis as shown in the first figure --> 5 10 15 20 25

The Y-axis--> 5 10 15 20 25 30

Please guide me, how the change the size of hole?

Really very very thankful for your expert guidance.

Regards

M.S. Khan
on 5 Sep 2019

Dear Image Analyst and all Mathwork expert, i want to ask two questions plz.

Question #1

can i set the axis limits by following commands as shown in above coding.?

ax.xlim = [-120:10:120]

ax.ylim = [-120:10:120]

Question #2

Can i replace the filled gaps by any other number like 3 i?

i want to different to differentiate the fillied gaps from other numbers.

Thanks in advance for all your kind cooperation.

regards

Bruno Luong
on 18 Aug 2019

Edited: Bruno Luong
on 23 Aug 2019

Add the salt to suit your need

Aorg = xlsread('Y_slice.xlsx');

gapmax = 5; % adjust to your need

[m,n] = size(Aorg);

A = Aorg>0;

P=[1 2 3;

8 0 4;

7 6 5];

Apad = zeros(m+2,n+2);

Apad(2:end-1,2:end-1) = A;

B = zeros(m,n,8);

for k=1:8

[i,j] = find(P==k);

B(:,:,k) = Apad(i-2+(2:end-1),j-2+(2:end-1));

end

As = A & sum(diff(B(:,:,[1:8 1]),1,3)==1,3)<=1;

[y,x] = find(As);

p = length(x);

xy = [x,y];

xy1 = reshape(xy,1,[],2);

xy2 = reshape(xy,[],1,2);

d = sum(abs(xy1-xy2),3);

d(d==0) = NaN;

i = (1:size(d,1))';

[dmin,j] = min(d,[],2);

keep = dmin <= gapmax;

keep = keep & j<i;

i = i(keep);

j = j(keep);

for k=1:length(i)

xyi = xy(i(k),:);

xyj = xy(j(k),:);

dxy = xyi-xyj;

if abs(dxy(1)) > abs(dxy(2))

xr = linspace(xyi(1),xyj(1),abs(dxy(1))+1);

yr = round(interp1([xyi(1),xyj(1)],[xyi(2),xyj(2)],xr));

else

yr = linspace(xyi(2),xyj(2),abs(dxy(2))+1);

xr = round(interp1([xyi(2),xyj(2)],[xyi(1),xyj(1)],yr));

end

A(sub2ind(size(A),yr,xr)) = 1;

end

close all

subplot(1,2,1);

imagesc(Aorg);

title('original');

subplot(1,2,2);

imagesc(A);

title('filling gap');

M.S. Khan
on 19 Aug 2019

Aorg =

Columns 1 through 22

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 3 3 0 0 0 0 3 3 3 3 0 0 0

0 0 0 0 0 3 3 3 0 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3

0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3

0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3

0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0

0 0 0 0 0 0 0 3 3 3 0 0 0 0 0 0 3 0 3 0 0 0

0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Columns 23 through 28

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

3 0 0 0 0 0

3 0 0 0 0 0

0 3 0 0 0 0

0 3 0 0 0 0

0 3 0 0 0 0

0 0 0 0 0 0

0 0 3 0 0 0

0 0 3 0 0 0

0 0 3 0 0 0

0 0 3 0 0 0

0 0 3 0 0 0

0 3 3 0 0 0

0 3 0 0 0 0

0 3 0 0 0 0

3 0 0 0 0 0

3 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0]

Thanks Dear Bruno Luong for cooperation. Really obliged for giving such a professional tips of matlab. Bruno, if i am applying your code on this matrix. its still giving holes. plz help me to make it more dynamic so that we can apply on all type of matrices to fill holes.

Again Warm regards for your professional support!!!

Bruno Luong
on 19 Aug 2019

I can't copy past your matrix display output that breaks the colums in 2 blocks.

Please attach the MATFILE or a post a copy/pastable code to generate the matrix

M.S. Khan
on 19 Aug 2019

Thanks Bruno for your cooperation. i am trying to utilize it on different matrices of different shapes. Very thankful for your time.

God bless you.

Regards and Greetings!!

M.S. Khan
on 20 Aug 2019

Dear Bruno, very thankful for your cooperation.

Could you please explain to me the coding?

How and why you took P matrix with these numbers?

P=[1 2 3;

8 0 4;

7 6 5];

M.S. Khan
on 20 Aug 2019

Bruno, how to bring MAT file here in mathwork coding place.

Sorry, I dont know the method. Please if you can tell me about steps. i will be very thankful.

Bruno Luong
on 20 Aug 2019

Use SAVE command under MATLAB to save your variables in a MATFILE.

In Answer interface, just use attach button, then attach the MAT file.

Bruno Luong
on 20 Aug 2019

P represents 8 neightbour pixels of the central pixel (0).

I put it that way because I want the pixel turning around the central pixel continuously.

I use it to get values of 8 pixels around a given (bounday) pixel (first for-loop), then count number of transition from 0 to 1 by computing the quantity

sum(diff(B(:,:,[1:8 1]),1,3)==1,3) % this deserves an explanation

If the number of transitions is 0 then it is an isolated pixel, 1 then it is a pixel at the end of the boundary from the original image so there a gap. Otherwise the above expression will return 2 (or 3 of a T intersection, etc...).

Next I just isolate those end pixels,

As = A & sum(diff(B(:,:,[1:8 1]),1,3)==1,3)<=1

then I compute their pair-wise distance (mathathan distane) in d. If their distance is <= gapmax (==5), I simply draw a discrete line to joint them so to fill the gap (the second for-loop).

There are some subtility about the interpolation of vertical or horizontal lines (if in for loop) or avoid drawing twice the same line (i<j). But those are just the details.

NOTE that my code does not require any toolbox.

M.S. Khan
on 23 Aug 2019

Thanks Dear Bruno for your time. God bless you.

P=[1 2 3;

8 0 4;

7 6 5];

Bruno, i want to know, In matrix P, these numbers should be always in the same order and sequence or we are allowed to change

Bruno Luong
on 23 Aug 2019

The numbers 1:8 are required to be consecutive on the border of the 3x3 square. However the direction (clock/anti-clock) or where it starts doesn't matter.

For example this one is also valid

P = [5 4 3;

6 0 2;

7 8 1];

M.S. Khan
on 23 Aug 2019

Thanks dear Bruno, Great!!

i am studying it and will need your help in future too.

Wish you all the best for all your cooperation.

warm regards

Bruno Luong
on 5 Sep 2019

This code a reply to this Question

Aorg = xlsread('Y_slice.xlsx');

gapmax = 5; % adjust to your need

[m,n] = size(Aorg);

A = Aorg>0;

P=[1 2 3;

8 0 4;

7 6 5];

Apad = zeros(m+2,n+2);

Apad(2:end-1,2:end-1) = A;

B = zeros(m,n,8);

for k=1:8

[i,j] = find(P==k);

B(:,:,k) = Apad(i-2+(2:end-1),j-2+(2:end-1));

end

As = A & sum(diff(B(:,:,[1:8 1]),1,3)==1,3)<=1;

[y,x] = find(As);

p = length(x);

xy = [x,y];

xy1 = reshape(xy,1,[],2);

xy2 = reshape(xy,[],1,2);

d = sum(abs(xy1-xy2),3);

d(d==0) = NaN;

i = (1:size(d,1))';

[dmin,j] = min(d,[],2);

keep = dmin <= gapmax;

keep = keep & j<i;

i = i(keep);

j = j(keep);

A = double(A); % change here for Q2

for k=1:length(i)

xyi = xy(i(k),:);

xyj = xy(j(k),:);

dxy = xyi-xyj;

if abs(dxy(1)) > abs(dxy(2))

xr = linspace(xyi(1),xyj(1),abs(dxy(1))+1);

yr = round(interp1([xyi(1),xyj(1)],[xyi(2),xyj(2)],xr));

else

yr = linspace(xyi(2),xyj(2),abs(dxy(2))+1);

xr = round(interp1([xyi(2),xyj(2)],[xyi(1),xyj(1)],yr));

end

A(sub2ind(size(A),yr(2:end-1),xr(2:end-1))) = 3; % change here for Q2

end

close all

ax=axes();

imagesc([-120,120],[-120 120],A); % change here for Q1

set(ax,'xtick',-120:10:120,'ytick',-120:10:120); % change here for Q1

title('filling gap');

M.S. Khan
on 5 Sep 2019

Thanks Bruno for reply.

usine the same file, please guide me as you have used this for width of 10

set(ax,'xtick',-120:10:120,'ytick',-120:10:120); % change here for Q1

For the same question, if i change the widht as 5 like -120:5:120

Then the boundary remains open and gaps still exist there.

Regards for all cooperation

Bruno Luong
on 5 Sep 2019

"For the same question, if i change the widht as 5 like -120:5:120 Then the boundary remains open and gaps still exist there."

It doesn't make sense

set(ax,'xtick',...)

changes the graphic of the axis not the image.

Closing the gap is performed way before any display, it's even there if you don't display anything on screen.

You make a mistake (with variable name probably), so double/triple verify on your side.

And you notice that I attach the full-code and the result image everytime I post. You should do the same.

M.S. Khan
on 5 Sep 2019

%Aorg = xlsread('Y_slice.xlsx');

Aorg = Result_matrix.mat

gapmax = 5; % adjust to your need

[m,n] = size(Aorg);

A = Aorg>0;

P=[1 2 3;

8 0 4;

7 6 5];

Apad = zeros(m+2,n+2);

Apad(2:end-1,2:end-1) = A;

B = zeros(m,n,8);

for k=1:8

[i,j] = find(P==k);

B(:,:,k) = Apad(i-2+(2:end-1),j-2+(2:end-1));

end

As = A & sum(diff(B(:,:,[1:8 1]),1,3)==1,3)<=1;

[y,x] = find(As);

p = length(x);

xy = [x,y];

xy1 = reshape(xy,1,[],2);

xy2 = reshape(xy,[],1,2);

d = sum(abs(xy1-xy2),3);

d(d==0) = NaN;

i = (1:size(d,1))';

[dmin,j] = min(d,[],2);

keep = dmin <= gapmax;

keep = keep & j<i;

i = i(keep);

j = j(keep);

A = double(A); % change here for Q2

for k=1:length(i)

xyi = xy(i(k),:);

xyj = xy(j(k),:);

dxy = xyi-xyj;

if abs(dxy(1)) > abs(dxy(2))

xr = linspace(xyi(1),xyj(1),abs(dxy(1))+1);

yr = round(interp1([xyi(1),xyj(1)],[xyi(2),xyj(2)],xr));

else

yr = linspace(xyi(2),xyj(2),abs(dxy(2))+1);

xr = round(interp1([xyi(2),xyj(2)],[xyi(1),xyj(1)],yr));

end

A(sub2ind(size(A),yr(2:end-1),xr(2:end-1))) = 3; % change here for Q2

end

close all

ax=axes();

imagesc([-120,120],[-120 120],A); % change here for Q1

set(ax,'xtick',-120:5:120,'ytick',-120:5:120); % change here for Q1

title('filling gap');

Dear Bruno, now you can view it to give me your expert suggestion.

warm regards

Bruno Luong
on 5 Sep 2019

Thanks, the problem is my initial algorithm is not robust for large number of gaps. What you observe has nothing to do with axis of step 5 or 10.

Here is the code more robust.

clear

s = load('Result_matrix.mat');

Aorg = s.Aorg;

gapmax = 10; % adjust to your need

[m,n] = size(Aorg);

A = double(Aorg>0); % change here for Q2

P=[1 2 3;

8 0 4;

7 6 5];

Apad = zeros(m+2,n+2);

maxattempt = 10;

for niter = 1:maxattempt % Change here to fix BUG when there is large number of gaps

Apad(2:end-1,2:end-1) = A>0;

B = zeros(m,n,8);

for k=1:8

[i,j] = find(P==k);

B(:,:,k) = Apad(i-2+(2:end-1),j-2+(2:end-1));

end

As = A>0 & sum(diff(B(:,:,[1:8 1]),1,3)==1,3)<=1;

[y,x] = find(As);

if isempty(x)

break

end

p = length(x);

xy = [x,y];

xy1 = reshape(xy,1,[],2);

xy2 = reshape(xy,[],1,2);

d = sum(abs(xy1-xy2),3);

d(d==0) = NaN;

i = (1:size(d,1))';

[dmin,j] = min(d,[],2);

keep = dmin <= gapmax;

i = i(keep);

j = j(keep);

for k=1:length(i)

xyi = xy(i(k),:);

xyj = xy(j(k),:);

dxy = xyi-xyj;

if abs(dxy(1)) > abs(dxy(2))

xr = linspace(xyi(1),xyj(1),abs(dxy(1))+1);

yr = round(interp1([xyi(1),xyj(1)],[xyi(2),xyj(2)],xr));

else

yr = linspace(xyi(2),xyj(2),abs(dxy(2))+1);

xr = round(interp1([xyi(2),xyj(2)],[xyi(1),xyj(1)],yr));

end

A(sub2ind(size(A),yr(2:end-1),xr(2:end-1))) = 3; % change here for Q2

end

end

if isempty(x)

fprintf('Success\n')

else

fprintf('Fail\n')

end

figure(1);

clf;

ax=subplot(1,2,1);

imagesc([-120 120],[-120 120],Aorg>0); % change here for Q1

set(ax,'xtick',-120:5:120,'ytick',-120:5:120,'clim',[0 3]); % change here for Q1

axis equal

title('original>0');

ax=subplot(1,2,2);

imagesc([-120 120],[-120 120],A); % change here for Q1

set(ax,'xtick',-120:5:120,'ytick',-120:5:120,'clim',[0 3]); % change here for Q1

axis equal

title('filling gap');

M.S. Khan
on 5 Sep 2019

Thanks Bruno, its works, Very thankful. God bless you.

Now i want to fill all interior with 2s.

i wrote following code but its changing all the perimeter as either 1, not keeping 3 as a boundary.

dlmwrite('A.txt',A)

%% interior filling as 2

Perimeter1=bwperim(A)

% dlmwrite('Closed Boundary filled with 1s.txt',Perimeter)

interior_filled = imfill(A,'holes')

A = 3*double(A)

interior_filled = 2*double(interior_filled)

interior_filled(Perimeter)=1

imshow(interior_filled,[])

dlmwrite('Boundary as 1 or 3 with interior filled as 2s.txt',interior_filled)

Bruno Luong
on 5 Sep 2019

I don't own IPTbx license so I can't test but I would change to

interior_filled(Perimeter)=A(Perimeter)

Not sure either what is the purpose of

A = 3*double(A)

You want then to change perimeter pixels to to 3 and 9?

M.S. Khan
on 5 Sep 2019

Thanks Bruno for all your kind help. i resolved the issue of boundary of 1 and 3 by using your professional tips.

Please i want to learn how to change the image view because in the below picture, the x sclae is very down while y scale is ok. How to adjust the x-scale and y-scale so that it looks better.

i tried to handle it by following code but its disappearing it properties.

imshow(Aorg,[],'InitialMagnification',800)

Could you plz guide me.

Again thanks for all your support.

Good wishes and special prayers.

Bruno Luong
on 5 Sep 2019

I don't understand your question.

But it seems unrelated to closing boundary problem.

You probably need to open a new thread with this specific issue so more people can read.

M.S. Khan
on 5 Sep 2019

M.S. Khan
on 5 Sep 2019

Thanks Bruno for all your professional supprt. i solved the issue.

Warmest regards!!!

Bruno Luong
on 5 Sep 2019

I strongly advise you to open the new thread. The question is about basic plotting, unrelated to closing the gap of boundary of the original post.

Please stop making this thread longer and longer with a string of unrelated graphic rendering issues (tick label/axis limits, white strips, etc...). This helps people to read the thread.

figure(1);

clf;

ax=subplot(1,2,1);

imagesc([-120 120],[-120 120],Aorg>0); % change here for Q1

set(ax,'xtick',-120:5:120,'ytick',-120:5:120,'clim',[0 3]); % change here for Q1

axis equal

axis tight % <- what you need is this

title('original>0');

ax=subplot(1,2,2);

imagesc([-120 120],[-120 120],A); % change here for Q1

set(ax,'xtick',-120:5:120,'ytick',-120:5:120,'clim',[0 3]); % change here for Q1

axis equal

axis tight % <- what you need is this

title('filling gap');

M.S. Khan
on 6 Sep 2019

Hi Bruno, hope you are all well.

when i am running the above code for closing boundary. At the end, you have written this code. After excuting, i am getting ' Fail '.

if isempty(x)

fprintf('Success\n')

else

fprintf('Fail\n')

end

Bruno Luong
on 6 Sep 2019

It's just a warning if the boundary has a pig-tai that is not supposed attach to anything else - as with the apple shape and the small stick end (not sure the english name).

You can remove it if it's bother you.

M.S. Khan
on 6 Sep 2019

very thankful for your immediate reply.

Regards with heartfelt prayers and wishes

M.S. Khan
on 17 Sep 2019

i want to ask for the same closed boundary as boundary is filled as yellow color, Can i fill the interior with other color like Green. plz

i want to put is as new question as in new queue as well.

Regards in advance.

Image Analyst
on 17 Sep 2019

M.S. Khan
on 17 Sep 2019

Dear Image Analyst, holes can be any size but if its filled on the boundary surface, then I want to have boundary filled as color blue, holes filled as yellow and interior filled as green.

Is it possible, as you have already filled the boundary in the thread above.

Regards for best cooperation.

Image Analyst
on 18 Sep 2019

If the holes can be any size, then you can simply use imfill() to make a solid blob, then use that image, plus the original image, in cat() to construct the RGB image.

I don't really know the difference between "holes" and "interior" since you said holes can be any size whatsoever from 1 pixel up to nearly the entire blob size. So I don't know what distinguishes between what would be a yellow region and a green region. Please supply a diagram and point out what differences the yellow and green regions have (since you said it's NOT their size).

M.S. Khan
on 18 Sep 2019

yes i am using imfill() functions but i want then to differentiate between boundary and interor.

For example interior is filled as 2s and boundary as 1s or 3s.

i want the interior as filled with 2s to be different color.

Boundary filled with1s and 3s as a different color

Exterior can be any other different color.

Thanks for cooperation

Bruno Luong
on 17 Aug 2019

You can use imclose (image processing toolbox required)

M.S. Khan
on 17 Aug 2019

Thanks Bruno for support but its not following the exact boundary which the shape has. i want the same bouundary as Image analyst has shown in 3rd figure. its good for circle but i want it be more dynamic to make boundary of any type of shape.

Thanks for all help and support

Bruno Luong
on 17 Aug 2019

M.S. Khan
on 17 Aug 2019

Bruno, could you please explain to me how to utilize SE? Give me an example.

i will be very thankful.

Regards

M.S. Khan
on 17 Aug 2019

Dear image analyst, i am taking help of your code and has tried to apply on non circular shapes like apple. i used the imclose() function in the following code to generate boundary but the problems is that its giving probelm in closing. plz help me how to get closed shape apple.

% Get and display original data.

% [numbers, strings, raw] = xlsread('matrix.xlsx');

m = load('Matrix_Boundary_fill_3s_only.txt')

m = uint8(m);

subplot(2, 2, 1);

imshow(m, [], 'InitialMagnification', 800);

axis('on', 'image');

title('Original Data', 'FontSize', 20);

% Get convex hull.

% chImage = bwconvhull(m);

se = strel('arbitrary',10)

closeBW = imclose(m,se)

subplot(2, 2, 2);

imshow(closeBW, [], 'InitialMagnification', 800);

axis('on', 'image');

perimImage = bwperim(closeBW)

boundary = bwboundaries(closeBW);

boundary = boundary{1}; % Extract the outermost boundary from the cell.

x = boundary(:, 2);

y = boundary(:, 1);

title('apple shape', 'FontSize', 20);

% Show results.

subplot(2, 2, 3);

imshow(m, [], 'InitialMagnification', 800);

axis('on', 'image');

hold on;

plot(x, y, 'r.-', 'LineWidth', 2, 'MarkerSize', 15);

title('Original Data with Boundary Overlaid', 'FontSize', 20);

% Get the perimeter

[rows, columns] = size(m);

mask = poly2mask(x, y, rows, columns); % Create a solid mask.

% Get the perimeter only.

perimImage = bwperim(mask);

% Show results.

subplot(2, 2, 4);

imshow(perimImage, [], 'InitialMagnification', 800);

axis('on', 'image');

title('New, apple like Perimeter', 'FontSize', 20);

%------------------------------------------------------------------------------

% Set up figure properties:

% Enlarge figure to full screen.

set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);

% Get rid of tool bar and pulldown menus that are along top of figure.

% set(gcf, 'Toolbar', 'none', 'Menu', 'none');

% Give a name to the title bar.

set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')

M.S. Khan
on 18 Aug 2019

in above pic having red color boundary having one hole.

can anyone help me please, how to close it and get the closed perimeter.

Thanks in advance for cooperation.

Image Analyst
on 19 Aug 2019

You can try this, where I find endpoints and draw a line between any endpoints that are closer than a certain, specified distance.

clc; % Clear the command window.

close all; %Close all figures (except those of imtool.)

clear; % Erase all existing variables. Or clearvars if you want.

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

fontSize = 14;

% Get and display original data.

[numbers, strings, raw] = xlsread('x_slice.xlsx');

m = uint8(numbers);

subplot(2, 2, 1);

imshow(m, [], 'InitialMagnification', 800);

axis('on', 'image');

title('Original Data', 'FontSize', fontSize);

% Find the skeleton.

binaryImage = m ~= 0; % Convert double to logical.

skelImage = bwmorph(binaryImage, 'skel', inf);

subplot(2, 2, 2);

imshow(skelImage, [], 'InitialMagnification', 800);

axis('on', 'image');

title('Skeleton', 'FontSize', fontSize);

% Find the endpoints.

endPoints = bwmorph(skelImage, 'endpoints');

[epYRows, epXColumns] = find(endPoints)

subplot(2, 2, 3);

imshow(endPoints, [], 'InitialMagnification', 800);

axis('on', 'image');

title('Endpoints', 'FontSize', fontSize);

%------------------------------------------------------------------------------

% Set up figure properties:

% Enlarge figure to full screen.

set(gcf, 'Units', 'Normalized', 'OuterPosition', [0.5, 0.04, 0.5, 0.96]);

% Get rid of tool bar and pulldown menus that are along top of figure.

% set(gcf, 'Toolbar', 'none', 'Menu', 'none');

% Give a name to the title bar.

set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')

% Now that we have the endpoints, we can begin "Edge linking".

% For each endpoint, find the distances to every other endpoint,

% and connect them with a line if they are closer than aspecified distance.

finalImage = logical(m); % Image of the final image.

lineCount = 0;

maxAllowableClosestDistance = 4; % Connect if this or closer, ignore if farther away than this

for k = 1 : length(epYRows) - 1

thisX = epXColumns(k);

thisY = epYRows(k);

for k2 = k+1 : length(epYRows)

thisDistance = sqrt((thisX - epXColumns(k2)).^2 + (thisY - epYRows(k2)) .^ 2);

% Get rid of the kth distance which will be zero because it's the distance of the point to itself.

% For all that are closer than 3 pixels, connect them.

if thisDistance == 0 || thisDistance > maxAllowableClosestDistance

% This point is too far away, or in the very same location.

fprintf('Skipping point #%d and %d.\n', k, k2);

continue; % Skip to next pair.

end

fprintf('Connecting point #%d and %d.\n', k, k2);

% Make a binary image with a line connecting the kth index to each of the other close indexes.

% Create a line objects between these two points.

p = [thisX, thisY; epXColumns(k2), epYRows(k2)]; % [x1, y1; x2, y2]

% Create a line ROI object.

subplot(2, 2, 3);

hLine = drawline('Position', p,'StripeColor','r');

% Create a binary image ("mask") from the ROI object.

singleLineBinaryImage = hLine.createMask();

% Display the lines mask.

subplot(2, 2, 4);

imshow(singleLineBinaryImage);

lineCount = lineCount + 1;

caption = sprintf('Binary mask after connecting %d lines', lineCount);

title(caption, 'FontSize', fontSize);

% Burn line into image by setting it to 255 wherever the mask is true.

finalImage(singleLineBinaryImage) = true;

% Display the image with the "burned in" line.

cla;

imshow(finalImage);

caption = sprintf('New image with %d lines burned into image', lineCount);

title(caption, 'FontSize', fontSize);

end

end

% % Optionally fill the shape and get the outer perimeter.

% finalImage = imfill(finalImage, 'holes');

% finalImage = bwperim(finalImage);

% Display the perimeter of the filled shape.

imshow(finalImage);

caption = sprintf('New image with %d lines burned into image', lineCount);

title(caption, 'FontSize', fontSize);

fprintf('Done!\n');

M.S. Khan
on 19 Aug 2019

Dear Image Analyst, Salute to you.

Really very thankful for your professional support.

Good wishes and special prayers for you and all math work team and community members.

M.S. Khan
on 19 Aug 2019

Image Analyst, please you explain me the coding because some function are very new to me.

or could you send to me some stuff to read it plz.

warm regards

M.S. Khan
on 19 Aug 2019

Hi community brothers & sisters

is it possible to fill all the interior of fixed boudary with any other number like 2 or 3.

i tried imfill() but its not working.

Thanks in advance for support

Image Analyst
on 19 Aug 2019

To fill the interior of a binary image, you must first identify the perimeter with bwperim and save it. Then multiply the image by 2 or 3 and finally set the perimeter back to 1.

perimImage = bwperim(mask);

% Set everything to 3

mask = 3 * double(mask);

% Set perimeter back to 1.

mask(perimImage) = 1;

imshow(mask, []); % Use [] so you can see it when displayed.

M.S. Khan
on 19 Aug 2019

Thanks for reply.

i think we dont variable mask in the new edited code.

regards

M.S. Khan
on 23 Aug 2019

Hi Image Analyst and all community members,

thanks for all support and professional cooperation.

May i ask you two questions

Q1: in the 3rd pic, there are 2 whits dots. how can we can we remove it

Q2: in the X-axis & Y -axis, how can we change the scalling of our own choice.

Thanks for all your help in advance.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)