exponenta event banner

Оценка обнаружений границ полос движения на основе данных об истинности грунта

В этом примере показано, как сравнивать данные истинности земли с результатами алгоритма обнаружения границ полосы движения. Он также иллюстрирует, как это сравнение может быть использовано для настройки параметров алгоритма для получения наилучших результатов обнаружения.

Обзор

Данные о истинности грунта обычно доступны в координатах изображения, тогда как границы моделируются в системе координат транспортного средства. Сравнение двух включает преобразование координат и, таким образом, требует дополнительной осторожности при интерпретации результатов. Решения о вождении основаны на расстояниях в системе координат транспортного средства. Поэтому более полезно выразить и понять требования к точности, используя физические единицы в координатах транспортного средства, а не в координатах пикселей.

MonoCameraExample описаны внутренние устройства датчика монокулярной камеры и процесс моделирования границ полосы движения. В этом примере показано, как оценить точность этих моделей по данным, подтвержденным вручную. После установления фреймворка сравнения фреймворк расширяется для точной настройки параметров алгоритма обнаружения границ для оптимальной производительности.

Загрузка и подготовка исходных данных

Вы можете использовать приложение Ground Truth Labeler, чтобы отмечать и маркировать границы полос в видео. Эти аннотированные границы полосы движения представлены в виде наборов точек, расположенных вдоль интересующих границ. Наличие богатого набора аннотированных вручную границ полосы движения для различных сценариев вождения имеет решающее значение для оценки и точной настройки алгоритмов автоматического обнаружения границ полосы движения. Пример набора для caltech_cordova1.avi видеофайл доступен вместе с панелью инструментов.

Загрузка предопределенных границ левой и правой эго-полос, указанных в координатах изображения. Каждая граница представлена набором M-by-2 чисел, представляющих M местоположений пикселей вдоль этой границы. Каждый видеокадр имеет не более двух таких наборов, представляющих левую и правую полосу.

loaded = load('caltech_cordova1_EgoBoundaries.mat');
sensor = loaded.sensor; % Associated monoCamera object
gtImageBoundaryPoints = loaded.groundTruthData.EgoLaneBoundaries;

% Show a sample of the ground truth at this frame index
frameInd = 36;

% Load the video frame
frameTimeStamp = seconds(loaded.groundTruthData(frameInd,:).Time);
videoReader = VideoReader(loaded.videoName);
videoReader.CurrentTime = frameTimeStamp;
frame = videoReader.readFrame();

% Obtain the left lane points for this frame
boundaryPoints = gtImageBoundaryPoints{frameInd};
leftLanePoints = boundaryPoints{1};

figure
imshow(frame)
hold on
plot(leftLanePoints(:,1), leftLanePoints(:,2),'+','MarkerSize',10,'LineWidth',4);
title('Sample Ground Truth Data for Left Lane Boundary');

Преобразование точек истинности грунта из координат изображения в координаты транспортного средства для прямого сравнения с моделями границ. Для выполнения этого преобразования используйте imageToVehicle функция со связанной monoCamera объект для выполнения этого преобразования.

gtVehicleBoundaryPoints = cell(numel(gtImageBoundaryPoints),1);
for frameInd = 1:numel(gtImageBoundaryPoints)
    boundaryPoints   = gtImageBoundaryPoints{frameInd};
    if ~isempty(boundaryPoints)
        ptsInVehicle = cell(1, numel(boundaryPoints));
        for cInd = 1:numel(boundaryPoints)
            ptsInVehicle{cInd} = imageToVehicle(sensor, boundaryPoints{cInd});
        end
        gtVehicleBoundaryPoints{frameInd} = ptsInVehicle;
    end
end

Модель границ полос движения с использованием монокулярного датчика

Для получения тестовых данных для сравнения выполните алгоритм моделирования границ полосы движения на видео образца. Здесь повторно используйте helperMonoSensor модуль представлен в примере «Визуальное восприятие с использованием монокулярной камеры». При обработке видео необходим дополнительный шаг для возврата обнаруженных граничных моделей. Эта логика заключена в вспомогательную функцию, detectBoundaries, определяется в конце этого примера.

monoSensor  = helperMonoSensor(sensor);
boundaries  = detectBoundaries(loaded.videoName, monoSensor);

Расчет моделей границ полос движения

