Detect longest line in an image

Hi,
I would like to detect the longest line in an image. Does anyone know how I can detect this line?
Regards,
Mihael

2 Comments

Could you upload a sample image?
Hi Akira,
This is the picture:
This picture is the area around a goal (soccer). The aim is to recognize a goal. So my thought is to find the longest line and then intersect with the two smalles lines. Then I would have the X and the Y coordinates of those intersections and know if the soccer ball goes through the line.

Sign in to comment.

 Accepted Answer

Image Analyst
Image Analyst on 12 Nov 2017
this looks like computer graphics. Therefore you will know the location of all the lines. You just have to see when "the ball" goes between columns 250 and 480 and the y coordinate is greater than 150. That is SO much simpler than trying to find the lines. Since you already know where the goal is, why not just use that information?

1 Comment

The aim is to detect the goalline from different angles. Therefore I will need to detect the line.

Sign in to comment.

More Answers (1)

Hi Mihael-san,
Thank you for sharing your picture. By detecting the bottom edge of the center black rectangle, I think you can detect the goal. Here is an example to do this.
% Read image
I = imread('Strafschopgebied.png');
Igray = rgb2gray(I);
% Extract the black area whose Area is close to that of BoundingBox
BW = imbinarize(Igray);
BW = imclearborder(~BW);
stats = struct2table(regionprops(BW));
ratio = stats.Area./(stats.BoundingBox(:,3).*stats.BoundingBox(:,4));
[~, idx] = max(ratio);
stats = stats(idx,:);
% Goal line (= bottom edge of the BoundingBox)
goalLine = [...
stats.BoundingBox(1),stats.BoundingBox(2)+stats.BoundingBox(4);
stats.BoundingBox(1)+stats.BoundingBox(3),stats.BoundingBox(2)+stats.BoundingBox(4)];
% Show the result
figure
imshow(I)
hold on
plot(goalLine(:,1),goalLine(:,2),'c','LineWidth',4)

12 Comments

Hi Akira,
Thank you for the example.
So this boundingBox searches the smallest rectangle that is completely black?
I also saw that there is a vertical and horizontal scale on the side. Is it possible that i get the X and the Y coordinates of the line? I have tried something by myself and used the following code:
% stats = regionprops(goalLine);
Unfortunately it didn't work quite well. I only got an array 483x1.
I have found the coordinates of the goalLine with the following code:
object = goalLine
bb = stats(object).BoundingBox;
bc = stats(object).Centroid;
rectangle('Position',bb,'EdgeColor','r','LineWidth',2)
plot(bc(1),bc(2), '-m+')
a=text(bc(1)+15,bc(2), strcat('X: ', num2str(round(bc(1))), ' Y: ', num2str(round(bc(2)))));
set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 12, 'Color', 'yellow');
end
Hi Mihael-san,
Using my sample code, the following will give the coordinates of the goalLine.
(x1,y1) = (stats.BoundingBox(1), stats.BoundingBox(2)+stats.BoundingBox(4))
(x2,y2) = stats.BoundingBox(1)+stats.BoundingBox(3), stats.BoundingBox(2)+stats.BoundingBox(4))
Hi Akira,
I have been working on this code to develop it in a Simulink function block, however, when I put the (x1,y1) code you gave me, it gives me an error. The given error is:
Error: File: Doellijn2.m Line: 18 Column: 4 Expression or statement is incorrect--possibly unbalanced (, {, or [.
The code is as follow:
if true
function y=Doellijn2(I)
%%%y size declareren
y=I;
% Foto goal inlezen
%I = imread('strafschopgebied.png');
Igray = rgb2gray(I);
% Het zwarte gebied eruit filteren dat dichtbij BoundingBox zit
BW = imbinarize(Igray);
BW = imclearborder(~BW);
stats = struct2table(regionprops(BW));
ratio = stats.Area./(stats.BoundingBox(:,3).*stats.BoundingBox(:,4));
[~, idx] = max(ratio);
stats = stats(idx,:);
% GoalLijn (= Onderrand van BoundingBox)
goalLijn = [...
stats.BoundingBox(1),stats.BoundingBox(2)+stats.BoundingBox(4);
stats.BoundingBox(1)+stats.BoundingBox(3),stats.BoundingBox(2)+stats.BoundingBox(4)];
(x1,y1) = (stats.BoundingBox(1), stats.BoundingBox(2)+stats.BoundingBox(4))
(x2,y2) = stats.BoundingBox(1)+stats.BoundingBox(3), stats.BoundingBox(2)+stats.BoundingBox(4))
% Presentatie van het resultaat
figure
imshow(I)
hold on
y=plot(goalLijn(:,1),goalLijn(:,2),'c','LineWidth',4)
end
Do you know how I can solve the error?
You need a ... line continuation indicator at the end of this line:
stats.BoundingBox(1),stats.BoundingBox(2)+stats.BoundingBox(4);
Mihael  Rakic
Mihael Rakic on 5 Dec 2017
Edited: Mihael Rakic on 9 Dec 2017
Hi, I have made the line continuation indicator. When I run this, I get the message "Too many output arguments".
Do you know why I get this message?
You can't use parentheses here:
(x1,y1) = (stats.BoundingBox(1), stats.BoundingBox(2)+stats.BoundingBox(4))
(x2,y2) = stats.BoundingBox(1)+stats.BoundingBox(3), stats.BoundingBox(2)+stats.BoundingBox(4))
You'd have to use brackets, but even that wouldn't work. Do it like this:
x1 = stats.BoundingBox(1);
y1 = stats.BoundingBox(2)+stats.BoundingBox(4);
x2 = x1 + stats.BoundingBox(3);
y2 = y1 + stats.BoundingBox(4);
Thank you. I don't get any errors with this code.
I only have one more question. Can I get these coordinates in a messagebox to check the values?
Yes, just use sprintf() and msgbox or helpdlg:
message = sprintf('The values are.....
uiwait(helpdlg(message));
message = sprintf('The values are:',x1)
uiwait(helpdlg(message));
I have used your code, but when I run it, I get only the message with "The values are:". It seems my variable will not show in the message?
Well of course you need to learn how to use sprintf. You didn't put in a format specifier! What is x1? Is it a double? If so use %f.
message = sprintf('The value is: %f',x1)
Is it an integer? If so use %d
message = sprintf('The value = %d',x1)
You really need to learn how to use all the percent format specifiers - it will help you immensely in the future.
thank you!

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!