W tym poście opiszę, jak stworzyłem oprogramowanie do analizy wideo, które jest w stanie wykryć niektóre rodzaje wykroczeń drogowych, analizując strumienie wideo z kamer drogowych. Oprogramowanie jest w stanie wykrywać i przechowywać wykroczenia drogowe, które są związane ze skrzyżowaniami pojazdów z liniami ciągłymi i naruszeniami sygnalizacji świetlnej.

To oprogramowanie zostało stworzone w celach demonstracyjnych iw niektórych przypadkach nie jest w stanie wykryć odpowiednich naruszeń. W przypadku dalszego rozwoju będzie w stanie automatycznie wykrywać większość rodzajów wykroczeń drogowych, a nie tylko te związane ze skrzyżowaniami z linią ciągłą i czerwonym światłem. Dalej opisuję szczegóły techniczne realizacji i robię kilka ilustracji.

Podczas rozwoju tego projektu chodziło o jak najszybsze uzyskanie MVP. Tak więc w niektórych przypadkach wybiera się pewne podejście zamiast lepszego podejścia, aby zaoszczędzić czas. Projekt został zrealizowany poprzez maksymalne wykorzystanie dostępnych algorytmów i dostępnej bazy kodu opensource, aby napisać jak najmniej kodu i poświęcić jak najmniej czasu. Projekt został opracowany w języku Python3, z dużym wykorzystaniem SciPy [https://www.scipy.org/] i OpenCV [https://opencv.org/]. Interfejs użytkownika jest oparty na GTK [https://www.gtk.org/].

Aby przeanalizować wideo i wykryć naruszenia, które są obecne w wideo, zastosowano następujące podejście. Po pierwsze, modele drogi i ruchu pojazdów są uzyskiwane poprzez przetwarzanie strumienia wideo. Po drugie, modele te są łączone i analizowane w celu wykrycia wykroczeń drogowych.

Analiza drogowa

Do analizy struktury drogi stosuje się podejście ręczne. W tym projekcie analizowane są proste linie oznakowania dróg. Ciągłe proste linie odgrywają kluczową rolę w kształtowaniu drogi. Takie linie to linie stopu, linie krawędzi, linie podwójne i inne.

Najpierw obraz tła wideo jest wyodrębniany przez zastosowanie algorytmu wyodrębniania tła/pierwszego planu [https://sagi-z.github.io/BackgroundSubtractorCNT/]. Ekstrakcja tła pozwala wyeliminować z wideo poruszające się obiekty i uzyskać wyraźny obraz drogi. Po drugie, obraz tła jest analizowany w celu wykrycia prostych linii drogi.

Jednym z najpopularniejszych sposobów znajdowania linii prostych na obrazie jest wstępne przetworzenie obrazu za pomocą algorytmu wykrywania krawędzi, a następnie zastosowanie transformacji hough [https://en.wikipedia.org/wiki/Hough_transform, https://docs. opencv.org/3.0-beta/modules/imgproc/doc/feature_detection.html?highlight=houghline#cv2.HoughLinesP ], aby zidentyfikować linie. Implementacje tych algorytmów są dostępne w bibliotece OpenCV. Chociaż ten algorytm jest dość ogólny, nie dał wymaganych wyników. Problem polegał na tym, że równolegle do wykrywania linii prostych widocznych na obrazie, jako linie identyfikowano także inne fragmenty obrazu, które zawierają dużo krawędzi. W przypadku rosnących progów dla linii często nie identyfikuje się również linii drogowych. Jasne, z dalszą obróbką obrazu, m.in. dzięki usunięciu małych nieprostych krawędzi można osiągnąć lepszy wynik, ale wybrano inne podejście.

Aby wykryć linie, najpierw stosuje się algorytm LSD [http://www.ipol.im/pub/art/2012/gjmr-lsd/article.pdf]. Implementacja tego algorytmu jest również dostępna w bibliotece OpenCV [https://docs.opencv.org/3.0-beta/modules/line_descriptor/doc/LSDDetector.html]

Następnie, po wykryciu odcinków linii, w celu określenia, czy kilka odcinków znajduje się na tej samej linii, z wykrytych odcinków składa się wykres. Węzły są połączone ze sobą, gdy odpowiadające im segmenty znajdują się prawie na tej samej linii i są wystarczająco blisko. Następnie, poprzez zastosowanie odpowiedniego algorytmu, identyfikowane są połączone składowe grafu [. J. Pearce, „An Improved Algorithm for Finding the Strongly Connected Components of a Directed Graph”, Technical Report, 2005], implementacja jest dostępna w SciPy [https://docs.scipy.org/doc/scipy/reference/generated /scipy.sparse.csgraph.connected_components.html]. Wreszcie połączone komponenty są identyfikowane jako linie proste.

Śledzenie pojazdów

Następnym krokiem jest uzyskanie modelu pozycji i ruchów pojazdu. W celu wykrycia pojazdów sieć neuronowa YOLO przetwarza klatki strumienia wideo [https://pjreddie.com/darknet/yolo/].

Aby zidentyfikować pojazdy i wygładzić fluktuacje przewidywanych pozycji w sekwencji detekcji, do detekcji stosuje się algorytm SORT. [https://arxiv.org/pdf/1602.00763.pdf, https://github.com/abewley/sort]. Algorytm ten wykorzystuje elementarną kombinację technik, takich jak filtr Kalmana i algorytm węgierski do śledzenia komponentów, ale jednocześnie to podejście zapewnia dokładność porównywalną z najnowocześniejszymi trackerami online. Następnie ścieżka ruchu pojazdu jest komponowana na podstawie wyniku śledzenia, a ścieżka jest wygładzana.

Logika naruszeń

Do tej pory opisałem, w jaki sposób uzyskuje się tor poruszającego się pojazdu oraz modele linii znakowania dróg. Po wykryciu linii są one pokazywane w oknie aplikacji i użytkownik może ustawić dowolny typ linii (Przód, Równoległy) lub pozostawić go bez ustawiania typu. Linie frontu przeznaczone są do wykorzystania w poprzek jezdni, a równoległe wzdłuż jezdni. Przekroczenie linii jest uważane za naruszenie. W przypadku Linii frontu można również wybrać kolor sygnalizacji świetlnej, aby określić, czy przekroczenie tej linii w określonym momencie jest naruszeniem, czy nie.

Ilustracje

Poniższe filmy ilustrują działanie oprogramowania. Filmy są tworzone na podstawie transmisji na żywo z kamer drogowych znalezionych w YouTube. Ponieważ zazwyczaj w krótkim czasie dochodzi do niewielu wykroczeń drogowych, linie są zwykle ustawiane na kolor czerwony (czerwone światło), aby tworzyć sztuczne wykroczenia. Można zauważyć, że nie wszystkie odpowiednie naruszenia są wykrywane. W niektórych przypadkach wynika to z faktu, że YOLO nie wykrywa pojazdów. Można to znacznie poprawić poprzez dodatkowe szkolenie sieci neuronowej na obrazach z kamer drogowych. W innych przypadkach ścieżka pojazdu naruszającego w rzeczywistości nie przekracza linii, co można poprawić, dostosowując logikę naruszenia. Na przykład, biorąc pod uwagę projekcję 2D sceny 3D, prostym możliwym ulepszeniem przecinania linii frontu jest przedłużenie linii do górnego kierunku kamery. Postanowiłem przerwać analizę linii na tym etapie, ponieważ w produkcji planuję zastosować inne podejście do uzyskania modelu drogi, który da bardziej precyzyjną i szczegółową reprezentację.

Kod projektu jest dostępny na GitHub https://github.com/partus/traffic-violation-detection-demo .

Specjalne podziękowania dla Arsena Mamikonyana, Tigrana Gevorgyana i Sahaka Aghamiryana za pomocne dyskusje.