ROS 1 Noetic Visietoepassingen

Dit hoofdstuk behandelt praktische ROS 1-visieworkflows op reComputer Jetson, waaronder cameravoorvertoning, QR-herkenning, poseschatting, objectdetectie, AR-markers, OpenCV en MediaPipe-voorbeelden.

Lange, uitvoerbare voorbeelden worden bewaard onder ./code/, en bijbehorende afbeeldingen worden bewaard onder ./images/.

Inhoud

7.2.2.1 Lees dit eerst

Het draait allemaal om gebruik.

De ROS 1-omgeving bevindt zich in de Docker-image en heeft een Docker-basis nodig om volledig operationeel te zijn!

Opmerking: Docker-images kunnen alleen visuele cases uitvoeren die USB-camera's gebruiken!

Ga naar Docker.

Open een terminal en voer het volgende commando in de docker-image voor ROS 1 in

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Afbeeldingen

7.2.2.1 Read This First figure 1

7.2.2.2 Cameravoorvertoning

Cameravoorvertoning

Ga naar de ROS 1 Docker-image

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Bekijk de parameters die door camera's worden ondersteund

Voer het volgende commando in om de apparaatnaam van de USB-cameramapping te zien:

bash
ls /dev/video*

Bekijk het stroomformaat, de framerate en de resolutie die door USB-camera's worden ondersteund, aan de hand van de bijbehorende apparaatindexnummers (0 tot n):

bash
# Install v4l2 utilities if they are not already installed:
apt update
apt install v4l-utils ffmpeg
bash
v4l2-ctl -d /dev/video0 --list-formats-ext

Cameravoorvertoningsbeeld -- terminalcommando

Terminals kunnen USB-camera's openen met ffplay

bash
ffplay -f v4l2 -i /dev/video0

Cameravoorvertoning - Python-script

Voer lokale USB-camera's uit om scripts te testen:

bash
 cd source_code/ROS 1/
 python3 CameraPreview.py

Het script doorloopt de beschikbare USB-camera's om weer te geven en de framerate af te drukken

De broncode van CameraPreview.py is als volgt:

Codebestand: 7-2-2-2-camera-preview-CameraPreview.py

python
#!/usr/bin/env python3
import cv2
import glob
import time
import os

def list_video_devices():
    """Return the /dev/video* device list."""
    devs = sorted(glob.glob("/dev/video*"))
    return devs

def try_open_camera(dev):
    """Try to open a camera device."""
    cap = cv2.VideoCapture(dev, cv2.CAP_V4L2)
    if not cap.isOpened():
        cap.release()
        return None
    return cap

def main():
    devices = list_video_devices()
    if not devices:
        print("❌ No /dev/video* found")
        return

    print("🔍 Found video devices:")
    for d in devices:
        print("  ", d)

    cams = []
    for dev in devices:
        cap = try_open_camera(dev)
        if cap:
            print(f"✅ Opened {dev}")
            cams.append((dev, cap))
        else:
            print(f"❌ Failed {dev}")

    if not cams:
        print("❌ No usable cameras")
        return

    cam_index = 0
    last_time = time.time()
    fps = 0.0

    print("\nControls:")
    print("  n: next camera")
    print("  p: previous camera")
    print("  q / ESC: quit\n")

    while True:
        dev, cap = cams[cam_index]

        ret, frame = cap.read()
        if not ret:
            cv2.putText(
                frame,
                "Camera read failed",
                (30, 50),
                cv2.FONT_HERSHEY_SIMPLEX,
                1,
                (0, 0, 255),
                2,
            )
        else:
            now = time.time()
            fps = 1.0 / (now - last_time)
            last_time = now

            # FPS display
            cv2.putText(
                frame,
                f"FPS: {fps:.2f}",
                (20, 40),
                cv2.FONT_HERSHEY_SIMPLEX,
                1,
                (0, 255, 0),
                2,
            )

            # Device name display
            cv2.putText(
                frame,
                dev,
                (20, frame.shape[0] - 20),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.7,
                (255, 255, 255),
                2,
            )

        cv2.imshow("CameraPreview", frame)

        key = cv2.waitKey(1) & 0xFF
        if key in [27, ord("q")]:  # ESC / q
            break
        elif key == ord("n"):
            cam_index = (cam_index + 1) % len(cams)
            print(f"➡ Switch to {cams[cam_index][0]}")
            time.sleep(0.2)
        elif key == ord("p"):
            cam_index = (cam_index - 1) % len(cams)
            print(f"⬅ Switch to {cams[cam_index][0]}")
            time.sleep(0.2)

    for _, cap in cams:
        cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

Afbeeldingen

7.2.2.2 Camera Preview figure 1

7.2.2.2 Camera Preview figure 2

7.2.2.2 Camera Preview figure 3

7.2.2.2 Camera Preview figure 4

7.2.2.2 Camera Preview figure 5

