I have image with black background and white lines. How to find co-ordinate (x,y) of end points of white lines on that image?
Show older comments
Accepted Answer
More Answers (2)
Image Analyst
on 14 Dec 2015
To find where the lines branch, use
branchpoints = bwmorph(binaryImage, 'branchpoints');
[rows, columns] = find(branchpoints);
You can find the endpoints where a single line hits the edge of the image using the 'endpoints' option instead of branchpoints.
endpoints = bwmorph(binaryImage, 'endpoints');
[rows, columns] = find(endpoints);
2 Comments
LAKSHMANAN ADAIKKAPPAN
on 15 Dec 2015
Image Analyst
on 15 Dec 2015
This line does it:
[rows, columns] = find(branchpoints);
Why do you think it does not?
John BG
on 15 Dec 2015
Hi, Perhaps LAKSHMANAN ADAIKKAPPAN does not have the Image Toolbox. I tried with R2012 image toolbox and your code did not find a single node.
Let me suggest a different approach:
1. grid the image with enough resolution so that there is only one node per image block
2. recur: repeat only on the blocks where nodes have been found
% BW: image that looks like binary,
% but 1.- values are [0:255] not [0 1] 2.- has 3 layers, slightly misaligned
BW=imread('binary cells map.jpg')
% .jpg .png files have 3 layers, haven't found a single BW image in .jpg slightly, ever
% always missaligned, even fill all black grap a white-white pend and draw a line
% has to do with compression and perhaps OS embedding data in the image with slight
% colour variations,never mind
BW=BW(:,:,1) % not a standard way to clean image supposed to be BW, but as starter will do
[BWy,BWx]=size(BW)
% augenblick: choose a block size to split your image that will roughly catch 1 or no nodes, % I say split 7 for Y, 5 for X
Amount_Blocks_x=7; Amount_Blocks_y=5
blocky=floor(linspace(1,BWy,Amount_Blocks_y));blockx=floor(linspace(1,BWx,Amount_Blocks_x))
% With 7 5 i can see a couple blocks where there is more than one crossing take place
figure(1);imshow(BW);xlabel('X');ylabel('Y');hold all
for i=2:1:Amount_Blocks_x-1 plot([blockx(i) blockx(i)],[0 BWy],'r'); end
for i=2:1:Amount_Blocks_y-1 plot([1 BWx],[blocky(i) blocky(i)],'r'); end
% so increase blocks resolution a bit, meaning decrease blocks size:
Amount_Blocks_x=9; Amount_Blocks_y=7
blocky=floor(linspace(1,BWy,Amount_Blocks_y));blockx=floor(linspace(1,BWx,Amount_Blocks_x))
figure(2);imshow(BW);xlabel('X');ylabel('Y'); % same as ax.XLabel.String='X';ax.XLabel.String('Y')
hold all
for i=2:1:Amount_Blocks_x-1 plot([blockx(i) blockx(i)],[0 BWy],'r'); end
for i=2:1:Amount_Blocks_y-1 plot([1 BWx],[blocky(i) blocky(i)],'r'); end
% increase resolution further
Amount_Blocks_x=12; Amount_Blocks_y=12
blocky=floor(linspace(1,BWy,Amount_Blocks_y));blockx=floor(linspace(1,BWx,Amount_Blocks_x))
figure(3);imshow(BW);xlabel('X');ylabel('Y'); hold all
for i=2:1:Amount_Blocks_x-1 plot([blockx(i) blockx(i)],[0 BWy],'r'); end
for i=2:1:Amount_Blocks_y-1 plot([1 BWx],[blocky(i) blocky(i)],'r'); end
% Now I am confident to say only that all blocks with nodes or crossings have 3
% or 4 sides crossed by lines Let's spot blocks containing nodes
Ny=floor(mean(diff(linspace(1,BWy,Amount_Blocks_y))));
Nx=floor(mean(diff(linspace(1,BWx,Amount_Blocks_y))))
% Nxy % blocks size simplified to non-overlapping and squares
mark_block=zeros(Amount_Blocks_y,Amount_Blocks_x)
block_with_crossings_x=0;block_with_crossings_y=0
for i=1:1:numel(blockx)-1 % x sweep
for j=1:1:numel(blocky)-1 % y sweep
bw_block=BW([blocky(j):1: blocky(j+1)],[blockx(i):1:blockx(i+1)])
bwblk_top_line=bw_block(1,:) % top line
bwblk_bot_line=bw_block(end,:)' % bottom line
bwblk_left_line=bw_block(:,1) % left side line
bwblk_right_line=bw_block(:,end)' % right side line
tp_ln_ref=find(bwblk_top_line>250)
bt_ln_ref=find(bwblk_bot_line>250)
lft_ln_ref=find(bwblk_left_line>250)
rght_ln_ref=find(bwblk_right_line>250)
% catch blocks with 4 sides or 3 sides crossed by line
if ((numel(tp_ln_ref)>0)&&(numel(bt_ln_ref)>0)&&...
(numel(lft_ln_ref)>0)&&(numel(rght_ln_ref)>0)) mark_block(i,j)=1; end
if ((numel(bt_ln_ref)>0)&&(numel(lft_ln_ref)>0)&&...
(numel(rght_ln_ref)>0)) mark_block(i,j)=1; end
if ((numel(tp_ln_ref)>0)&&(numel(lft_ln_ref)>0)&&...
(numel(rght_ln_ref)>0)) mark_block(i,j)=1; end
if ((numel(tp_ln_ref)>0)&&(numel(bt_ln_ref)>0)&&...
(numel(rght_ln_ref)>0)) mark_block(i,j)=1; end
if ((numel(tp_ln_ref)>0)&&(numel(bt_ln_ref)>0)&&...
(numel(lft_ln_ref)>0)) mark_block(i,j)=1; end
% it could still be u turns hitting all sides but lines not crossing: recur,
% smaller blocks inside blocks blocks that flagged
end
end
% find coordinates of blocks containing node
spot_mark_block=find(mark_block>0);[I,J]=ind2sub(size(mark_block),spot_mark_block)
% count them all
numel(mark_block(mark_block>0))
% crossings_x(1)=[];crossings_y(1)=[]
% imshow(BW)
% hold all
% plot(crossings_x,crossings_y,'og')
If you find this to be the correct approach, I challenge you to increase resolution
1.- to find possibly missed crossings, for instance 2 diagonal parallels would hit all 4 sides yet if the block is too big it would give a false node 2.- achieve accurate coordinates of the all nodes found
I also tried for each block to calculate 2 lines and find possible intersections, but reached time limit for this question. It would approximate anyway, recurring with smaller blocks is the best way, and without the Image Toolbox.
If you choose to develop this solution let me know about your progress.
1 Comment
LAKSHMANAN ADAIKKAPPAN
on 16 Dec 2015
Categories
Find more on Neighborhood and Block Processing in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
