Edge and corner detection using Hough Transform
Show older comments
Hello, I am trying to write a code that will ultimately detect and plot the corners of a PCB as well as outline the two sides and top edge shown in the camera view. I am trying to do this using a Houghs Transform and line identification. I want to outline the three edges shown in the camera view ( two sides and top edge) and plot the intersections of the top line with the two side lines, marking the top two corners of my PCB. I Have a code that does a simple line detection based off MATHWORKs documentation. I will also share the edge detected picture as well as the lines overlayed on the original camera view. Can anyone explain why only the right edge is being detected, and steps i can take to ensure the other that the other two edges (top and left side) are to be detected and outlined as well?
:
clc; clear all; close all
%% Initialize Cameras
camList = webcamlist; % camera list, figure which is top view
cam = webcam(3);
cam.Resolution='1280x960';
%% set parameters
filter=105; %Intensity of pixel to base filter on; originally at 100
line_num=3;
fill_gap=200;
parameters=[filter,line_num,fill_gap]; % detection parameters
%% Take image
I2=snapshot(cam);
imshow(I2)
%% Turn image to grayscale
I0=rgb2gray(I2);
imshow(I0)
%% Index pixels that are lighter than filter value
index=find(I0<parameters(1));
%% Make Matrix of same size as original picture w/ all black
Ix=zeros(size(I0));
%% Paste pixels that passed filter onto the all black matrix
Ix(index)=I0(index);
imshow(Ix)
%% Detect Edges of newly created, whited out image
I3 = edge(Ix,'Roberts');
imshow(I3)
%% Houghs Transform
[H, theta, rho] = hough(I3)
P = houghpeaks(H,parameters(2),'threshold',ceil(0.7*max(H(:))));
%% plot peaks
imshow(H,[],'XData',theta,'YData',rho,'InitialMagnification','fit');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
plot(theta(P(:,2)),rho(P(:,1)),'s','color','white');
%%
lines = houghlines(I3, theta, rho, P,'FillGap',parameters(3)); %info about the lines extracted
%%
figure, imshow(I2), hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
end
1 Comment
Sam Blake
on 27 Jul 2023
Accepted Answer
More Answers (1)
Image Analyst
on 27 Jul 2023
The whole approach is wrong. You should just do shape detection. Just
- threshold
- find centroid
- find boundary coordinates
- find distance of centroid to all boundary coordinates
- Use findpeaks to find peaks of the distances plot.
In short:
mask = grayImage > threshold % Or use Color Thresholder
mask = brareafilt(imfill(mask, 'holes'), 1); % Take largest blob.
props = regionprops(mask, 'Centroid'); % Find centroid.
boundary = bwboundaries(mask);
boundary = boundary{1};
xb = boundary(:, 1);
yb = boundary(:, 2);
distances = sqrt((xb - props.Centroid(1)).^2 + (yb - props.Centroid(2)) .^ 2);
plot(distances, 'b-');
grid on
[peakValues, peakIndexes] = findpeaks(distances);
and so on. I'm sure you can finish it. Let me know if you can't, and why you want the coordinates of the edges (what will that enable you to do?).
The peaks are the corners of the board. See attached demos.
8 Comments
Sam Blake
on 27 Jul 2023
Image Analyst
on 28 Jul 2023
@Sam Blake aha! Now we're getting somewhere. What we have is:
So you really want to know the centroid of the gold pads and you thought getting the edges was a step towards that. So do you want to know
- the centroid of the gold pads in pixel coordinates?
- Or the shortest distance of the pad to the closest edge of the PCB?
In case 1 you can use some algorithm to segment the gold pads and then use regionprops. In case 2, you'll have to do case 1 and then call bwboundaries on the entire PCB and then use sqrt() and min() to find the boundary point closest to each centroid, and then multiply by a scaling factor if you need the distance in real world units such as millimeters.
Sam Blake
on 28 Jul 2023
Sam Blake
on 28 Jul 2023
Image Analyst
on 31 Jul 2023
Image Analyst
on 31 Jul 2023
Moved: Matt J
on 1 Aug 2023
Sorry for the delay I was busy. I still think your whole approach is wrong, especially so after reading your comment to me. But we really need to know if your extruder/robot is using the same coordinate system as your camera and image. If it is, you don't need the edges of the PCB or the corners of it. You just need to find the solder pads, which none of this does. However if the extruder robot operates on it's own coordinate system, we're going to have to convert the pixel coordinates of the pads into extruder coordinates. And we'd need to know if the robot has a fixed coordinate system with repect to the lab countertop, mounting jig or whatever, or if it adjusts it's coordinate system to the location of the PCB. Like the PCB might be anywhere but the upper left corner is always (0,0) millimeters as far as the robot is concerned.
Categories
Find more on Computer Vision with Simulink in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