7.2.2.2 Camera Preview figure 6

7.2.2.3 QR-codes

Inleiding tot 1 QR-code

QR-code is een van de tweedimensionale streepjescodes, en QR komt van het acroniem "Quick Response" in het Engels, wat snelle reactie betekent, en komt van de hoop van een uitvinder dat de QR-code snel gedecodeerd kan worden. De QR-code heeft niet alleen een hoge informatiecapaciteit, betrouwbaarheid en kosten, maar geeft ook aan dat meerdere tekstuele gegevens, zoals Chinese karakters en afbeeldingen, vertrouwelijk en onvervalsbaar zijn en gemakkelijk gebruikt kunnen worden. Belangrijker nog, de QR-codetechnologie is opensource.

Inleiding tot QR

Kenmerken van de QR-code

Gegevenswaarden in de QR-code bevatten dubbele informatie (redundantiewaarden). Zo blijft, zelfs als tot 30 procent van de tweedimensionale codestructuur vernietigd is, de leesbaarheid van de tweedimensionale code onaangetast. De opslagruimte voor de QR-code bedraagt maar liefst 7089 bits of 4296 tekens, inclusief leestekens en speciale tekens, die allemaal in de QR-code worden geschreven. Naast cijfers en tekens is het mogelijk om woorden en zinnen (zoals websites) te coderen. De codestructuur wordt complexer naarmate er meer gegevens aan de QR-code worden toegevoegd en de omvang van de code toeneemt.

Aanmaken en herkennen van 2D QR-codes

Installatieafhankelijkheid:

Codebestand: 7-2-2-3-qr-codes-install-deps.sh

bash
sudo apt update
sudo apt install -y python3-pip libzbar-dev
python3 -m pip install qrcode pyzbar

Maakt een qrcode-object aan, waarmee direct qr code create.py-scripts in de map kunnen worden uitgevoerd:

bash
python3 qrcode_create.py

Er wordt een tweedimensionale code (QR-code) met een ingestelde logo gegenereerd in de figure-map in de werkmap. De locatie van de vooraf ingestelde logoafbeelding bevindt zich ook in de figure-map. Het effect van de gegenereerde 2D-code is als volgt:

De broncode van qrcode create.py is als volgt:

Codebestand: 7-2-2-3-qr-codes-create.py

python
#!/usr/bin/env python3
import os
import qrcode
from PIL import Image
from pathlib import Path


def add_logo(img, logo_path):
    # Add logo, open logo image
    icon = Image.open(    logo_path)
    img_w, img_h = img.size
    # Set the size of the logo
    factor = 6
    size_w = int(img_w / factor)
    size_h = int(img_h / factor)
    icon_w, icon_h = icon.size
    if icon_w > size_w: icon_w = size_w
    if icon_h > size_h: icon_h = size_h
    # Resize the logo
    icon = icon.resize((icon_w, icon_h), Image.Resampling.LANCZOS)
    # Center the logo
    w = int((img_w - icon_w) / 2)
    h = int((img_h - icon_h) / 2)
    # Paste the logo
    img.paste(icon, (w, h), mask=None)
    return img


def create_qrcode(data, file_name, logo_path):
    '''
    version: Integer from 1 to 40, controls the size of the QR code.
    error_correction: Controls the error correction function. Can be one of the following:
        ERROR_CORRECT_L: About 7% or fewer errors can be corrected.
        ERROR_CORRECT_M (default): About 15% or fewer errors can be corrected.
        ERROR_CORRECT_H: About 30% or fewer errors can be corrected.
    box_size: Controls the number of pixels in each box of the QR code.
    border: Controls the number of boxes for the border (the default is 4).
    '''
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=10,
        border=4)
    # Add data to the QR code
    qr.add_data(data)
    print(data)
    qr.make(fit=True)
    img = qr.make_image(fill_color="green", back_color="white")
    # Add logo if file exists
    if Path(logo_path).is_file():
        img = add_logo(img, logo_path)
    # Save and show the image
    img.save(file_name)
    img.show()
    return img


if __name__ == '__main__':
    file_path = "./figures"
    logo_path = file_path + "/seeed_logo.png"
    out_img = file_path + '/seeed_logo_qr.jpg'
    text = input("Please enter:")
    create_qrcode(text, out_img, logo_path)

De parameters voor het aanmaken van QR-codes betekenen het volgende:

Codebestand: 7-2-2-3-qr-codes-example-03.py

python
'''
    Parameters:
    version:integer from 1 to 40 that controls QR-code size.
             use None with fit if you want the library to choose automatically.
    error_correction:controls QR-code error correction.
    ERROR_CORRECT_L:about 7% or fewer errors can be corrected.
    ERROR_CORRECT_M (default): about 15% or fewer errors can be corrected.
    ROR_CORRECT_H:about 30% or fewer errors can be corrected.
    box_size:controls the pixel size of each QR-code cell.
    border:controls the border width in cells; the default 4 is the standard minimum.
    '''

