Jak zatem możemy określić odległość od kamery obiektowej w czasie rzeczywistym, korzystając z kamery internetowej z przyzwoitą dokładnością, bez konieczności stosowania dodatkowego sprzętu, takiego jak kamera stereofoniczna lub czujnik głębokości?*

W tym wpisie na blogu omówimy implementację prostego algorytmu zwanego podobieństwem trójkątów. W przypadku wykrywania obiektów uprościmy to, używając po prostu wykrywania twarzy w OpenCV.

Film demonstracyjny dotyczący szacowania odległości

Baza kodu

Kod będzie dostępny w moim Repozytorium GitHub. Tutaj wyjaśnię ważne fragmenty kodu. Jeśli potrzebujesz pomocy, zostaw komentarz, chętnie Ci pomogę 😎

Wymagania

Wymagania są dość proste: potrzebujesz plików Python, OpenCV i Haar-cascade do wykrywania twarzy.

Po zainstalowaniu Pythona na swoim komputerze po prostu otwórz terminal i wklej w nim następujące polecenie i gotowe, Instalacja.

pip install opencv-python # on Linux turn pip to pip3

Zrób zdjęcie referencyjne

Obraz referencyjny pozwala nam na odwzorowanie świata rzeczywistego (płaszczyzny obiektu), ponieważ tracimy głębię obiektu, gdy uchwycimy go w przestrzeni 2D (obraz), w przeciwnym razie potrzebujemy specjalnej kamery, która może uchwycić głębię, ponieważ chcemy aby korzystać z naszej kamery internetowej, wymagany jest obraz referencyjny, musisz zadbać o kilka rzeczy, aby dokładność nie spadła, możesz użyć mojego obrazu referencyjnego, nie będzie to miało większego wpływu, ale polecam zrobić to samodzielnie, aby uzyskać większa dokładność.

Podczas robienia obrazu referencyjnego musisz zadbać o kilka rzeczy.

  • Rozdzielczość obrazu (ramki) musi być taka sama, jak w obrazie referencyjnym, zachowałem domyślne ustawienia OpenCV, czyli (640, 480)
  • Podczas wykonywania zdjęć referencyjnych trzymaj aparat możliwie prosto.
  • Zmierz odległość (KNOWN_DISTANCE) od kamery obiektowej, zanotuj ją i przechwyć obraz ustawiony na 76,2 centymetra.
  • Zmierz szerokość (KNOWN_WIDTH) obiektu, również ją zapisz, u mnie wynosi ona 14,3 centymetra.

Ważne zmienne

  • KNOWN_DISTANCE:jest to odległość kamery obiektowej 📷 w świecie rzeczywistym.
  • KNOWN_WIDTH:jest to zmierzona szerokość obiektu w świecie rzeczywistym
  • face_width_in_frame:Jest to szerokość twarzy w obrazie (ramce) określana przez detektor twarzy, mierzona w pikselach
KNOWN_DISTANCE = 76.2  # centimeter
KNOWN_WIDTH = 14.3  # centimeter

Wykrywanie obiektów (twarz)

Używam tutaj detekcji twarzy, jest ona nieubłagana dla każdego detektora obiektów, wystarczy postępować zgodnie z procedurą,

Wykrywanie twarzy przy użyciu Pythona Opencv, oto funkcja, która po prostu wykrywa twarz i zwraca szerokość twarzy w pikselach

Funkcja Dane twarzy przyjmuje tylko jeden argument, którym jest obraz.

def face_data(image):
face_width = 0
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray_image, 1.3, 5)
    for (x, y, h, w) in faces:
        cv2.rectangle(image, (x, y), (x+w, y+h), WHITE, 1)
        face_width = w
return face_width

Szukacz ogniskowej

Funkcja szukacza ogniskowej opiera się na trzech argumentach:

  1. Zmierzona_odległość to odległość między kamerą a obiektem podczas wykonywania obrazu referencyjnego, znana_odległość = 72,2 centymetra
  2. Real_width Zmierzona szerokość obiektu w świecie rzeczywistym. Tutaj mierzę szerokość twarzy, która wynosi około Known_width = 14,3 centymetra
  3. Szerokość_w_rf_image to szerokość obiektu w obrazie/ramce, która będzie wyrażona w pikselach

Ta funkcja zwróci ogniskową, która służy do znalezienia odległości, jest to tylko mapowanie.

oto kod:

def FocalLength(measured_distance, real_width, width_in_rf_image):
    focal_length = (width_in_rf_image* measured_distance)/ real_width
    return focal_length

Wyszukiwacz odległości

Ta funkcja ma trzy argumenty,

  1. Ogniskowa w pikselach, czyli wynik z funkcji Wyszukiwacz ogniskowej
  2. Real_width Mierzy szerokość obiektu w świecie rzeczywistym, tutaj mierzę szerokość twarzy, która wynosi około Known_width = 14,3 centymetra
  3. Szerokość_w_rf_image to szerokość obiektu w obrazie/ramce, która będzie wyrażona w pikselach

Funkcja wyszukiwania odległości zwróci odległość w centymetrach

oto kod:

def Distance_finder(Focal_Length, real_face_width, face_width_in_frame):
    distance = (real_face_width * Focal_Length)/face_width_in_frame
    return distance

To w zasadzie tyle, oto samouczek wideo, który wszystko szczegółowo wyjaśnia,

tutaj jest dokładniejsza wersja tego algorytmu, tutaj jest Repozytorium GitHub

Istnieje inny sposób („Markery Aruco”) na znalezienie odległości, który jest wygodniejszy i dokładniejszy, za pomocą jednej kamery (zwykłej kamery internetowej laptopa). Przyjrzymy się temu w nadchodzącym poście.

Odniesienie: