Sunteți pe pagina 1din 8

Șerbănescu Antonio

Volvoreanu Mugur
Anul II Master PCON

Proiect ADPSV
Tema 1
Urmărirea a mai multor autovehicule folosind o
camera video

Pentru a realiza urmărirea a mai multor autovehicule folosind o cameră video trebuie să
se parcurgă următorii pași:
1. Se definesc proprietățile camerei si poziția de montare a camerei;
2. Se încarcă și configurează un detector de autovehicule;
3. Se configurează un tracker multi-object;
4. Se rulează detectorul pentru fiecare cadru;
5. La ultimul pas se actualizează dispozitivul de urmărire cu rezultatele de urmărire într-
un videoclip.

Se va folosi ToolBox-ul Automated Driving, deoarece ne oferă detectoare de vehicule


preinstruite și un tracker multi obiect pentru a facilita urmărirea vehiculelor. Detectoarele de
vehicule se bazează pe caracteristicile ACF si Faster R-CNN, o tehnică de detectare a
obiectelor pe bază de Deep Learning.
Configurarea detectorului de vehicule si Tracker-ului Multi-
Object.

Pentru realizarea acestui proiect se va folosi detectorul de vehicule preinstruit ACF și se


va configura detectorul pentru a incorpora informațiile camerei. În mod prestabilit
detectorul scanează întreaga imagine la mai multe mărimi. Cunoscând parametrii camerei se
poate configura detectorul pentru a detecta vehiculele de pe planul solului numai la mărimi
rezonabile.
Astfel se introduce prima linie de cod:
d = load('FCWDemoMonoCameraSensor.mat', 'sensor');
Aceasta încarcă fisierul monoCamera care conține informațiile camerei.
A doua linie de cod :
detector = vehicleDetectorACF('full-view');, încarcș un detector de
vehicule ACF preinstruit. Detectorul ACF utilizează ”Aggregate Channel Features”
Modul ”Full-View” este instruit pe imagini din partea frontală, posterioară, stângă și
dreaptă a vehiculelor.
Detectorul trebuie configurat utilizând informațiile senzorului. Detectorul încearcă doar
să găsească vehicule în regiunea de imagine deasupra solului. Acest lucru poate reduce
calculul si previne detecțiile false.
Lătimea pentru marea majoritate a autovehiculelor este cuprinsă între 1.5 si 2.5 metri.
Doar o caseta de încadrare cu lățimea cuprinsă în aceast interval este considerată ca o
detectare în imagine.
vehicleWidth = [1.5, 2.5];
Detectorul se configurează folosind senzorul ”monoCamera” și lățimea dorită prin
următoarea linie de comandă:
detector = configureDetectorMonoCamera(detector, d.sensor,
vehicleWidth);
Ultima linie folosită pentru configurarea detectorului de vehicule si a Tracker-ului
Multi-Object, utilizează funcția ”setupTracker”, care creează un multiObjectTracker pentru a
urmări mai multe obiecte cu ajutorul filtrelor Kalman. Atunci când se creează un
multiObjectTracker se iau în considerare următoarele:
Initializarea filtrelor FCN: Modelele de mișcare și de măsurare posibile. Asociază detecțiilor la
track-uri. Inițializarea track-urilor noi pe baza detecțiilor neatribuite.
Assigment Threshold: Toate track-urile sunt inițializate ca ”tentativă”, reprezentând
posibilitatea ca acestea să rezulte dintr-o detectare falsă. Cât de departe detecțiile se pot
depărta de la pistă. Valoarea implicită pentru acest parametru este 30.
NumCoastingUpdates: Toate track-urile sunt inițializate ca ”tentativă”, reprezentând
posibilitatea ca acestea să rezulte dintr-o detectare falsă. Stergerea track-urilor dacă acestea
au rămas neatribuite pentru prea mult timp. Valoarea implicită este 5.
ConfirmationParrameters: Parametrii pentru confirmarea unei track-uri. Confirmarea
track-urilor daca de M detecții atribuite în N cadre. Se actualizează piesele existente pe baza
detecțiilor atribuite. Prezicerea track-urilor neatribuite existente.

Codul functiei: function


[tracker, positionSelector] = setupTracker()
% Create the tracker object.
tracker = multiObjectTracker('FilterInitializationFcn',
@initBboxFilter, ...
'AssignmentThreshold', 50, ...
'NumCoastingUpdates', 5, ...
'ConfirmationParameters', [3 5]);

% The State vector is: [x; vx; y; vy; w; vw; h; vh]


% [x;y;w;h] = positionSelector * State
positionSelector = [1 0 0 0 0 0 0 0; ...
0 0 1 0 0 0 0 0; ...
0 0 0 0 1 0 0 0; ...
0 0 0 0 0 0 1 0];
end

Urmărirea vehiculelor într-un video.

Pentru a urmari vehiculele in acest material video folosim o metoda de segmentare