Wanneer u een tweedimensionale code genereert, kunt u deze afdrukken (A4-formaat is voldoende) voor de tweedimensionale herkenningstest.

De code-segmenten voor de herkenningsfunctie zijn als volgt:

Codebestand: 7-2-2-3-qr-codes-example-04.py

python
def decodeDisplay(image, font_path):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    # Convert decoded text to Unicode before drawing it on the image.
    barcodes = pyzbar.decode(gray)
    for barcode in barcodes:
        # Extract the QR code bounding box.
        (x, y, w, h) = barcode.rect
        # Draw the barcode bounding box on the image.
        cv.rectangle(image, (x, y), (x + w, y + h), (225, 0, 0), 5)
        encoding = 'UTF-8'
        # Convert the decoded bytes to a string before drawing.
        barcodeData = barcode.data.decode(encoding)
        barcodeType = barcode.type
        # Draw the decoded data and type on the image.
        pilimg = Image.fromarray(image)
        # Create a drawing object.
        draw = ImageDraw.Draw(pilimg)
        # Parameter 1: font file path. Parameter 2: font size.
        fontStyle = ImageFont.truetype(font_path, size=12, encoding=encoding)
        # Parameter 1: text position. Parameter 2: text. Parameter 3: text color. Parameter 4: font.
        draw.text((x, y - 25), str(barcode.data, encoding), fill=(255, 0, 0), font=fontStyle)
        # Convert the PIL image back to an OpenCV image.
        image = cv.cvtColor(np.array(pilimg), cv.COLOR_RGB2BGR)
        # Print barcode data and type to the terminal.
        print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))
    return image

In de qr code-herkenningsmap, start de detectie van de 2-dimensionale code:

python
qrcode_parsing_usb.py

De testresultaten worden hieronder geïllustreerd, en er wordt een testkader getekend nadat de 2D-code is geïdentificeerd.

Afbeeldingen

7.2.2.3 QR Codes figure 1

7.2.2.3 QR Codes figure 2

7.2.2.3 QR Codes figure 3

7.2.2.4 Menselijke poseschatting

Menselijke poseschatting

Inleiding

Menselijke houdingsbeoordeling is een op de computer gebaseerde visietechnologie, ontworpen om automatisch de locatie van de belangrijkste menselijke gewrichten te identificeren en te lokaliseren via afbeeldingen of video's en om de skeletstructuur van het menselijk lichaam te modelleren. Human Pose Estimation, dat op grote schaal wordt toegepast op het gebied van actie-identificatie, intelligente bewaking, menselijke interactie, motoranalyse, revalidatie en virtual reality, is een sleuteltechnologie voor het verbinden van "het menselijk lichaam zien" en "menselijk gedrag begrijpen".

II. Onderliggende principe

