Edge and corner detection using Hough Transform

17 次查看(过去 30 天)
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 个评论
Sam Blake
Sam Blake 2023-7-27
Also, here is an example image from the camera so that you can reproduce the exact results:

请先登录,再进行评论。

采纳的回答

Matt J
Matt J 2023-7-28
编辑:Matt J 2023-7-28
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 个评论
Matt J
Matt J 2023-7-28
编辑:Matt J 2023-7-28
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)
Sam Blake
Sam Blake 2023-7-31
Thats the route i was originally going to go, thanks a lot. you helped a ton, sorry for the delay on accepting

请先登录,再进行评论。

更多回答(1 个)

Image Analyst
Image Analyst 2023-7-27
The whole approach is wrong. You should just do shape detection. Just
  1. threshold
  2. find centroid
  3. find boundary coordinates
  4. find distance of centroid to all boundary coordinates
  5. 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 个评论
Sam Blake
Sam Blake 2023-7-31
移动:Matt J 2023-8-1
No need to apologize. So my extruded is horizontally fixed on a rotary stage, it only rotates about the z axis if x and y is looking straight down on the table. The PCB is attached to a fixed template that can move in the z and x direction, which we’ll say is alongside the rotary stage and perpendicular to the extruder. The coordinates for the stage movement is based off of the motion controller specific software but it will be in mm or steps, which I’ve already made conversions for. As I said before this is already completed work for the most part as it’s based off of a published dissertation and a previously working machine, I’m just re-working it with a different motion controller and PCB. Im going to link my final product from my image processing that I got today. I appreciate your insights as I’m going to be looking through the demo codes and trying to make more Sense of them in the future. Looking through your profile, I’m sure if this was your project you’d finish it in a half hour instead of a few weeks like me.

请先登录,再进行评论。

Community Treasure Hunt

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

Start Hunting!

Translated by