MATLAB Answers

0

Detect orientation of screw image

Asked by Ang Xian Jia on 10 Nov 2019 at 9:15
Latest activity Edited by Ang Xian Jia on 11 Nov 2019 at 0:50
The screw as shown in the image is not completely horizontal. I would like to detect the orientation of screw and form a new image that can make sure that the screw is completely horizontal. Is there a way to do that?
20.bmp

  2 Comments

KSSV
on 10 Nov 2019 at 9:23
Read the pixels...get the coordinates...use polyfit to fit a straight line, get the slope and try to rotate the coordinates to make slope zero.
Ang Xian Jia on 10 Nov 2019 at 9:46
pixelgraph.png
This is the pixels I read from top part of the screw. May I know what you mean by " try to rotate the coordinates to make slope zero" ? Thanks

Sign in to comment.

2 Answers

Answer by Stephan
on 10 Nov 2019 at 11:23
Edited by Stephan
on 10 Nov 2019 at 11:49
 Accepted Answer

Using this script lets you know which angle to rotate. Then use this information to rotate the image and check the orientation again:
%% read image and find points that should lie on a straight line
img = rgb2gray(imread('20.bmp'));
res = detectHarrisFeatures(img,'MinQuality', 0.1, 'ROI', [1 386 762 20]);
% Extract coordinates of the points
x_vals = double(res.Location(:,1));
y_vals = double(res.Location(:,2));
% find slope and offset of the line formed by the points and use arctan to
% estimate the angle the srew is different from horizontal orientation
slope_and_offset = polyfit(x_vals, y_vals,1);
angle = atand(slope_and_offset(1));
fprintf('\nThe screw is oriented %.5f degree to the horizontal.\n', angle)
%% rotate the image
img_rot = imrotate(img,angle);
% search points again on rotated image
res_new = detectHarrisFeatures(img_rot,'MinQuality', 0.1, 'ROI', [1 395 762 10]);
% Extract coordinates of the points
x_vals_rot = double(res_new.Location(:,1));
y_vals_rot = double(res_new.Location(:,2));
% find slope and offset of the line formed by the points and use arctan to
% estimate the angle the srew is different from horizontal orientation
slope_and_offset_rot = polyfit(x_vals_rot, y_vals_rot,1);
angle_rot = atand(slope_and_offset_rot(1));
fprintf('\nThe screw is oriented %.5f degree to the horizontal after rotation.\n\n', angle_rot)
%% plot results
subplot(1,2,1)
hold on
title('Original Image')
imshow(img)
scatter(res.Location(:,1),res.Location(:,2),'or')
hold off
subplot(1,2,2)
hold on
title('Corrected Image')
imshow(img_rot)
scatter(res_new.Location(:,1),res_new.Location(:,2),'ob')
hold off
The keypoint is to define the ROI to the algorithm, so that you only detect points that are valid to reach high presicion.

  4 Comments

Show 1 older comment
Stephan
on 10 Nov 2019 at 15:12
If we apply the same operation on both sides as i did for the lower part, it should be able to estimate the center line, even if the screw would be conic.
Ang Xian Jia on 10 Nov 2019 at 15:30
Hi Sir Stephan, u means that I should take the average of two polyfit line (top and bottom) to form the centerline?
Stephan
on 10 Nov 2019 at 15:39
Yes, this is what i would try to do.

Sign in to comment.


Answer by Image Analyst
on 10 Nov 2019 at 15:46

An alternative way is to use the radon transform. Basically the radon transform makes projections along a list of angles that you specify. Then you can look at the projections image to identify which angle (angles are columns in the image) is the best one (it will be the column where the brightest value is).
See attached demo where I rotate the football demo image.
00_Screenshot.png

  3 Comments

Ang Xian Jia on 11 Nov 2019 at 0:18
Hi Image Analyst, why the code would not work if I use the image below for the code? Do I need to make any modification? Why we are extracting only the red channel? The reason I'm using different kind of image is because I'm curious whether the code will always orientate different image to horizional position or not. I'm still trying to understand the codes given. Thanks.
Image Analyst
on 11 Nov 2019 at 0:29
I extracted the red channel because radon() works on a grayscale image, not a color RGB image. You might either call rgb2gray() or use the green channel (since cameras have twice as many green pixels as red or blue pixels).
You have an image capture problem. Bad illumination, bad background, bad lens, bad geometry.
You need to
  1. Use a uniform white lightbox to create a silohette image.
  2. Use a telecentric lens so magnification does not change with distance from lens.
  3. Aim camera normal to screw axis, not at an angle like you have.
Ang Xian Jia on 11 Nov 2019 at 0:49
Yeah I understand that. My uni has only limited and old equipment for machine vision course yet I must have a clear screw image. I will still try to recapture the image. Thanks for the suggestion.

Sign in to comment.