bazata pe miscare. Aceasta metoda a fost implementata pentru a detecta regiuni
corespunzătoare obiectelor aflate în miscare precum vehicule sau oameni. O abordare
importantă pentru acest tip de segmentare este detectia modificărilor suferite de imagine.
Această problemă are ca scop identificarea unui set de pixeli corespunzători diferentelor
dintre două cadre ale aceleiasi scene. Modificările nesemnificative, precum cele cauzate de
variatii ale luminii, zgomot, etc., trebuie eliminate. Procesul de detectie a modificărilor are
trei etape: preprocesare, aplicarea unei reguli de decizie si de post-procesare. Folosim o
metoda cu detectia modificărilor deoarece este rapida si adecvate pentru aplicatiile în timp
real.
La fiecare pas de timp detectorul trebuie executat, tracker-ul actualizat cu rezultatele
de detectare și rezultatele de urmărire afișate într-un videoclip.
Astfel se va realiza setup-ul pentru video reader și player:
videoFile = 'TraficProiect.mp4';
videoReader = VideoReader(videoFile);
videoPlayer = vision.DeployableVideoPlayer();

currentStep = 0;
snapshot = [];
snapTimeStamp = 120;
cont = hasFrame(videoReader);

În continuare vom introduce următoarele lini de cod:

while cont
currentStep = currentStep + 1;

frame = readFrame(videoReader);

Pentru prima linie de cod se updatează frame-urile, iar cu a doua linie de cod se
introduce comanda pentru a citi următorul frame.
În continuare se vor folosi următoarele funcții:
● DetectObjects, aceasta funcție detectează vehiculele intr-o imagine.

detections = detectObjects(detector, frame, currentStep);

Funcția returnează casetele de încadrare a obiectelor detectate ca o listă de obiecte,


aceasta listă poate fi folosita ca un input pentru multiObjectTracker. Funcția returnează, de
asemenea masca binară, care are aceeași dimensiune ca si cadrul de intrare. Funcția
efectuează segmentarea mișcării folosind detectorul foreground.

Codul functiei:

function detections = detectObjects(detector, frame, frameCount)


% Run the detector and return a list of bounding boxes: [x, y,
w, h]
bboxes = detect(detector, frame);

% Define the measurement noise.


L = 100;
measurementNoise = [L 0 0 0; ...
0 L 0 0; ...
0 0 L/2 0; ...
0 0 0 L/2];

% Formulate the detections as a list of objectDetection reports.


numDetections = size(bboxes, 1);
detections = cell(numDetections, 1);
for i = 1:numDetections
detections{i} = objectDetection(frameCount, bboxes(i, :),
...
'MeasurementNoise', measurementNoise);
end
end

Folosind lista de la objectDetections, returnează track-urile actualizate pentru pasul


curent.

confirmedTracks = updateTracks(tracker, detections, currentStep);

● RemoveNoisyTracks, această funcție elimina zgomotul din track-uri.

confirmedTracks = removeNoisyTracks(confirmedTracks,
positionSelector, d.sensor.Intrinsics.ImageSize);

O pistă este considerată zgomotoasă daca caseta predictivă de încadrare este prea mică.
De obicei, acest lucru implică faptul că vehiculul se află la departare.

Codul functiei:

function tracks = removeNoisyTracks(tracks, positionSelector,


imageSize)
if isempty(tracks)
return
end

% Extract the positions from all the tracks.


positions = getTrackPositions(tracks, positionSelector);
% The track is 'invalid' if the predicted position is about to
move out
% of the image, or if the bounding box is too small.
invalid = ( positions(:, 1) < 1 | ...
positions(:, 1) + positions(:, 3) > imageSize(2) |
...
positions(:, 3) <= 20 | ...
positions(:, 4) <= 20 );
tracks(invalid) = [];
end

● InsertTrackBoxes, inserează casetele de încadrare într-o imagine și afișează poziția


track-ului în fața mașinii, în unități mondiale.

frameWithAnnotations = insertTrackBoxes(frame, confirmedTracks,


positionSelector, d.sensor);

Codul functiei:

function I = insertTrackBoxes(I, tracks, positionSelector, sensor)

if isempty(tracks)
return
end

% Allocate memory.
labels = cell(numel(tracks), 1);
% Retrieve positions of bounding boxes.
bboxes = getTrackPositions(tracks, positionSelector);

for i = 1:numel(tracks)
box = bboxes(i, :);

% Convert to vehicle coordinates using monoCamera object.


xyVehicle = imageToVehicle(sensor, [box(1)+box(3)/2,
box(2)+box(4)]);

labels{i} = sprintf('x=%.1f,y=
%.1f',xyVehicle(1),xyVehicle(2));
end
I = insertObjectAnnotation(I, 'rectangle', bboxes, labels,
'Color', 'yellow', ...
'FontSize', 10, 'TextBoxOpacity', .8, 'LineWidth', 2);
End

Următoarea linie de cod, afișează cadrul adnotat, realizarea unui snapshot pasului
curent și închiderea buclei dacă video player-ul este închis de către user.

videoPlayer(frameWithAnnotations);

if currentStep == snapTimeStamp
snapshot = frameWithAnnotations;
end

cont = hasFrame(videoReader) && isOpen(videoPlayer);


end
Ultima linie de cod arată vehiculele urmărite și afișează distanța până la vehicul.
if ~isempty(snapshot)
figure
imshow(snapshot)
end