Edge and corner detection using Hough Transform
17 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Sam Blake
el 27 de Jul. de 2023
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?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1443822/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1443827/image.png)
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
Respuesta aceptada
Matt J
el 28 de Jul. de 2023
Editada: Matt J
el 28 de Jul. de 2023
Because you are detecting edges/corners of a simple convex polygon, I would recommend downloading pgonCorners,
load Image
[r,g,b]=imsplit(Image);
BW=g>120 &b>90 ;
BW=bwareafilt(imclose(BW,ones(5)),1);
p=polyshape(fliplr(pgonCorners(BW,4)));
imshow(Image);
hold on
plot(p,'FaceColor','none','EdgeColor','m','LineWidth',5)
hold off
3 comentarios
Matt J
el 28 de Jul. de 2023
Editada: Matt J
el 28 de Jul. de 2023
I doubt it, but you could use pgonCorners to find the corners of the thick-bordered rectangle at the bottom of the image from the BW image developed below. This will give you enough landmarks to unravel the geometry of the entire PCB, using fitgeotrans or fitgeotform2d.
load Image
[r,g,b]=imsplit(Image);
BW=g>120 &b>90 ;
BW=bwareafilt(imclose(BW,ones(5)),1);
box=imclose(r>220 & b>220 & g>220 & BW, ones(7));
z=box(end,:);
box(end,:)=1;
box=bwareafilt(imfill(box,'holes'),1);
box(end,:)=z;
imshow(box)
Más respuestas (1)
Image Analyst
el 27 de Jul. de 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 comentarios
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!