How to find intersection coordinates of node points in truss image?

3 次查看(过去 30 天)
Hello, I would like to know the way to find coordinate points (x,y) of nodes in truss image. I give an example of image. In that image, I will get only six edge points and I will exclude two crossed points in the middle. How can I find the coordinate points in that figure?

采纳的回答

Cedric
Cedric 2017-9-29
编辑:Cedric 2017-10-2
If you are always dealing with regular trusses, your best option may be to detect vertical and horizontal edges by summation over dimensions 1 and 2:
img = im2bw(imread('TrussExt1.png')) ;
subplot(1,2,1) ; plot(sum(img,1)) ; grid('on') ; title('Sum over rows') ;
subplot(1,2,2) ; plot(sum(img,2)) ; grid('on') ; title('Sum over columns') ;
Getting the relevant nodes coordinates hence just means getting these mins:
>> c = find(sum(img, 1) < size(img, 1)/2)
c =
21 22 23 183 184 185 346 347 348 508 509 510 671 672 673
we see that, as the horizontal and vertical lines are 3 pixels wide, we get three close numbers per min, and we can take the "middle ones" as follows:
>> c(2:3:end)
ans =
22 184 347 509 672
Putting all that together we get:
img = im2bw(imread('TrussExt1.png')) ;
c = find(sum(img, 1) < size(img, 1)/2) ;
c = c(2:3:end) ;
r = find(sum(img, 2) < size(img, 2)/2) ;
r = r(2:3:end) ;
[R, C] = meshgrid(r, c) ;
imshow(img) ;
hold('on') ;
plot( C(:), R(:), 'rx', 'MarkerSize', 10, 'LineWidth', 3 ) ;
If you are not always dealing with regular trusses, your best option may be to detect the diagonal cross nodes and to build a grid based on them, using the position of the outer boundaries found by taking the first and last mins using the approach developed above.
Here is an example, where we spot the nodes that you don't want to get:
img = im2bw(imread('TrussExt2.png')) ;
ker = [0,0,0,1,1,1,1,1,1,1,0,0,0; ...
1,1,0,0,0,1,1,1,0,0,0,0,1; ...
1,1,1,0,0,0,1,0,0,0,1,1,1; ...
1,1,1,1,0,0,0,0,0,1,1,1,1; ...
1,1,1,1,0,0,0,0,0,1,1,1,1; ...
1,1,1,0,0,0,0,0,0,0,1,1,1; ...
1,1,0,0,0,1,1,1,0,0,0,1,1; ...
0,0,0,0,1,1,1,1,1,0,0,0,0] ;
ker = 10 * (1 - 2*ker) ; % {0,1} -> {10,-10}.
ker = rot90(ker, 2) ;
cv = conv2( 1-img, ker, 'same' ) ;
[r,c] = find(cv > 0.7*max(cv(:))) ;
figure() ;
imshow(img) ;
hold('on') ;
plot(c, r, 'ro', 'MarkerSize', 10, 'LineWidth', 3) ;
Applied to TrussExt2.png attached to my answer, we get:
which shows that it is working pretty well. Depending the quality of the image, we may have to filter/cluster the output of FIND, but in this case we don't. I'll stop here but with a little extra work, you can find the nodes of the "multi-scale" rectangular grid that corresponds to these "cells centers".
Another approach could consist in performing more shape-specific convolutions, in order to target the 6 or 7 possible geometries of interest. As the width of the non-diag. lines is 3 pixels, it could be done as follows:
img = im2bw(imread( 'truss.JPG')) ;
imshow(img) ;
hold('on') ;
np = 3 ; B = ones(np) ;
kernels = {[-B,-B,-B;-B, B, B;-B, B, B], ... % sym. lower right
[-B,-B,-B; B, B, B; B, B, B], ... % sym. lower middle
[-B,-B,-B; B, B,-B; B, B,-B]} ; % sym. lower left
kernels = [kernels, cellfun(@flipud, kernels, 'UniformOutput', false)] ;
nKer = numel(kernels) ;
colors = jet(nKer) ;
for kId = 1 : nKer
cv = conv2(1-2*img, kernels{kId}, 'same') ;
[r, c] = find(cv == max(cv(:))) ;
plot(c, r, 'x', 'Color', colors(kId,:), 'MarkerSize', 20, 'LineWidth', 3) ;
end
If you have many nodes of each type/shape though, you may need to set a tolerance ( cv >= tol*max(cv(:)) ) and aggregate close points (which brings us back to clustering).
Or, if you know the number of relevant points in advance, you can reduce you problem to a peak identification problem or a clustering problem:
img = im2bw(imread('truss.JPG')) ;
n = 3 ; B = ones( n ) ; ker = [B, 10*B, B; 10*B, 10*B, 10*B; B, 10*B, B]/(3*n)^2 ;
cv = conv2(1-img, ker, 'same') ;
surf(cv)
where you see that all straight lines and diagonal crosses are below the level of the 6 relevant nodes. I defined the weights of the blocks in the kernel for that purpose. The condition is that elements of the "high" blocks are greater than twice the value of elements of the "low" blocks, and elements of the "low" blocks must be positive (I picked 10 and 1 as weights of B to be on the safe side).
  9 个评论
ayemoe aung
ayemoe aung 2017-10-10
Thank you so much. I have learnt a lot and my problem is solved from your answer.

请先登录,再进行评论。

更多回答(1 个)

Image Analyst
Image Analyst 2017-9-29
编辑:Image Analyst 2017-9-29
Call bwmorph(BW, 'skel', inf) followed by bwmorph(bw, 'branchpoints') followed by find(). See attached demo.

类别

Help CenterFile Exchange 中查找有关 Structural Analysis 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by