How to detect number of bends of racing track starting from image

4 views (last 30 days)
Hello everybody,
I need to detect some features (such as number of bends, number of straights, etc...) of a racing circuit starting from its image.
I'm starting from an image like that:
Obviously, i'm interessed only on the "red lines", so i did some preprocessing and I managed to get the skeleton of the circuit:
Now, starting from the skeleton of the circuit, I'm interessed to extract some features (such as number of bends, number of straights, average radius of curvature, etc...) (I know the total length of the circuit).
I tried to extract the number of bends from the first image, counting the "yellow curve identifiers", but i would like to extract this information from the skeleton, in order to detect the average radius of curvature, the total bend length etc... .
I tried with the Hough transformation but i didnt reach the desired result.
Thanks in advance

Answers (1)

Image Analyst
Image Analyst on 3 Dec 2022
What I'd do is to get the (x,y) coordinates of the curve in order. You can do this with bwboundaries(). Then define a window size that you will use to slide along the curve fitting a quadratic to. You'll need to extend the endpoints by the window width so that you can get good curvatures on the first few points and the last few points. Now march along the curve fitting a certain number of points (like 7 if the window width is 7) to a quadratic with polyfit
coefficients = polyfit(xWindow, yWindow, 2);
Now you can get the curvature of the central point by taking the derivative and evaluating it at the center
% Derivative = 2 * coefficients(1) * x + coefficients(2)
curvature(k) = 2 * coefficients(1) * xWindow(4) + coefficients(2) % For a window width of 7, 4 is the middle point
k is the overall index of where you are along the whole curve, so if you have 2000 points, k will range from 1 to 2000 (ignoring the edge effects).
See if you can program up this algorithm. Here's a start (untested)
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
imshow(originalImage); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('%d Outlines, from bwboundaries()', numberOfBoundaries);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
windowWidth = 7 % An odd number.
centerIndex = ceil(windowWidth/2) % 4
centerIndex1 = centerIndex - 1; % 3
numPoints = numel(x);
x = [x(end-centerIndex1); x; x(1:centerIndex1)] % Pad endpoints.
y = [y(end-centerIndex1); y; y(1:centerIndex1)] % Pad endpoints.
for k = centerIndex : length(x) - centerIndex1
xWindow = x(k:k+windowWidth);
yWindow = x(k:k+windowWidth);
coefficients = polyfit(xWindow, yWindow, 2);
%Now you can get the curvature of the central point by taking the derivative and evaluating it at the center
% Derivative = 2 * coefficients(1) * x + coefficients(2)
curvature(k-centerIndex1) = 2 * coefficients(1) * xWindow(centerIndex) + coefficients(2) % For a window width of 7, 4 is the middle point
end
plot(curvature, 'b-', 'LineWidth', 2);
grid on;
xlabel('index')
ylabel('Curvature')
  3 Comments
Jeff
Jeff on 3 Dec 2022
Hi, thanks for your answer.
I like the idea to consider a sliding window over the boundaries in order to calculate the curvature, but i have some question.
How can i determine the corrispondence between the curvature and the bend? We are getting coordinates of the curve "in order". But what order? I would like to indicate on the original photo the position of the curves.
The result of the program is this figure (i had to adjust the end values of the last for loop because of a "Index exceeds the number of array elements" error, i think there is some incorrectness with the padding)
It is normal that there are some negative curvature?
What I understood is that the points on the graph correspond to the curvature of the points in the sliding window each time. Therefore, points other than 1 indicate that there is a curve with that specific curvature.
Thanks for your support. :)
Image Analyst
Image Analyst on 3 Dec 2022
Jeff, if you get the coordinates from bwboundaries, they will be in order. Not sure which is "point 1" but it doesn't really matter because you will be getting the row in the array that has high curvature and that row corresponds to the (x,y) position if you use the same row in the x and y vectors.
The curvature is positive or negative depending on which way the quadratic bends, as you know. I probably don't need to tell you but if a quadratic has the vertex on the bottom then the coefficient of x^2 is positive while if the quadratic has the apex at the top then that coeficient would be negative. To get the curvature regardless if the curve bulges out (a peninsula) or bows in (a bay), you'd want to take the absolute value of the curvature.
If you need more help, attach the binary skeleton image, and your code where you tried to use my algorithm.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!