15 views (last 30 days)

Show older comments

HI everybody! I have a binary image matrix uploaded as A.mat:

White pixels correspond to 1, black regions correspond to 0. I would like to split the curve into left and right parts, something like the following:

and

Initially, I thought of finding the indices of midponts of elements having 1 at their positions, at each row. Using the indices, I can substitute ones on the left (and right) of the midpoints (at each row) using relational operators. Maybe there might be a better way to do this, but this method comes to my mind right now.

So I start from the bottommost row, and I keep on moving upwards. As evident from the A.mat figure (first figure), a row can have more than 2 cells having values one. To choose the appropriate cells for calculating midpoints at row "r", I compare the number of elements having one on left and right side of midpoint at row "r+1". I am attaching the code below:

clc;

clearvars;

load('A.mat');

[m,n] = size(A);

midpoint = zeros(m,n);

midpt_idx = zeros(m,1);

%%

A_sep = A;

for r = m:-1:1

k = find(A(r,:));

if size(k,2)==2

midpt_idx(r) = ceil((k(1)+k(2))*0.5);

elseif sum(A(r,1:midpt_idx(r+1))) < sum(A(r,midpt_idx(r+1)+1:end))

midpt_idx(r) = ceil((k(1)+k(2))/2);

elseif sum(A(r,1:midpt_idx(r+1))) > sum(A(r,midpt_idx(r+1)+1:end))

midpt_idx(r) = ceil((k(end-1)+k(end))/2);

elseif sum(A(r,1:midpt_idx(r+1))) == sum(A(r,midpt_idx(r+1)+1:end))

midpt_idx(r) = ceil((k(size(k,2)/2)+k((size(k,2)/2)+1))*0.5);

end

A_sep(r,midpt_idx(r)) = 2; % Midpoints have value 2 in their cells, I change this to 1 for checking solution by using imshow(A_sep)

end

An error is dispayed when execution comes at row 64. There is only one cell having 1 in row 64. For now, this error can be ignored (I think!).

This code runs correctly for some parts, but fails at other parts:

If you run the code along with A.mat file, starting from row 416, it gives correct results till row 278. At row 277, the code fails because there are a larger number of points adjacent to each other on right side, compared to left side of the midpoint index at row 279.

So, basically my method fails in these situations. Can you please help me with this? Maybe an advice for my code, or some other method which is better than what I am doing right now.

Thanks!

Matt J
on 14 Sep 2020

Edited: Matt J
on 14 Sep 2020

There is a small break in the curve which I assumed was supposed to indicate the desired dividing point between the right and left sides.

Under that assumption, I propose the following:

load A

[I,J]=find(A);

B=[I,J];

[b,j]=sortrows(B,[+1,-2]);

j=j(end);

C=regionprops(A,'PixelList');

for i=1:numel(C)

if ismember(flip(B(j,:)),C(i).PixelList,'rows')

C=fliplr(C(i).PixelList); break

end

end

Left=accumarray(C,1,size(A)); %the resultant images

Right=A&~Left;

Image Analyst
on 19 Sep 2020

Why not simply scan your image column by column with find() finding the topmost and bottommost row?

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

Start Hunting!