필터 지우기
필터 지우기

Skeletonisation until edges of a beam

조회 수: 7 (최근 30일)
Annael Sort-Montenegro
Annael Sort-Montenegro 2024년 5월 21일
댓글: Image Analyst 2024년 5월 22일
Hello MATLAB community,
I am doing some image processing with MATLAB and some issues with my coding. I just like to warn you that I am very new at coding and MATLAB so I apologise in advance for my low level and I would be very glad to have some help as I have hitted a wall, and can't find a solution to my problem.
Context: I have a video of beams, that move right to left over time. The base is fixed, only the beam moves. I converted the video to images, and my MATLAB program is going through the image file and treating every image in it. Here are two image examples:
and
I want to measure the following things:
a. The coordinates between the 2 extremities of the beam (length of the beam, without its base), let's call them A and B.
b. The bending deformation E (L0-Lt/L0 *100), obtained by calculating the distance between A and B, called Lt.
c. the curvature of the beam (1/R), obtained by extracting the radius R of a circle fitting the curvature of the beam.
d. The angle between a vertical line passing through A, and the line AB.
What I have done so far:
My approach has been to transform my image into an rgbimage, then binaryImage, then have the complementary image, apply some modifications/corrections to the image, and then skeletonize it. And from then, I extract the coordinates of A and B, the distance between A&B (Lt), the radius of the beam R, and the angle between A&B (T).
My main issue is the skeletonisation. Because my beam is quite thick, it shortens up too much my beam, and in an inconcistent manner. So then my results are completly wrong. Here is an image of the different images and operation I have done and the result:
So as you can see, the length is shorter. I would like to have a skeleton that meets the edges of the beam to calculate the end points.
I have tried "bwskel(BW, 'MinBranchLength', 30)" and "bwmorph(BW, 'thin', inf)", and this: https://uk.mathworks.com/matlabcentral/fileexchange/11123-better-skeletonization. But the problem remains the same. I have tried regionpropos, but the major axis they return is too long, I have tried bwferet(), but the maxlength is in diagonal of the beam... I have running out of ideas.
Problem: So I guess my main problem is how can I get a skeletonisation that goes to the edges of the beam?
Here is my code:
for i = TrackingStart:TrackingEnd
FileRGB(:,:,i) = rgb2gray(imread(IMG)); % Convert to grayscale
croppedRGB = FileRGB(y3left:y3right, x3left:x3right, i);
binaryImage = imbinarize(croppedRGB, 'adaptive', 'ForegroundPolarity','dark','Sensitivity', 0.50);
out = nnz(~binaryImage);
while out <= 4300 % Change threshold if needed
for j = 1:50
sensitivity = 0.50 + j * 0.01;
binaryImage = imbinarize(croppedRGB, 'adaptive', 'ForegroundPolarity', 'dark', 'Sensitivity', sensitivity);
out = nnz(~binaryImage);
if out >= 4325
break; % Exit the loop if the condition is met
end
end
end
% Create a line Model
BW = imcomplement(binaryImage);
BW(y1left:y1right, x1left:x1right) = 1; % there is always sample at the junction area (between beam and base)
BW(y2left:y2right, x2left:x2right) = 0; % Always = 0 if no sample here
BW = bwmorph(BW, 'close', Inf);
BW = bwmorph(BW, 'bridge');
BW = bwareafilt(BW, 1);
s = regionprops(BW, 'FilledImage');
BW = s.FilledImage;
BW = bwskel(BW, 'MinBranchLength', 30);
endpoints = bwmorph(BW, 'endpoints');
[y_end, x_end] = find(endpoints == 1);
%Degree of bending deformation method
Lt = sqrt(power(x_end(1)-x_end(2),2)+power(y_end(1)-y_end(2),2));
if x_end(2) > x_end(1)
Lt = -Lt;
end
Lstore(i) = Lt;
%Curvature method
[row_dots_cir, col_dots_cir, val] = find(BW == 1);
[xc(i),yc(i),Rstore(i),a] = circfit(col_dots_cir,row_dots_cir);
%Angle method
slope_endpoints = (x_end(1) - x_end(2)) / (y_end(1) - y_end(2));
angle_radians = atan(slope_endpoints);
angle_degrees = rad2deg(angle_radians);
if x_end(2) > x_end(1)
angle_degrees = -angle_degrees;
end
Tstore(i) = angle_degrees;
i
end

답변 (1개)

Image Analyst
Image Analyst 2024년 5월 21일
Since the base/box is in a fixed permanent position, you can simply measure that location once and you have that point for all frames. You can use impixelinfo to find it.
As for the beam, you might be able to just use thresholding instead of edge detection. Is there anyway you can improve the contrast of the scene, like with lighting or camera lens filters or geometry (move light or camera)?
  댓글 수: 2
Annael Sort-Montenegro
Annael Sort-Montenegro 2024년 5월 21일
Hello,
Thank you very much for taking the time to answer! Yes, I was actually thinking about getting point A this way...
As for the beam, unfortunatly I cannot get an better constrast, this is the best images/videos I can currently get. Isn't imbinary() that I am applying to my code already a thresholding method?
Thank you very much again!
Kind regards,
Image Analyst
Image Analyst 2024년 5월 22일
It looks like the images you posted have horrendous JPG block artifacts due to extreme over compression. Did you JPG these images? If so, can you attach the original uncompressed images?
imbinary is a thresholding routine but the automatic threshold it picks may not be optimal. If you have good control over your image intensity and exposure then I high recommend you use a fixed threshold.
Try using the Color Thresholder on the Apps tab and use HSV or LAB color space to set the V or L threshold respectively.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Image Processing Toolbox에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by