radius of rod along its length in an image

10 views (last 30 days)
I have an image (attached) containing a rough rod. I am trying to find the values of radius along the rod's length. The true radius at the edge of the rod is known to me. What would be a good/ elegant way of doing this using matlab image processing tools?
  3 Comments
MAM09
MAM09 on 17 Feb 2022
Thank you for your suggestions. If the issues you mentioned were not there, how would I actually measure the radius in matlab? I know how to get dimensions from images of simple objects such as circles, but not sure how to do the same for radius along the length of this rod (at 1 mm intervals).
Image Analyst
Image Analyst on 17 Feb 2022
Just threshold to get the rod, then sum the binary image vertically. The sum is the diameter so divide it by 2.
mask = imbinarize(grayImage); % Assuming the mask looks good.....I have not tried it.
horizontalProfile = sum(mask, 1);
radii = horizontalProfile / 2;

Sign in to comment.

Accepted Answer

DGM
DGM on 17 Feb 2022
Edited: DGM on 17 Feb 2022
I ended up having to do a little manual touchup on the image (attached). It's still not a very good result, and the perspective probably makes the results meaningless, but it should serve as an example.
A = imread('wavyrod.jpg');
A = rgb2gray(A);
% crop it down to save time
A = imcrop(A,[0.5 962.5 4032 572]);
% try to flatten the image and smooth out any noise
Af = imflatfield(A,200);
Af = medfilt2(Af,[10 10]);
%imshow(Af)
% threshold the image and try to clean it up
m = Af>50;
m = bwareafilt(m,1);
m = imfill(m,'holes');
m = imopen(m,strel('disk',30,0));
figure
%imshow(m)
% omit the very end, since it's not a full diameter due to the viewing angle
startx = 3908;
m = m(:,1:startx);
% object width in pixels
profile = sum(m,1);
% assuming end diameter is known, that could be used for scaling
enddia = 25; % mm
scale_estimate1 = enddia/mean(profile(end-10:end)) % from the diameter
scale_estimate1 = 0.0596
% or the ruler could be used for scaling
% this is the distance beween the the lower 2 and 23 cm tickmarks on the ruler
% i just measured this manually
rulerspan = [3440 40]; % pixels [x y]
spanlen = 210; % mm
scale_estimate2 = spanlen/norm(rulerspan) % from the ruler
scale_estimate2 = 0.0610
% we now have two estimates of the scaling factor
% for this example, i'm going to assume the second has preferable accuracy
% note that this is reversed, aligning the visible end of the rod with zero
profilemm = profile * enddia/mean(profile(end-10:end));
% create scaled xdata for the profile
xposmm = linspace(scale_estimate2*numel(profilemm),0,numel(profilemm));
plot(xposmm,profilemm)
% now let's say we want to interpolate this xdata every 1mm
% start by getting new xdata
xposmm_new = 0:1:floor(xposmm(1));
% one approach would be to fit a spline to both interpolate and denoise
pp = fit(xposmm',profilemm','smoothingspline','smoothingparam',0.5);
profilemm_new = pp(xposmm_new);
figure
plot(xposmm_new,profilemm_new) % the new data at every mm
Obviously, the radius would be half that.
I don't feel confident to trust the ruler for scaling, since its length varies by about 12% across the image. In a better setup, using the ruler may be more effective.
  6 Comments
DGM
DGM on 28 Feb 2022
For the given image (or a similar setup), I would expect that you're right. The accuracy in getting the exact edge isolated varies due to the reflectivity of the object and the texture of the background. Some edges look exactly like the background since they're a reflection of it.
As I think I mentioned, I've resorted to backlighting parts on a light table to get good edge contrast, but I haven't done it with shiny round parts. Reflections might still be an obstacle, and I know my current digital camera does not like to behave with the flicker from the light table, so that might be another source of frustration.
I guess the brute simple way to do it would be to just smoke the part with lampblack and photograph it against a plain white background. That would be a bit of a mess, but it would be way easier.
MAM09
MAM09 on 1 Mar 2022
Thank you for your suggestions. The reflective nature of the rod is indeed an issue.

Sign in to comment.

More Answers (1)

yanqi liu
yanqi liu on 17 Feb 2022
yes,sir,may be ocr the number and use the scale information to get result,now we can see the ocr process.
im = imread('https://ww2.mathworks.cn/matlabcentral/answers/uploaded_files/896745/image.jpg');
bw = im2bw(im);
bwt = ~rot90(bw,2);
c = ocr(bwt,'CharacterSet','0123456789');
bts = [];
wts = [];
for i = 1 : length(c.Words)
if length(c.Words{i}) ~= 2 || c.WordBoundingBoxes(i,4) > size(bw,2)/40
continue;
end
bts(end+1,:) = c.WordBoundingBoxes(i,:);
wts{end+1} = c.Words{i};
end
[~,ind] = max(bts(:,1));
rect = bts(ind,:);
word = wts{ind};
figure; imshow(rot90(im,2),[]); hold on;
hold on; rectangle('position', rect, 'EdgeColor', 'r', 'LineWidth', 2)
text(rect(1),rect(2)-rect(4)/2,word,'Color','r','FontSize',20);
  1 Comment
MAM09
MAM09 on 17 Feb 2022
Edited: MAM09 on 17 Feb 2022
Hello, thanks for the response. But does the above method give me the radius at different points along the length of the rod? If yes, how? Sorry, I could not understand how the radius values of the rod can be found.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!