Menepati janji saya beberapa bulan yang lalu dimana saya akan membagi hasil proyek bersama profesor atletik di unesa, maka beberapa episode tulisan saya akan membahas mengenai pemanfaatan pendeteksi marker yang bernama Aruco-AprilTag. Gambar animasi diatas terlihat mahasiswa yang berlari menggunakan topi lucu dengan code kotak disamping. Apakah itu ?
Dalam dunia computer vision, kemampuan untuk mendeteksi dan melokalisasi objek secara akurat merupakan hal yang sangat penting, terutama dalam aplikasi robotika, augmented reality, drone, dan sistem navigasi otomatis. Salah satu teknologi yang populer digunakan untuk kebutuhan ini adalah ArUco dan AprilTag — dua jenis penanda (fiducial marker) yang memungkinkan mesin mengenali posisi dan orientasi suatu objek dengan presisi tinggi dan latensi rendah.
Meskipun memiliki tujuan serupa, kedua teknologi ini memiliki perbedaan mendasar dalam pendekatan algoritma, struktur marker, serta performa deteksi. Dalam artikel ini, kita akan menjelajahi bagaimana kedua sistem bekerja, lalu fokus pada implementasi penggunaannya menggunakan Python dan OpenCV, lengkap dengan contoh kode sederhana yang bisa langsung Anda coba sendiri.
Apakah Anda seorang penggemar robotika, developer AR/VR, atau sekadar tertarik dengan teknologi visi komputer? Artikel ini akan memberikan dasar yang kuat untuk memahami dan mulai memanfaatkan ArUco dan AprilTag dalam proyek-proyek Anda berikutnya.
Perhatikan gambar diatas yang saya generate melalui website ( https://chev.me/arucogen/) untuk mencetak gambar aruco DICT 5x5. Kita ubah menjadi kotak hitam dan putih dan binarynya seperti berikut:
[0, 1, 1, 1, 0]
[1, 0, 0, 0, 1]
[1, 0, 1, 0, 1]
[1, 0, 0, 0, 1]
[0, 1, 1, 1, 0]
Langkah konversi:
1. Flattening matriks : semua baris disusun menjadi satu dimensi.
misal: [1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1]
2. Menghitung nilai hash/biner unik : ini dilakukan oleh library OpenCV secara internal menggunakan algoritma tertentu (tergantung dictionary).
3. Pencarian ID : Hash tersebut dibandingkan dengan semua marker yang ada di dictionary untuk menemukan ID uniknya.
Misalnya, jika cocok dengan marker ID 23 dalam dictionary, maka sistem akan mengembalikan nilai id = 23.
🔄 Visualisasi Proses (secara logis):
Gambar Asli → Thresholding → Crop & Warp → Matriks Biner → Flattening → Hash/ID → Cocokkan dengan Dictionary → Dapatkan ID Marker
💡 Catatan Penting:
- Tidak semua pola biner bisa jadi ID valid — hanya pola-pola yang sudah ditentukan dalam dictionary ArUco yang dikenali.
- Jika pola tidak cocok, sistem akan mengabaikannya atau menandainya sebagai marker tidak dikenal.
- AprilTag bekerja dengan prinsip serupa, tapi menggunakan pendekatan deteksi dan encoding yang sedikit berbeda (lebih toleran terhadap noise dan rotasi).
- import cv2
- import numpy as np
- import winsound
- import time
- # Initialize the AprilTag detector with the 36h11 dictionary
- aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_APRILTAG_36H11)
- parameters = cv2.aruco.DetectorParameters()
- # Create the detector
- detector = cv2.aruco.ArucoDetector(aruco_dict, parameters)
- # Beep function (runs in a separate thread)
- def beep():
- winsound.Beep(1000, 200) # Frequency: 1000 Hz, Duration: 200 ms
- #winsound.PlaySound('beep.wav', winsound.SND_FILENAME)
- # Open webcam
- cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
- cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
- cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
- if not cap.isOpened():
- print("Failed to open webcam.")
- exit()
- frame_count = 0
- try:
- while True:
- ret, frame = cap.read()
- if not ret:
- print("Failed to grab frame. Reconnecting...")
- cap.release()
- e
- # Only process every 15th frame to save computational effort
- frame_count += 1
- if frame_count % 5 != 0:
- continue
- # Convert the frame to grayscale (required for detection)
- gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- # Detect AprilTags
- corners, ids, _ = detector.detectMarkers(gray)
- # If any tags are detected
- if ids is not None:
- for corner, tag_id in zip(corners, ids.flatten()):
- # Draw the bounding box
- int_corners = corner.astype(np.intp)
- cv2.polylines(frame, [int_corners], isClosed=True, color=(0, 255, 0), thickness=2)
- # Display the tag ID
- tag_id_str = f"ID: {tag_id}"
- cv2.putText(frame, tag_id_str, (int_corners[0][0][0], int_corners[0][0][1] - 10),
- cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
- #beep sound
- beep()
- print(f"Detected IDs: {ids.flatten()}")
- frame_resized = cv2.resize(frame, (800,600))
- # Show the resized video feed
- cv2.imshow("IP Camera apriltag Code Detection - press q to quit", frame_resized)
- # Quit if 'q' is pressed
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
- except KeyboardInterrupt:
- print("Program interrupted.")
- finally:
- # Release the resources
- cap.release()
- cv2.destroyAllWindows()
0 komentar:
Posting Komentar