# How to create a centerline between lines in image?

12 Ansichten (letzte 30 Tage)
Dekel Mashiach am 3 Mai 2022
Kommentiert: Image Analyst am 8 Mai 2022
Hi
I'm trying to convert the image to binary and create a centerline between the two white lines. Can someone please help me?
clc;
clearvars;
close all;
workspace;
if ndims(grayImage) == 3
% It's color. Take the red channel.
grayImage = grayImage(:, :, 1);
end
figure
imshow(grayImage, []);
impixelinfo;
mask = logical(grayImage > 140 & grayImage < 255);
mask = bwareafilt(mask, 2); % Make sure we have only two lines.
figure
line1 = ismember(labeledImage, 1);
line2 = ismember(labeledImage, 2);
% Get rows and columns of each line.
[r1, c1] = find(line1);
[r2, c2] = find(line2);
for k = 1 : length(r1)
distances = ((r1(k) + r2) / 2);
[minDistance, index] = min(distances);
% Find the midPoint
midX = mean([c1(k), c2(index)]);
midY = mean([r1(k), r2(index)]);
% Optionally drop a marker there
hold on;
plot(midX, midY, 'g.', 'MarkerSize', 10);
end
% Need to add a small amount of noise to x to make the values unique.
midX = midX + 0.001 * rand(size(midX));
midY = midY + 0.001 * rand(size(midY));
% Interpolate x and y to make sure there are no gaps.
kVec = 1 : length(midX);
kFit = linspace(1, kVec(end), 10000);
xFit = interp1(kVec, midX, kFit, 'linear');
yFit = interp1(kVec, midY, kFit, 'linear');
% Remove duplicate values
xy = unique(round([xFit(:), yFit(:)]), "rows");
% Extract individual x and y.
midX = xy(:, 1);
midY = xy(:, 2);
hold on;
plot(midX, midY, 'g.', 'MarkerSize', 10);
##### 0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Akzeptierte Antwort

Image Analyst am 8 Mai 2022
Try fitting each lane stripe to a line, then getting the average column for every row. You need to extend the fitted line outside the image so you can get the middle line when only one lane stripe is in the image, like at the bottom of your image.
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
folder = pwd;
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgbImage(:, :, 3);
else
grayImage = rgbImage;
end
%--------------------------------------------------------------------------------------------------------
% Crop away white surrounding frame and other stuff in the screenshot to get the image alone.
grayImage = grayImage(34:752, 83:1362,:);
% Update the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
% Display histogram.
subplot(2, 2, [2,4]);
histogram(grayImage);
grid on;
drawnow;
title('Histogram of Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Binarize the image to get a mask.
lowThreshold = 192;
highThreshold = intmax(class(grayImage)) - 1;
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% threshold(lowThreshold, highThreshold, grayImage);
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Put red threshold line on histogram so they know where it was thresholded at.
xline(lowThreshold, 'Color', 'r', 'LineWidth', 2)
% Take only the two largest blobs.
subplot(2, 2, 3);
hold on;
impixelinfo;
axis('on', 'image');
drawnow;
title('Mask, a Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Label the two blobs so we can fit a line through wach one, one at a time.
% Fit a line through the left blob
leftLine = ismember(labeledImage, 1);
[leftRows, leftCols] = find(leftLine);
coefficients = polyfit(leftRows, leftCols, 1)
% Make sure xFit is plenty wide enough so that y will span the vertical part of the image.
rowFitLeft = -10 * rows : 10 * rows;
colFitLeft = polyval(coefficients, rowFitLeft);
% Get indexes where y is out of the image
badIndexes = (rowFitLeft < 1) | (rowFitLeft > rows);
% Plot line in red over road lane marker.
hold on;
plot(colFitLeft, rowFitLeft, 'r-', 'LineWidth', 3);
% Fit a line through the left blob
rightLine = ismember(labeledImage, 2);
[rightRows, rightCols] = find(rightLine);
coefficients = polyfit(rightRows, rightCols, 1)
rowFitRight = -10 * rows : 10 * rows;
colFitRight = polyval(coefficients, rowFitRight);
% Get indexes where y is out of the image
badIndexes = (rowFitRight < 1) | (rowFitRight > rows);
% Plot line in red over road lane marker.
plot(colFitRight, rowFitRight, 'r-', 'LineWidth', 3);
% Get the middle line as the average of the two x values.
middleLineCols = (colFitLeft + colFitRight) / 2;
% Plot line in red over road lane marker.
plot(middleLineCols, rowFitRight, 'r-', 'LineWidth', 3);
##### 2 KommentareKeine anzeigenKeine ausblenden
Dekel Mashiach am 8 Mai 2022
Thank you very much, you solved my problem !
Last question, I want to convert the image to 3D in order to get the depth of the centerline , is it possible to do that?
Image Analyst am 8 Mai 2022
See this:
I haven't used it so can't answer questions about it so call the Mathworks if you have questions.

Melden Sie sich an, um zu kommentieren.

### Weitere Antworten (2)

Image Analyst am 3 Mai 2022
Here are the stps I would try
1. Crop the image to get rid of that white frame.
2. Threshold the image to get the white lines.
3. Call bwareafilt(bw, 2) to take only the 2 largest blobs.
4. Scan down line-by-line using find() to get the first and last white pixel on each line.
5. The center line is the average of the first column and the last column.
6. If you want, you can fit a straight line through the centerline data to remove noise and smooth the line.
##### 7 Kommentare5 ältere Kommentare anzeigen5 ältere Kommentare ausblenden
Image Analyst am 7 Mai 2022
@Abdul Hannan Qureshi that wasn't the post I was thinking of, but thanks. @Dekel Mashiach I just got back from 4 days of traveling. You probably have it solved by now, but if not, write back. I'd probably modify my steps 4-6 above and just fit a line on each side, then get the average x point for each fitted y value.
Dekel Mashiach am 8 Mai 2022
Bearbeitet: Dekel Mashiach am 8 Mai 2022
Unfortunately, I didn't resolve this yet. I would be very happy if you could help me.

Melden Sie sich an, um zu kommentieren.

yanqi liu am 7 Mai 2022
##### 0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Kategorien

Mehr zu Image Processing Toolbox finden Sie in Help Center und File Exchange

### Community Treasure Hunt

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

Start Hunting!

Translated by