Используйте evaluateLaneBoundaries функция, чтобы найти количество границ, которые соответствуют этим границам в истинном основании. Истинность земли назначается тестовой границе только в том случае, если все точки истинности земли находятся в пределах заданного расстояния в поперечном направлении от соответствующей тестовой границы. Если множественные границы истинности грунта удовлетворяют этому критерию, выбирается граница с наименьшим максимальным боковым расстоянием. Остальные помечены как ложные положительные результаты.

threshold = 0.25; % in vehicle coordinates (meters)
[numMatches, numMisses, numFalsePositives, assignments] = ...
    evaluateLaneBoundaries(boundaries, gtVehicleBoundaryPoints, threshold);
disp(['Number of matches: ', num2str(numMatches)]);
disp(['Number of misses: ', num2str(numMisses)]);
disp(['Number of false positives: ', num2str(numFalsePositives)]);
Number of matches: 321
Number of misses: 124
Number of false positives: 25

Эти необработанные подсчеты можно использовать для вычисления других статистических данных, таких как точность, отзыв и F1 балл:

precision = numMatches/(numMatches+numFalsePositives);
disp(['Precision: ', num2str(precision)]);

recall = numMatches/(numMatches+numMisses);
disp(['Sensitivity/Recall: ', num2str(recall)]);

f1Score = 2*(precision*recall)/(precision+recall);
disp(['F1 score: ', num2str(f1Score)]);
Precision: 0.92775
Sensitivity/Recall: 0.72135
F1 score: 0.81163

Визуализация результатов с помощью графика птичьего глаза

evaluateLaneBoundaries дополнительно возвращает индексы назначения для каждого успешного совпадения между истинными границами грунта и тестовыми границами. Это можно использовать для визуализации обнаруженных и наземных границ истинности, чтобы получить лучшее представление о режимах отказа.

Найдите кадр, имеющий одну соответствующую границу и одну ложноположительную. Данные истинности земли для каждого кадра имеют две границы. Таким образом, кадр-кандидат будет иметь два индекса назначения, причем один из них будет равен 0, чтобы указать ложное положительное значение.

hasMatch           = cellfun(@(x)numel(x)==2, assignments);
hasFalsePositive   = cellfun(@(x)nnz(x)==1, assignments);
frameInd           = find(hasMatch&hasFalsePositive,1,'first');
frameVehiclePoints = gtVehicleBoundaryPoints{frameInd};
frameImagePoints   = gtImageBoundaryPoints{frameInd};
frameModels        = boundaries{frameInd};

Используйте assignments вывод evaluateLaneBoundaries чтобы найти модели, которые соответствовали (истинные положительные результаты), и модели, которые не имели совпадений (ложные положительные результаты) в истинной основе.

matchedModels    = frameModels(assignments{frameInd}~=0);
fpModels         = frameModels(assignments{frameInd}==0);

Настройте график птичьего глаза и визуализируйте точки истины и модели на нем.

bep = birdsEyePlot();
gtPlotter = laneBoundaryPlotter(bep,'DisplayName','Ground Truth',...
    'Color','blue');
tpPlotter = laneBoundaryPlotter(bep,'DisplayName','True Positive',...
    'Color','green');
fpPlotter = laneBoundaryPlotter(bep,'DisplayName','False Positive',...
    'Color','red');

plotLaneBoundary(gtPlotter, frameVehiclePoints);
plotLaneBoundary(tpPlotter, matchedModels);
plotLaneBoundary(fpPlotter, fpModels);
title('Bird''s-Eye Plot of Comparison Results');

Визуализация результатов на видео в камере и на экране птичьего глаза

Чтобы получить лучший контекст результата, можно также визуализировать точки истинности земли и модели границ на видео.

Получить кадр, соответствующий интересующему кадру.

videoReader             = VideoReader(loaded.videoName);
videoReader.CurrentTime = seconds(loaded.groundTruthData.Time(frameInd));
frame                   = videoReader.readFrame();

Рассматривайте граничные модели как сплошную линию (независимо от того, как датчик классифицирует ее) для визуализации.

fpModels.BoundaryType      = 'Solid';
matchedModels.BoundaryType = 'Solid';

Вставка соответствующих моделей, ложных срабатываний и точек истинности земли. Этот график полезен для вывода о том, что наличие перекрестков создает сложный сценарий для алгоритма моделирования границ.

