Wprowadzenie
Wykrywanie obiektów to duże pole widzenia komputerowego i jedno z ważniejszych zastosowań widzenia komputerowego „na wolności”. Z niego wyodrębniono wykrywanie punktów kluczowych (często używane do szacowania pozy).
Punktami kluczowymi mogą być różne punkty – części twarzy, kończyny ciała itp. Estymacja pozycji to szczególny przypadek wykrywania punktów kluczowych – w którym punkty są częściami ludzkiego ciała.
Szacowanie pozy to niesamowite, niezwykle zabawne i praktyczne wykorzystanie wizji komputerowej. Dzięki niemu możemy pozbyć się sprzętu używanego do szacowania póz (stroje do przechwytywania ruchu), które są kosztowne i nieporęczne. Dodatkowo możemy odwzorować ruch ludzi na ruch robotów w przestrzeni euklidesowej, umożliwiając precyzyjne ruchy motoryczne bez użycia kontrolerów, które zwykle nie pozwalają na wyższy poziom precyzji. Szacowanie punktów kluczowych może być wykorzystane do przełożenia naszych ruchów na modele 3D w AR i VR, a coraz częściej używa się do tego tylko kamery internetowej. Wreszcie – ocena pozy może nam pomóc w sporcie i bezpieczeństwie.
W tym przewodniku będziemy wykonywać szacowanie pozycji w czasie rzeczywistym na podstawie wideo w Pythonie, korzystając z najnowocześniejszego modelu YOLOv7.
W szczególności będziemy pracować nad filmem z zimowych igrzysk olimpijskich 2018, które odbyły się w południowokoreańskim PyeongChang:
Aljona Savchenko i Bruno Massot wykonali niesamowity występ, obejmujący nakładanie się ciał na aparat, szybki płynny ruch i wirowanie w powietrzu. Będzie to niesamowita okazja, aby zobaczyć, jak model radzi sobie w trudnych do wnioskowania sytuacjach!
YOLO i ocena pozycji
YOLO (patrzysz tylko raz) to metodologia, a także rodzina modeli zbudowanych do wykrywania obiektów. Od momentu powstania w 2015 r. YOLOv1, YOLOv2 (YOLO9000) i YOLOv3 zostały zaproponowane przez tego samego autora (autorów) – a społeczność głębokiego uczenia kontynuowała postępy z otwartymi źródłami w kolejnych latach.
Ultralytics' YOLOv5 to repozytorium do wykrywania obiektów klasy branżowej, oparte na metodzie YOLO. Jest zaimplementowany w PyTorch, w przeciwieństwie do C++ w poprzednich modelach YOLO, jest w pełni open source i ma pięknie prosty i potężny interfejs API, który pozwala elastycznie wywnioskować, trenować i dostosowywać projekt. Jest to podstawa, na której opiera się większość nowych prób udoskonalenia metody YOLO.
W ten sposób YOLOR (Uczysz się tylko jednej reprezentacji) i YOLOv7, które zbudowane na bazie YOLOR (ten sam autor) również zostały stworzone!
YOLOv7 nie jest tylko architekturą wykrywania obiektów – zapewnia nowe nagłówki modeli, które mogą wyprowadzać punkty kluczowe (szkielety) i przeprowadzać segmentację instancji oprócz tylko regresji pola ograniczającego, co nie było standardem w poprzednich modelach YOLO. Nie jest to zaskakujące, ponieważ wiele architektur wykrywania obiektów zostało wcześniej przeprojektowanych do zadań segmentacji instancji i wykrywania punktów kluczowych, ze względu na wspólną ogólną architekturę, z różnymi wynikami w zależności od zadania.
Chociaż nie jest to zaskakujące – obsługa segmentacji instancji i wykrywania punktów kluczowych prawdopodobnie stanie się nowym standardem dla modeli opartych na YOLO, które kilka lat temu zaczęły przewyższać praktycznie wszystkie inne detektory dwustopniowe zarówno pod względem dokładności, jak i szybkości.
Dzięki temu segmentacja instancji i wykrywanie punktów kluczowych są szybsze niż kiedykolwiek wcześniej, dzięki prostszej architekturze niż detektory dwustopniowe.
Sam model został stworzony poprzez zmiany architektoniczne, a także optymalizację aspektów szkolenia, nazwanych „torbą gratisów”, co zwiększyło dokładność bez zwiększania kosztów wnioskowania.
Instalowanie YOLOv7
Zacznijmy od sklonowania repozytorium, aby uzyskać kod źródłowy:
! git clone https://github.com/WongKinYiu/yolov7.git
Przejdźmy teraz do yolov7
katalog, w którym znajduje się projekt, i spójrz na zawartość:
%cd yolov7
!ls
/content/yolov7
cfg figure output.mp4 test.py
data hubconf.py paper tools
deploy inference README.md train_aux.py
detect.py LICENSE.md requirements.txt train.py
export.py models scripts utils
Uwaga: powołanie !cd dirname
przenosi Cię do katalogu w tej komórce. Powołanie %cd dirname
przenosi Cię również do katalogu w nadchodzących komórkach i utrzymuje Cię tam.
Teraz YOLO ma być wykrywaczem obiektów i nie jest dostarczane z wagami szacowania pozy przez dedfault. Będziemy chcieli pobrać wagi i załadować z nich konkretną instancję modelu. Wagi są dostępne w tym samym repozytorium GitHub i można je również łatwo pobrać za pośrednictwem interfejsu CLI:
! curl -L https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-w6-pose.pt -o yolov7-w6-pose.pt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 153M 100 153M 0 0 23.4M 0 0:00:06 0:00:06 --:--:-- 32.3M
Po pobraniu możemy zaimportować biblioteki i metody pomocnicze, których będziemy używać:
import torch
from torchvision import transforms
from utils.datasets import letterbox
from utils.general import non_max_suppression_kpt
from utils.plots import output_to_keypoint, plot_skeleton_kpts
import matplotlib.pyplot as plt
import cv2
import numpy as np
Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!
Świetny! Przejdźmy teraz do ładowania modelu i tworzenia skryptu, który pozwala wywnioskować pozy z filmów z YOLOv7 i OpenCV.
Szacowanie pozycji w czasie rzeczywistym za pomocą YOLOv7
Stwórzmy najpierw metodę ładowania modelu z pobranych wag. Sprawdzimy jakie mamy dostępne urządzenie (CPU czy GPU):
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
def load_model():
model = torch.load('yolov7-w6-pose.pt', map_location=device)['model']
model.float().eval()
if torch.cuda.is_available():
model.half().to(device)
return model
model = load_model()
W zależności od tego, czy mamy GPU, czy nie, włączymy półprecyzję (używając float16
zamiast float32
w operacjach), co znacznie przyspiesza wnioskowanie. Należy pamiętać, że zdecydowanie zaleca się wykonanie tego na GPU w celu uzyskania prędkości w czasie rzeczywistym, ponieważ procesory prawdopodobnie nie będą miały wystarczającej mocy, aby to zrobić, chyba że uruchomią się na małych filmach.
Napiszmy metodę przekonywania do prowadzenia wnioskowania. Akceptujemy obrazy jako tablice NumPy (ponieważ będziemy je później przekazywać podczas czytania wideo). Po pierwsze, używając letterbox()
funkcja – zmienimy rozmiar i dopasujemy wideo do kształtu, z którym model może pracować. To nie musi być i nie będzie kształtem (rozdzielczością) powstałego wideo!
Następnie zastosujemy transformacje, skonwertujemy obraz do połowy precyzji (jeśli dostępny jest procesor graficzny), wsadujemy go i przepuszczamy przez model:
def run_inference(image):
image = letterbox(image, 960, stride=64, auto=True)[0]
image = transforms.ToTensor()(image)
if torch.cuda.is_available():
image = image.half().to(device)
image = image.unsqueeze(0)
with torch.no_grad():
output, _ = model(image)
return output, image
Zwrócimy przewidywania modelu, a także obraz jako tensor. Są to „zgrubne” przewidywania – zawierają wiele nakładających się aktywacji, a my będziemy chcieli je „oczyścić” za pomocą niemaksymalnego tłumienia i nanieść przewidywane szkielety na sam obraz:
def draw_keypoints(output, image):
output = non_max_suppression_kpt(output,
0.25,
0.65,
nc=model.yaml['nc'],
nkpt=model.yaml['nkpt'],
kpt_label=True)
with torch.no_grad():
output = output_to_keypoint(output)
nimg = image[0].permute(1, 2, 0) * 255
nimg = nimg.cpu().numpy().astype(np.uint8)
nimg = cv2.cvtColor(nimg, cv2.COLOR_RGB2BGR)
for idx in range(output.shape[0]):
plot_skeleton_kpts(nimg, output[idx, 7:].T, 3)
return nimg
Po ich wprowadzeniu nasz ogólny przepływ będzie wyglądał następująco:
img = read_img()
outputs, img = run_inference(img)
keypoint_img = draw_keypoints(output, img)
Aby przełożyć to na ustawienia wideo w czasie rzeczywistym — użyjemy OpenCV do odczytania wideo i uruchomimy ten proces dla każdej klatki. W każdej klatce zapiszemy ją również do nowego pliku, zakodowanego jako wideo. To z konieczności spowolni proces, ponieważ uruchamiamy wnioskowanie, wyświetlamy je i zapisujemy — możesz więc przyspieszyć wnioskowanie i wyświetlanie, unikając tworzenia nowego pliku i zapisywania do niego w pętli:
def pose_estimation_video(filename):
cap = cv2.VideoCapture(filename)
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('ice_skating_output.mp4', fourcc, 30.0, (int(cap.get(3)), int(cap.get(4))))
while cap.isOpened():
(ret, frame) = cap.read()
if ret == True:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
output, frame = run_inference(frame)
frame = draw_keypoints(output, frame)
frame = cv2.resize(frame, (int(cap.get(3)), int(cap.get(4))))
out.write(frame)
cv2.imshow('Pose estimation', frame)
else:
break
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
Połączenia VideoWriter
akceptuje kilka parametrów – nazwę pliku wyjściowego, FourCC (cztery kody kodeków, oznaczające kodek używany do kodowania wideo), liczbę klatek na sekundę i rozdzielczość jako krotkę. Aby nie zgadywać ani nie zmieniać rozmiaru wideo — użyliśmy szerokości i wysokości oryginalnego wideo, uzyskanej za pomocą VideoCapture
instancja zawierająca dane o samym filmie, takie jak szerokość, wysokość, całkowita liczba klatek itp.
Teraz możemy wywołać metodę na dowolnym wejściowym wideo:
pose_estimation_video('../ice_skating.mp4')
Spowoduje to otwarcie okna OpenCV, wyświetlającego wnioskowanie w czasie rzeczywistym. A także zapisze plik wideo w yolov7
katalog (ponieważ mamy cd
d do tego):
Uwaga: Jeśli Twój procesor graficzny ma problemy lub jeśli chcesz osadzić wyniki takiego modelu w aplikacji, której opóźnienie jest kluczowym aspektem przepływu pracy, zmniejsz wideo i pracuj na mniejszych klatkach. Jest to wideo w rozdzielczości Full HD 1920 × 1080 i powinno działać szybko w większości systemów domowych, ale jeśli nie działa tak dobrze w twoim systemie, zmniejsz obraz (obrazy).
Wnioski
W tym przewodniku przyjrzeliśmy się metodzie YOLO, YOLOv7 oraz relacjom między YOLO a wykrywaniem obiektów, estymacją pozy i segmentacją instancji. Następnie przyjrzeliśmy się, jak łatwo zainstalować i pracować z YOLOv7 za pomocą programistycznego interfejsu API i stworzyliśmy kilka wygodnych metod, aby ułatwić wnioskowanie i wyświetlanie wyników.
Na koniec otworzyliśmy wideo przy użyciu OpenCV, przeprowadziliśmy wnioskowanie z YOLOv7 i stworzyliśmy funkcję do szacowania pozy w czasie rzeczywistym, zapisując wynikowy film w pełnej rozdzielczości i 30 klatkach na sekundę na dysku lokalnym.
Idąc dalej – praktyczne uczenie głębokie dla wizji komputerowej
Twoja dociekliwość sprawia, że chcesz iść dalej? Zalecamy sprawdzenie naszego Kurs: „Praktyczne uczenie głębokie dla widzenia komputerowego z Pythonem”.
Kolejny kurs na temat wizji komputerowej?
Nie będziemy robić klasyfikacji cyfr MNIST ani mody MNIST. Swoją rolę pełnili dawno temu. Zbyt wiele zasobów edukacyjnych koncentruje się na podstawowych zestawach danych i podstawowych architekturach, zanim zaawansowane architektury czarnoskrzynkowe poniosą ciężar wydajności.
Chcemy się skupić demistyfikacja, praktyczność, zrozumienie, intuicja i realne projekty. Chcieć się nauczyć w jaki sposób możesz zrobić różnicę? Zabierzemy Cię na przejażdżkę od sposobu, w jaki nasze mózgi przetwarzają obrazy, przez pisanie klasyfikatora głębokiego uczenia się na poziomie badań naukowych w zakresie raka piersi, do sieci głębokiego uczenia się, które „halucynują”, ucząc Cię zasad i teorii poprzez praktyczną pracę, wyposażając Cię w know-how i narzędzia, aby stać się ekspertem w stosowaniu uczenia głębokiego do rozwiązywania wizji komputerowych.
Co jest w środku?
- Pierwsze zasady widzenia i jak nauczyć komputery „widzieć”
- Różne zadania i zastosowania wizji komputerowej
- Narzędzia handlu, które ułatwią Ci pracę
- Znajdowanie, tworzenie i wykorzystywanie zbiorów danych do wizji komputerowej
- Teoria i zastosowanie splotowych sieci neuronowych
- Obsługa zmiany domeny, współwystępowania i innych błędów w zbiorach danych
- Transfer uczenia się i wykorzystanie czasu szkolenia innych i zasobów obliczeniowych dla Twojej korzyści
- Budowanie i szkolenie najnowocześniejszego klasyfikatora raka piersi
- Jak zastosować zdrową dawkę sceptycyzmu do głównych idei i zrozumieć konsekwencje powszechnie stosowanych technik?
- Wizualizacja „przestrzeni koncepcyjnej” ConvNet za pomocą t-SNE i PCA
- Studia przypadków, w jaki sposób firmy wykorzystują techniki widzenia komputerowego do osiągania lepszych wyników
- Właściwa ocena modelu, wizualizacja przestrzeni utajonej i identyfikacja uwagi modelu
- Wykonywanie badań domenowych, przetwarzanie własnych zbiorów danych i tworzenie testów modelowych
- Najnowocześniejsze architektury, progresja pomysłów, co czyni je wyjątkowymi i jak je wdrażać
- KerasCV – biblioteka WIP do tworzenia najnowocześniejszych rurociągów i modeli
- Jak analizować i czytać artykuły i samodzielnie je wdrażać
- Wybór modeli w zależności od aplikacji
- Tworzenie kompleksowego procesu uczenia maszynowego
- Krajobraz i intuicja w wykrywaniu obiektów za pomocą szybszych sieci R-CNN, sieci RetinaNet, dysków SSD i YOLO
- Segmentacja instancyjna i semantyczna
- Rozpoznawanie obiektów w czasie rzeczywistym za pomocą YOLOv5
- Szkolenie wykrywaczy obiektów YOLOv5
- Praca z transformatorami przy użyciu KerasNLP (biblioteka przemysłowa WIP)
- Integracja Transformers z ConvNets w celu generowania podpisów obrazów
- DeepDream
- Optymalizacja modelu Deep Learning dla wizji komputerowej