Ten eerste worden de ingevoerde menselijke afbeeldingen naar het volumetrische neurale netwerk (CNN) gestuurd voor karakterisering, met semantische profielen op hoog niveau; De netwerkstructuur werd vervolgens verdeeld in twee takken, één voor het voorspellen van Part Confidence Maps (Keypoint Confidence Chart), om de waarschijnlijkheidsverdeling van posities in de ruimte voor individuele menselijke gewrichten weer te geven, en de andere voor het voorspellen van Part Affinity Fields (PAF's, Body Associated Fields), om verbindingen en richtingsinformatie tussen verschillende gewrichten in vectorvorm te beschrijven. Op basis van de confidence map, die het kandidaatknooppunt detecteert, en met gebruik van de richtingsconsistentie-informatie die door PAF wordt geleverd, wordt de verbinding tussen de knooppunten gemodelleerd als het bipartite matching-probleem in het diagram, door de gewrichtsknooppunten die tot dezelfde persoon behoren correct te matchen en geleidelijk het volledige menselijke skelet op te bouwen. Verder wordt geschat dat multi-persoon houdingen kunnen worden beschouwd als een multi-person parsing-probleem, dat multi-punt verbindingen omzet in grafische matching-kwesties, en gebruikmaakt van de klassieke tweedimensionale matchingmethode, zoals het Hongaarse algoritme, om de beste combinatie van gewrichtsknooppunten te vinden en zo nauwkeurige en stabiele schattingen van meerdere menselijke houdingen te bereiken.

Start van de procedure

Toegang tot ROS 1 docker-images

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Installatieafhankelijkheid

bash
apt-get update
apt-get install -y libatlas-base-dev libprotobuf-dev protobuf-build
apt-get install python3-pip
pip install \
  https://files.pythonhosted.org/packages/c0/b7/20228024ef7bcfaa9cad2cb2514f3f7cc7a2c2c16715dc65cb01c793693c/mediapipe-0.10.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

# Check whether the installation succeeded.
python3 -c "import mediapipe as mp; print(mp.__version__)"

Gebruik van afbeeldingen voor inferentie

Ga naar de codebestandenmap, voer het codescript uit

bash
cd sources_code/ROS 1
python3 target_pose_img.py

Gebruik van video-inferentie

Voer codescript uit

bash
undefined

Afbeeldingen

7.2.2.4 Human Pose Estimation figure 1

7.2.2.4 Human Pose Estimation figure 2

7.2.2.4 Human Pose Estimation figure 3

7.2.2.5 Objectdetectie

Objectdetectie

In diepgaand leren is doeldetectie een van de kerntaken van computervisualisatie en is ontworpen om alle interessante objecten in de afbeelding te identificeren en te markeren. Veelgebruikte methoden vallen uiteen in twee hoofdcategorieën:

Tweetraps-testen: Vertegenwoordigde methode is R-CNN, Fast R-CNN, Fast R-CNN. Mr. Region Products, en classificeert en retourneert vervolgens elk kandidaatgebied. Deze methoden zijn zeer nauwkeurig, maar relatief langzaam en geschikt voor scenario's die hoge nauwkeurigheid vereisen.

Eentraps-testen: De vertegenwoordigde methode is YOLO (You Only Look Once), SSD (Single Shot MultiBox Detector). De objectcategorieën en begrenzingskaders worden direct op de feature maps geprojecteerd zonder dat kandidaatgebieden hoeven te worden gegenereerd, met een hoge snelheid geschikt voor realtime detectie, maar met een vroege nauwkeurigheid die iets lager is dan bij twee fasen.

Deze titel demonstreert hoe de dnn-module van OpenCV te gebruiken om de doeltest te realiseren

Programma starten

Afbeeldingen van inferentie

Ga naar de codemap, voer scripts uit

bash
cd sources_code/ROS 1
python3 target_detect_img.py

Logische camera's

Ga naar de codemap, voer scripts uit

bash
cd sources_code/ROS 1
python3 target_detect_video.py

7.2.2.6 AR-visie

AR-visueel

Augmented reality (AR) verwijst naar het gebruik van op de computer gebaseerde visietechnologie om virtuele informatie of driedimensionale modellen in realtime te superponeren op afbeeldingen of video's van de echte wereld, waardoor de perceptie en interactieve ervaring van de gebruiker met de omgeving wordt versterkt. Het bereikt ruimtelijke uitlijning en realtime interactie tussen virtuele objecten en de echte wereld door video-opname van scenario's uit het echte leven, gecombineerd met technologie zoals doeldetectie, kenmerkpunt-tracking en dieptebepaling, en wordt op grote schaal gebruikt op gebieden zoals spel en entertainment, industrieel ontwerp, onderwijs en training en navigatie.

Ga naar ROS 1 Docker-image

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Camera gemarkeerd.

ROS biedt officieel een camerakalibratiepakket om USB-camera's eenvoudig te markeren:

bash
apt install ros-noetic-camera-calibration
apt install ros-noetic-usb-cam

Start USB-cameraknooppunten

bash
roslaunch usb_cam usb_cam-test.launch

Voorbereiding van pallets

Download en print tablets voor A4-formaat

Start markeerknooppunten

Open een andere terminal naar de docker-image voor ROS 1, voer de gemarkeerde knooppunten uit

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

  rosrun camera_calibration cameracalibrator.py \
  --size 8x6 --square 0.025 image:=/usb_cam/image_raw camera:=/usb_cam

Parameterbeschrijving:

--size 8x6: Aantal interne hoeken (kolom x rij) (8x6 = 48 hoeken van een 9x7-raster)

--square 0.025: elk vierkant lang, eenheid m (24mm)

Afbeeldingsonderwerp

Camera: =/usb_cam: Camera-naamruimte

Markeerinterface

X: Links en rechts bewegen van schaakvelden in het camerabeeld

Y: Schaakvakken die op en neer bewegen in het camerabeeld

Grootte: Heen en weer van het bord in het camerabeeld

Skew: Schaakvak gekanteld in het camerabeeld

Na een succesvolle start wordt het bord in het midden van de afbeelding geplaatst, waarbij de posities veranderen. Het systeem zal zichzelf identificeren, het beste is dat de lijnen onder X, Y, Size, Skew zoveel mogelijk gevuld worden met gegevensverzameling van rood naar geel.

Klik op Calibrate om de binnenkant van de camera te berekenen, wat aangeeft dat de interface mogelijk geen reactie toont, maar de terminal heeft nog steeds een output en wacht!

Na een succesvolle berekening toont de terminal de parameters van de camera en klikt u op SAVE om de cameraparameters op te slaan.

Het resultaat wordt standaard opgeslagen in /tmp/calibrationdata.tar.gz

Pak het uit en verplaats het naar tag-parameters. yaml-bestanden naar de scriptcodemap

bash
mv tmp/ost.yaml /source_code/ROS 1/sources

Script uitvoeren

Voer het AR-script uit in de ROS 1 Docker-container:

bash
python3 simple_AR.py

Codebestand: 7-2-2-6-ar-vision-example-01.py

python
#!/usr/bin/env python3
# simple_AR.py
# common lib
import os
import sys
import time
import cv2 as cv
import numpy as np
import yaml

print("import done")

cv_edition = cv.__version__
print("cv_edition: ",cv_edition)

def load_camera_from_ost(yaml_path: str):
    with open(yaml_path, 'r') as f:
        params = yaml.safe_load(f)
    camera_data = params['camera_matrix']['data']
    dist_data = params['distortion_coefficients']['data']
    camera_matrix = np.array(camera_data, dtype=np.float32).reshape(3, 3)
    dist_coeffs = np.array(dist_data, dtype=np.float32).reshape(-1, 1)
    return camera_matrix, dist_coeffs

def draw_stickman(img, img_pts):
    cv.line(img, tuple(img_pts[18]), tuple(img_pts[4]), (0, 0, 255), 3)
    cv.line(img, tuple(img_pts[18]), tuple(img_pts[6]), (0, 0, 255), 3)
    cv.line(img, tuple(img_pts[18]), tuple(img_pts[21]), (0, 0, 255), 3)
    cv.line(img, tuple(img_pts[21]), tuple(img_pts[19]), (0, 0, 255), 3)
    cv.line(img, tuple(img_pts[21]), tuple(img_pts[20]), (0, 0, 255), 3)
    cv.line(img, tuple(img_pts[21]), tuple(img_pts[22]), (0, 0, 255), 3)
    cv.circle(img, tuple(img_pts[22]), 15, (0, 0, 255), -1)
    cv.line(img, tuple(img_pts[74]), tuple(img_pts[72]), (0, 255, 0), 3)
    cv.line(img, tuple(img_pts[74]), tuple(img_pts[73]), (0, 255, 0), 3)
    cv.line(img, tuple(img_pts[74]), tuple(img_pts[37]), (0, 255, 0), 3)
    cv.line(img, tuple(img_pts[37]), tuple(img_pts[76]), (0, 255, 0), 3)
    cv.line(img, tuple(img_pts[37]), tuple(img_pts[77]), (0, 255, 0), 3)
    cv.line(img, tuple(img_pts[37]), tuple(img_pts[75]), (0, 255, 0), 3)
    cv.circle(img, tuple(img_pts[75]), 15, (0, 255, 0), -1)
    return img

def main():
    print("start")

    pattern_size = (8,6)
    yaml_path = os.path.join(os.path.dirname(__file__), 'sources', 'ost.yaml')
    camera_matrix, dist_coeffs = load_camera_from_ost(yaml_path)

    object_points = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
    object_points[:,:2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)

    axis = np.float32([
            [0, 0, -1], [0, 8, -1], [5, 8, -1], [5, 0, -1],
            [1, 2, -1], [1, 6, -1], [4, 2, -1], [4, 6, -1],
            [1, 0, -4], [1, 8, -4], [4, 0, -4], [4, 8, -4],
            [1, 2, -4], [1, 6, -4], [4, 2, -4], [4, 6, -4],
            [0, 1, -4], [3, 2, -1], [2, 2, -3], [3, 2, -3],
            [1, 2, -3], [2, 2, -4], [2, 2, -5], [0, 4, -4],
            [2, 3, -4], [1, 3, -4], [4, 3, -5], [4, 5, -5],
            [1, 2, -3], [1, 6, -3], [5, 2, -3], [5, 6, -3],
            [3, 4, -5], [0, 6, -4], [5, 6, -4], [2, 8, -4],
            [3, 8, -4], [2, 6, -4], [2, 0, -4], [1, 5, -4],
            [3, 0, -4], [3, 2, -4], [0, 3, -4], [1, 2, -4],
            [4, 2, -4], [5, 3, -4], [2, 7, -4], [3, 7, -4],
            [3, 3, -1], [3, 5, -1], [1, 5, -1], [1, 3, -1],
            [3, 3, -3], [3, 5, -3], [1, 5, -3], [1, 3, -3],
            [1, 3, -6], [1, 5, -6], [3, 3, -4], [3, 5, -4],
            [0, 0, -4], [3, 1, -4], [1, 1, -4], [0, 2, -4],
            [2, 4, -4], [4, 4, -4], [0, 8, -4], [5, 8, -4],
            [5, 0, -4], [0, 4, -5], [5, 4, -4], [5, 4, -5],
            [2, 5, -1], [2, 7, -1], [2, 6, -3], [2, 6, -5],
            [2, 5, -3], [2, 7, -3]
            ])

    capture = cv.VideoCapture(0)
    if cv_edition[0] == '3':
        capture.set(cv.CAP_PROP_FOURCC, cv.VideoWriter_fourcc(*'XVID'))
    else:
        capture.set(cv.CAP_PROP_FOURCC, cv.VideoWriter.fourcc('M', 'J', 'P', 'G'))
    capture.set(6, cv.VideoWriter_fourcc('M', 'J', 'P', 'G'))
    capture.set(cv.CAP_PROP_FRAME_WIDTH, 640)
    capture.set(cv.CAP_PROP_FRAME_HEIGHT, 480)

    last_time = time.time()
    fps = 0.0

    while True:
        ret, frame = capture.read()
        if not ret:
            break

        now = time.time()
        fps = 1.0 / max(1e-6, (now - last_time))
        last_time = now
        gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

        retval, corners = cv.findChessboardCorners(
            gray,
            pattern_size,
            None,
            flags=cv.CALIB_CB_ADAPTIVE_THRESH + cv.CALIB_CB_NORMALIZE_IMAGE + cv.CALIB_CB_FAST_CHECK,
        )

        if retval:
            corners = cv.cornerSubPix(
                gray,
                corners,
                (11, 11),
                (-1, -1),
                (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001),
            )
            retval, rvec, tvec, _inliers = cv.solvePnPRansac(
                object_points,
                corners,
                camera_matrix,
                dist_coeffs,
            )
            if retval:
                image_points, _jacobian = cv.projectPoints(
                    axis,
                    rvec,
                    tvec,
                    camera_matrix,
                    dist_coeffs,
                )
                img_pts = np.int32(image_points).reshape(-1, 2)
                frame = draw_stickman(frame, img_pts)

                cv.putText(frame, "AR Active - 2 Stickman", (10, 60), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
            else:
                cv.putText(frame, "Pose estimation failed", (10, 60), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
        else:
            cv.putText(frame, "No chessboard detected", (10, 60), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)

        cv.putText(frame, f"FPS: {fps:.1f}", (10, 30), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        cv.imshow('frame', frame)

        action = cv.waitKey(1) & 0xFF
        if action == ord('q') or action == 113:
            break

    capture.release()
    cv.destroyAllWindows()

if __name__ == "__main__":
    main()

Afbeeldingen

7.2.2.6 AR Vision figure 1

7.2.2.6 AR Vision figure 2

7.2.2.6 AR Vision figure 3

7.2.2.6 AR Vision figure 4

7.2.2.6 AR Vision figure 5

7.2.2.6 AR Vision figure 6

7.2.2.6 AR Vision figure 7

7.2.2.7 OpenCV-toepassingen

OpenCV-toepassing

Opencv apps is een set functionaliteitspakketten die door de ROS-community wordt onderhouden, en die een groot aantal OpenCV-beeldverwerkings- en computervisualisatiefuncties inkapselt in ROS-knooppunten, waardoor de invoer van een standaardonderwerp direct kan worden aangeroepen in het ROS-systeem, zonder dat de OpenCV-code zelf hoeft te worden voorbereid.

Start Opencv apps

Start docker

bash
sudo docker run -it \
  --name ros_noetic \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Installatie

bash
apt install ros-noetic-opencv-apps
apt install -y ros-noetic-usb-cam


# Check whether the installation succeeded.
roscd opencv_apps
# Open another terminal.
sudo docker exec -it ros_noetic bash

rosrun opencv_apps face_detection image:=/usb_cam/image_raw

Activeer camera

bash
roslaunch usb_cam usb_cam-test.launch

Gebruik Opencv apps

Er kan slechts één functie tegelijk worden uitgevoerd. Het commando moet worden uitgevoerd nadat de camera is geactiveerd:

bash
roslaunch opencv_apps face_recognition.launch image:=/usb_cam/image_raw          # Face recognition
roslaunch opencv_apps corner_harris.launch image:=/usb_cam/image_raw             # Harris corner detection
roslaunch opencv_apps camshift.launch image:=/usb_cam/image_raw                  # Object tracking
roslaunch opencv_apps contour_moments.launch image:=/usb_cam/image_raw           # Contour moments
roslaunch opencv_apps convex_hull.launch image:=/usb_cam/image_raw               # Convex hull
roslaunch opencv_apps discrete_fourier_transform.launch image:=/usb_cam/image_raw # Discrete Fourier transform
roslaunch opencv_apps edge_detection.launch image:=/usb_cam/image_raw            # Edge detection
roslaunch opencv_apps face_detection.launch image:=/usb_cam/image_raw            # Face detection
roslaunch opencv_apps fback_flow.launch image:=/usb_cam/image_raw                # Optical flow detection
roslaunch opencv_apps find_contours.launch image:=/usb_cam/image_raw             # Contour detection
roslaunch opencv_apps general_contours.launch image:=/usb_cam/image_raw          # General contour detection
roslaunch opencv_apps goodfeature_track.launch image:=/usb_cam/image_raw         # Feature point tracking
roslaunch opencv_apps hls_color_filter.launch image:=/usb_cam/image_raw          # HLS color filtering
roslaunch opencv_apps hough_circles.launch image:=/usb_cam/image_raw             # Hough circle detection
roslaunch opencv_apps hough_lines.launch image:=/usb_cam/image_raw               # Hough line detection
roslaunch opencv_apps hsv_color_filter.launch image:=/usb_cam/image_raw          # HSV color filtering
roslaunch opencv_apps lk_flow.launch image:=/usb_cam/image_raw                   # LKoptical flow algorithm
roslaunch opencv_apps people_detect.launch image:=/usb_cam/image_raw             # People detection
roslaunch opencv_apps phase_corr.launch image:=/usb_cam/image_raw                # Phase correlation displacement detection
roslaunch opencv_apps pyramids.launch image:=/usb_cam/image_raw                  # Image pyramid
roslaunch opencv_apps rgb_color_filter.launch image:=/usb_cam/image_raw          # RGB color filtering
roslaunch opencv_apps segment_objects.launch image:=/usb_cam/image_raw           # Foreground segmentation
roslaunch opencv_apps simple_flow.launch image:=/usb_cam/image_raw               # Simple optical flow
roslaunch opencv_apps smoothing.launch image:=/usb_cam/image_raw                 # Smoothing filter
roslaunch opencv_apps threshold.launch image:=/usb_cam/image_raw                 # Thresholding
roslaunch opencv_apps watershed_segmentation.launch image:=/usb_cam/image_raw    # Watershed segmentation

Voorvertoning

Activeer de camera en activeer een van de functies van Opencv apps om de afbeelding op de volgende manier te bekijken.

Lokale toegang

Voer het volgende commando in en selecteer het bijbehorende onderwerp om het effect te zien:

rqt image view

LAN-weergave

Op hetzelfde lokale netwerk voert u IP:poort (8080) in de browser in, bijvoorbeeld:

192.168.7.47:8080 # IP verwijst naar host-IP

Referenties

wiki: http://wiki.ros.org/opencv_apps

Bron: https://github.com/ros-perception/opencv_apps.git

Het grootste deel van de code is oorspronkelijk afkomstig van https://github.com/Itseez/opencv/tree/master/samples/cpp.

7.2.2.8 ROS + OpenCV-fundamenten

Functie-overzicht

ROS heeft OpenCV (3.x en hoger) al tijdens de installatie samengesteld, en de afbeeldingen worden in RS overgebracht in het sensor msgs/Image-berichtformaat en kunnen niet rechtstreeks met OpenCV worden verwerkt. Hiervoor biedt ROS cv bridge voor:

Een efficiënte conversie tussen ROS Image ↔ OpenCV Mat (nompy array) is de centrale brug voor ROS-beeldverwerking.

Functiepakket-afhankelijkheidsconfiguratie

package.xml

Codebestand: 7-2-2-8-ros-plus-opencv-fundamentals-package.xml

bash
<?xml version="1.0"?>
<package format="2">
  <name>ros_opencv_demo</name>
  <version>0.0.1</version>
  <description>
    ROS + OpenCV sample package that uses cv_bridge to subscribe to USB camera images and process them with OpenCV.
  </description>

  <!-- maintainer information -->
  <maintainer email="you@example.com">your_name</maintainer>

  <!-- open-source license -->
  <license>BSD</license>

  <!-- build tool -->
  <buildtool_depend>catkin</buildtool_depend>

  <!-- ================= core dependencies ================= -->

  <!-- Python / ROS -->
  <depend>rospy</depend>

  <!-- ROS messages -->
  <depend>std_msgs</depend>
  <depend>sensor_msgs</depend>

  <!-- image-related dependencies -->
  <depend>cv_bridge</depend>
  <depend>image_transport</depend>

  <!-- Optional: enable this if you use PCL later. -->
  <!-- <depend>pcl_ros</depend> -->

  <!-- ================= optional exports ================= -->
  <export>
  </export>

</package>

CMakeLists.txt (Python-knooppunt geminimaliseerd)

Codebestand: 7-2-2-8-ros-plus-opencv-fundamentals-example-02.cmake

bash
cmake_minimum_required(VERSION 3.0.2)
project(ros_opencv_demo)
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  sensor_msgs
  cv_bridge
  image_transport
)
catkin_package()
include_directories(
  ${catkin_INCLUDE_DIRS}
)

Start USB-cameraknooppunt

bash
# Install dependencies if needed.
apt install -y ros-noetic-usb-cam
roslaunch usb_cam usb_cam-test.launch

Kleurafbeeldingabonnementknooppunt (volledige code)

Bestandsnaam: usb_cam_image.py

Codebestand: 7-2-2-8-ros-plus-opencv-fundamentals-usb_cam_image.py

bash
#!/usr/bin/env python3

import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError


class UsbCamImageNode:
    def __init__(self):
        rospy.init_node("usb_cam_image_node", anonymous=True)

        self.bridge = CvBridge()

        # subscribe to USB camera images
        self.image_sub = rospy.Subscriber(
            "/usb_cam/image_raw",
            Image,
            self.image_callback,
            queue_size=1
        )

        rospy.loginfo("USB Camera Image Subscriber Started")

    def image_callback(self, msg):
        try:
            # ROS Image → OpenCV BGR
            frame = self.bridge.imgmsg_to_cv2(msg, desired_encoding="bgr8")
        except CvBridgeError as e:
            rospy.logerr(e)
            return

        # display the image
        cv2.imshow("USB Camera Image", frame)
        cv2.waitKey(1)


if __name__ == "__main__":
    try:
        UsbCamImageNode()
        rospy.spin()
    except rospy.ROSInterruptException:
        pass
    finally:
        cv2.destroyAllWindows()

Uitvoeringsrechten verlenen

bash
chmod +x usb_cam_image.py
cd /ros_ws
catkin_make

Voorbeeld uitvoeren

Multi-terminaltool installeren

bash
apt-get install terminator
# Run
terminator

Open een andere terminal horizontaal met de ctrl + Shift + o-sneltoets in de pop-up terminalinterface

Terminal 1: Start camera.

Roslaunch usb cam usb cam-test.launch

Terminal 2: Abonnementsknooppunt uitvoeren

rosrun ros opencv demo usb_cam_image.py

U ziet een OpenCV-venster dat USB-camera's in realtime weergeeft.

Bekijk knooppuntcommunicatie

Start een andere terminalbewerking:

bash
rqt_graph

Afbeeldingen

7.2.2.8 ROS + OpenCV Fundamentals figure 1

7.2.2.8 ROS + OpenCV Fundamentals figure 2

7.2.2.8 ROS + OpenCV Fundamentals figure 3

7.2.2.9 MediaPipe-ontwikkeling

MediaPipe-introductie

MediaPipe is een krachtig platformonafhankelijk sensorberekeningsframework, opensource door Google, gewijd aan het bouwen van realtime visuele en multimodulaire verwerkingsstromen. Het wordt uitgebreid gebruikt voor taken zoals menselijke houdingsschatting, handherkenning, gezichtsdetectie en keypoint-tracking, door middel van een grafische berekening (Graph), die de modules van camera-invoer, modelinferentie en herverwerking efficiënt met elkaar verbindt. MediaPipe omvat een verscheidenheid aan lichte kwantitatieve diepe leermodellen die realtime CPU-inferentie ondersteunen en zeer vriendelijk zijn voor embedded platforms (bijv. Jetson, mobiel), en ontwikkelaars kunnen snel stabiele, laag vertraagde realtime sensorische toepassingen realiseren met een klein aantal codes.

Diep-leeroplossingen in MediaPipe

Klik op een afbeelding om het volledige spreadsheet te bekijken

Start docker

bash
sudo docker run -it \
  --net=host \
  --privileged \
  -v /dev:/dev \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -e DISPLAY=$DISPLAY \
  -e QT_X11_NO_MITSHM=1 \
  ros:noetic

Gebruikte case

Handtest

bash
cd sources_code/ROS 1/mediapipe
python3 hand.py

Gezichtscontrole.

bash
cd sources_code/ROS 1/mediapipe
python3 face_detection.py

Gezichtseffecten.

bash
cd sources_code/ROS 1/mediapipe
python3 face_effect.py

D-objectidentificatie

bash
cd sources_code/ROS 1/mediapipe
python3 object_reg.py

Kwast

bash
cd sources_code/ROS 1/mediapipe
python3 virtual_brush.py

Gebarenherkenning.

bash
cd sources_code/ROS 1/mediapipe
python3 gesture_recognition.py

Vingerbesturing.

bash
cd sources_code/ROS 1/mediapipe
python3 hand_control.py

Houding

bash
cd sources_code/ROS 1/mediapipe
python3 pose_estimation.py

Gezichtstest

bash
cd sources_code/ROS 1/mediapipe
python3 face_mesh.py

Algehele test

bash
cd sources_code/ROS 1/mediapipe
python3 holistic.py

Case-splitsing

bash
cd sources_code/ROS 1/mediapipe
python3 selfie_segmentation.py

Afbeeldingen

7.2.2.9 MediaPipe Development figure 1

7.2.2.9 MediaPipe Development figure 2

7.2.2.9 MediaPipe Development figure 3

7.2.2.9 MediaPipe Development figure 4

7.2.2.9 MediaPipe Development figure 5

7.2.2.9 MediaPipe Development figure 6

7.2.2.9 MediaPipe Development figure 7

7.2.2.9 MediaPipe Development figure 8

7.2.2.9 MediaPipe Development figure 9

7.2.2.9 MediaPipe Development figure 10

7.2.2.9 MediaPipe Development figure 11

7.2.2.9 MediaPipe Development figure 12

7.2.2.9 MediaPipe Development figure 13