xVehicle = 3:20;
frame = insertLaneBoundary(frame, fpModels, sensor, xVehicle,'Color','Red');
frame = insertLaneBoundary(frame, matchedModels, sensor, xVehicle,'Color','Green');
figure
ha = axes;
imshow(frame,'Parent', ha);

% Combine the left and right boundary points
boundaryPoints = [frameImagePoints{1};frameImagePoints{2}];
hold on
plot(ha, boundaryPoints(:,1), boundaryPoints(:,2),'+','MarkerSize',10,'LineWidth',4);
title('Camera View of Comparison Results');

Можно также визуализировать результаты в виде этого кадра с высоты птичьего полета.

birdsEyeImage = transformImage(monoSensor.BirdsEyeConfig,frame);

xVehicle = 3:20;
birdsEyeImage = insertLaneBoundary(birdsEyeImage, fpModels, monoSensor.BirdsEyeConfig, xVehicle,'Color','Red');
birdsEyeImage = insertLaneBoundary(birdsEyeImage, matchedModels, monoSensor.BirdsEyeConfig, xVehicle,'Color','Green');

% Combine the left and right boundary points
ptsInVehicle = [frameVehiclePoints{1};frameVehiclePoints{2}];
gtPointsInBEV  = vehicleToImage(monoSensor.BirdsEyeConfig, ptsInVehicle);

figure
imshow(birdsEyeImage);
hold on
plot(gtPointsInBEV(:,1), gtPointsInBEV(:,2),'+','MarkerSize', 10,'LineWidth',4);
title('Bird''s-Eye View of Comparison Results');

Настройка параметров моделирования границ

Для точной настройки параметров алгоритма обнаружения границ полосы можно использовать структуру оценки, описанную выше. helperMonoSensor предоставляет три параметра, которые управляют результатами алгоритма поиска полосы движения.

  • LaneSegmentationSensitivity - Управляет чувствительностью segmentLaneMarkerRidge функция. Эта функция возвращает точки-кандидаты полосы в виде двоичной маски элемента полосы. Значение чувствительности может изменяться от 0 до 1, по умолчанию - 0,25. Увеличение этого числа приводит к увеличению числа потенциальных точек полосы движения и, возможно, к увеличению числа ложных обнаружений.

  • LaneXExtentThreshold - минимальная протяженность (длина) полосы движения. Оно выражается как отношение обнаруженной длины полосы к максимальной длине полосы, возможной для указанной конфигурации камеры. Значение по умолчанию - 0,4. Увеличьте это число, чтобы отклонить более короткие границы полос.

  • LaneStrengthThreshold - задает минимальную нормированную прочность для принятия обнаруженной границы полосы движения.

LaneXExtentThreshold и LaneStrengthThreshold являются производными от XExtent и Strength свойства parabolicLaneBoundary объект. Эти свойства являются примером того, как дополнительные ограничения могут быть наложены на алгоритмы моделирования границ для получения приемлемых результатов. Влияние варьирования LaneStrengthThreshold имеет дополнительные нюансы, которые стоит изучить. Типичные границы полос обозначены сплошными или пунктирными линиями. При сравнении с сплошными линиями пунктирные линии имеют меньшее число внутренних точек, что приводит к более низким значениям прочности. Это затрудняет установку общего порога прочности. Чтобы проверить влияние этого параметра, сначала создайте все границы путем установки LaneStrengthThreshold в 0. Этот параметр обеспечивает отсутствие влияния на выходные данные.

monoSensor.LaneStrengthThreshold = 0;
boundaries = detectBoundaries('caltech_cordova1.avi', monoSensor);

LaneStrengthThreshold имущество helperMonoSensor управляет нормализованным Strength параметр каждого parabolicLaneBoundary модель. Коэффициент нормализации, MaxLaneStrength, - это сила виртуальной полосы, которая проходит по всей протяженности изображения птичьего глаза. Это значение определяется исключительно birdsEyeView конфигурация helperMonoSensor. Оценка воздействия LaneStrengthThresholdсначала вычисляют распределение нормализованных уровней полосы для всех обнаруженных границ в видео образца. Обратите внимание на наличие двух прозрачных пиков, один из которых имеет нормализованную прочность 0,3, а другой - 0,7. Эти два пика соответствуют пунктирной и сплошной границам полосы соответственно. На этом графике можно эмпирически определить, что для обеспечения обнаружения пунктирных границ полосы движения LaneStrengthThreshold должно быть ниже 0,3.

strengths = cellfun(@(b)[b.Strength], boundaries,'UniformOutput',false);
strengths = [strengths{:}];
normalizedStrengths = strengths/monoSensor.MaxLaneStrength;
figure;
hist(normalizedStrengths);
title('Histogram of Normalized Lane Strengths');

Можно использовать структуру сравнения для дальнейшей оценки влияния LaneStrengthThreshold параметры по эффективности обнаружения алгоритма моделирования. Обратите внимание, что threshold значение, управляющее максимальным физическим расстоянием между моделью и истинной землей, остается таким же, как и раньше. Это значение продиктовано требованиями к точности системы ADAS и обычно не изменяется.

threshold = .25;
[~, ~, ~, assignments] = ...
    evaluateLaneBoundaries(boundaries, gtVehicleBoundaryPoints, threshold);

Складывать каждую границу в соответствии с нормированной прочностью. assignments информация помогает классифицировать каждую границу как истинную положительную (совпадающую) или ложную положительную. LaneStrengthThreshold является «минимальным» порогом, поэтому граница, классифицированная как истинное положительное значение при данном значении, будет оставаться истинным положительным значением для всех нижних пороговых значений.

nMatch = zeros(1,100); % Normalized lane strength is bucketed into 100 bins
nFP    = zeros(1,100); % ranging from 0.01 to 1.00.
for frameInd = 1:numel(boundaries)
    frameBoundaries  = boundaries{frameInd};
    frameAssignment  = assignments{frameInd};
    for bInd = 1:numel(frameBoundaries)
        normalizedStrength = frameBoundaries(bInd).Strength/monoSensor.MaxLaneStrength;
        strengthBucket     = floor(normalizedStrength*100);
        if frameAssignment(bInd)
            % This boundary was matched with a ground truth boundary,
            % record as a true positive for all values of strength above
            % its strength value.
            nMatch(1:strengthBucket) = nMatch(1:strengthBucket)+1;
        else
            % This is a false positive
            nFP(1:strengthBucket) = nFP(1:strengthBucket)+1;
        end
    end
end

Используйте эту информацию для вычисления количества «пропущенных» границ, то есть границ истинности земли, которые алгоритм не смог обнаружить на указанном LaneStrengthThreshold значение. С помощью этой информации вычислите точность и вспомните метрики.

gtTotal = sum(cellfun(@(x)numel(x),gtVehicleBoundaryPoints));
nMiss   = gtTotal - nMatch;

precisionPlot = nMatch./(nMatch + nFP);
recallPlot    = nMatch./(nMatch + nMiss);

Постройте график метрик точности и отзыва для различных значений порогового параметра прочности полосы движения. Этот график полезен для определения оптимального значения параметра прочности полосы движения. Для этого видеоклипа, чтобы максимизировать метрики отзыва и точности, LaneStrengthThreshold должно быть в диапазоне 0,20 - 0,25.

figure;
plot(precisionPlot);
hold on;
plot(recallPlot);
xlabel('LaneStrengthThreshold*100');
ylabel('Precision and Recall');
legend('Precision','Recall');
title('Impact of LaneStrengthThreshold on Precision and Recall Metrics');

Вспомогательная функция

Обнаружение границ в видео.

detectBoundaries использует предварительно сконфигурированный helperMonoSensor объект для обнаружения границ в видео.

function boundaries = detectBoundaries(videoName, monoSensor)
videoReader = VideoReader(videoName);
hwb         = waitbar(0,'Detecting and modeling boundaries in video...');
closeBar    = onCleanup(@()delete(hwb));
frameInd    = 0;
boundaries  = {};
while hasFrame(videoReader)
    frameInd  = frameInd+1;
    frame     = readFrame(videoReader);
    sensorOut = processFrame(monoSensor, frame);
    % Save the boundary models
    boundaries{end+1} =...
        [sensorOut.leftEgoBoundary, sensorOut.rightEgoBoundary];  %#ok<AGROW>
    waitbar(frameInd/(videoReader.Duration*videoReader.FrameRate), hwb);
end
end

См. также

Приложения

Функции

Связанные темы