İçeriğe geç

ROS (Robot İşletim Sistemi) hızlı başlangıç kılavuzu

ROS Tanıtımı (altyazılı), Open Robotics tarafından Vimeo üzerinde.

ROS nedir?

Robot İşletim Sistemi (ROS), robotik araştırma ve endüstrisinde yaygın olarak kullanılan açık kaynaklı bir çerçevedir. ROS, geliştiricilerin robot uygulamaları oluşturmasına yardımcı olmak için bir kütüphane ve araç koleksiyonu sağlar. ROS, çeşitli robotik platformlarla çalışmak üzere tasarlanmıştır ve bu da onu robot uzmanları için esnek ve güçlü bir araç haline getirir.

ROS'un Temel Özellikleri

  1. Modüler Mimari: ROS, modüler bir mimariye sahiptir ve geliştiricilerin düğümler adı verilen daha küçük, yeniden kullanılabilir bileşenleri birleştirerek karmaşık sistemler oluşturmasına olanak tanır. Her düğüm genellikle belirli bir işlevi yerine getirir ve düğümler konular veya hizmetler üzerinden mesajlar kullanarak birbirleriyle iletişim kurar.

  2. İletişim Ara Katmanı: ROS, süreçler arası iletişimi ve dağıtık hesaplamayı destekleyen sağlam bir iletişim altyapısı sunar. Bu, veri akışları (konular) için bir yayınlama-abonelik modeli ve hizmet çağrıları için bir istek-yanıt modeli aracılığıyla sağlanır.

  3. Donanım Soyutlaması: ROS, donanım üzerinde bir soyutlama katmanı sağlayarak geliştiricilerin aygıttan bağımsız kod yazmasına olanak tanır. Bu, aynı kodun farklı donanım kurulumlarıyla kullanılmasını sağlayarak daha kolay entegrasyon ve denemeyi kolaylaştırır.

  4. Araçlar ve Yardımcı Programlar: ROS, görselleştirme, hata ayıklama ve simülasyon için zengin bir araç ve yardımcı program setiyle birlikte gelir. Örneğin, RViz sensör verilerini ve robot durum bilgilerini görselleştirmek için kullanılırken, Gazebo algoritmaları ve robot tasarımlarını test etmek için güçlü bir simülasyon ortamı sağlar.

  5. Kapsamlı Ekosistem: ROS ekosistemi geniştir ve sürekli olarak büyümektedir; navigasyon, manipülasyon, algılama ve daha fazlası dahil olmak üzere farklı robotik uygulamalar için çok sayıda paket mevcuttur. Topluluk, bu paketlerin geliştirilmesine ve bakımına aktif olarak katkıda bulunur.

ROS Sürümlerinin Evrimi

ROS, 2007'deki gelişiminden bu yana, robotik topluluğunun artan ihtiyaçlarını karşılamak için her biri yeni özellikler ve iyileştirmeler sunan birden çok sürümden geçti. ROS'un geliştirilmesi iki ana seriye ayrılabilir: ROS 1 ve ROS 2. Bu kılavuz, ROS Noetic Ninjemys olarak bilinen ROS 1'in Uzun Süreli Destek (LTS) sürümüne odaklanmaktadır, kod önceki sürümlerle de çalışmalıdır.

ROS 1 - ROS 2 karşılaştırması

ROS 1 robotik geliştirme için sağlam bir temel sağlarken, ROS 2 aşağıdaki özellikleri sunarak eksikliklerini giderir:

  • Gerçek Zamanlı Performans: Gerçek zamanlı sistemler ve deterministik davranış için iyileştirilmiş destek.
  • Güvenlik: Çeşitli ortamlarda güvenli ve güvenilir çalışma için gelişmiş güvenlik özellikleri.
  • Ölçeklenebilirlik: Çoklu robot sistemleri ve büyük ölçekli dağıtımlar için daha iyi destek.
  • Çapraz Platform Desteği: Windows ve macOS dahil olmak üzere Linux'un ötesinde çeşitli işletim sistemleriyle genişletilmiş uyumluluk.
  • Esnek İletişim: Daha esnek ve verimli süreçler arası iletişim için DDS kullanımı.

ROS Mesajları ve Konuları

ROS'ta, düğümler arasındaki iletişim mesajlar ve konular aracılığıyla kolaylaştırılır. Mesaj, düğümler arasında değiş tokuş edilen bilgileri tanımlayan bir veri yapısıdır, konu ise mesajların gönderilip alındığı adlandırılmış bir kanaldır. Düğümler bir konuya mesaj yayınlayabilir veya bir konudan mesajlara abone olabilir, bu da birbirleriyle iletişim kurmalarını sağlar. Bu yayınlama-abonelik modeli, düğümler arasında eşzamansız iletişime ve ayrışmaya olanak tanır. Bir robotik sistemdeki her sensör veya aktüatör tipik olarak bir konuya veri yayınlar ve bu da diğer düğümler tarafından işleme veya kontrol için tüketilebilir. Bu kılavuzun amacı doğrultusunda, Görüntü, Derinlik ve Nokta Bulutu mesajlarına ve kamera konularına odaklanacağız.

ROS ile Ultralytics YOLO Kurulumu

Bu kılavuz, bu ROS ortamı kullanılarak test edilmiştir; bu ortam, ROSbot ROS deposunun bir çatallanmış halidir. Bu ortam, Ultralytics YOLO paketini, kolay kurulum için bir Docker konteynerini, kapsamlı ROS paketlerini ve hızlı test için Gazebo dünyalarını içerir. Husarion ROSbot 2 PRO ile çalışmak üzere tasarlanmıştır. Sağlanan kod örnekleri, simülasyon ve gerçek dünya dahil olmak üzere herhangi bir ROS Noetic/Melodic ortamında çalışacaktır.

Husarion ROSbot 2 PRO

Bağımlılıkların Kurulumu

ROS ortamının yanı sıra, aşağıdaki bağımlılıkları da yüklemeniz gerekecektir:

  • ROS Numpy paketi: Bu, ROS Görüntü mesajları ve numpy dizileri arasında hızlı dönüşüm için gereklidir.

    pip install ros_numpy
    
  • Ultralytics paketi:

    pip install ultralytics
    

Ultralytics'i ROS ile kullanın sensor_msgs/Image

sensor_msgs/Image mesaj türü genellikle ROS'ta görüntü verilerini temsil etmek için kullanılır. Kodlama, yükseklik, genişlik ve piksel verileri için alanlar içerir, bu da onu kameralar veya diğer sensörler tarafından yakalanan görüntüleri iletmek için uygun hale getirir. Görüntü mesajları, görsel algılama gibi robotik uygulamalarda yaygın olarak kullanılır, nesne tespiti, ve navigasyon.

ROS Gazebo'da Tespit ve Segmentasyon

Görüntü Adım Adım Kullanım

Aşağıdaki kod parçacığı, Ultralytics YOLO paketinin ROS ile nasıl kullanılacağını göstermektedir. Bu örnekte, bir kamera konusuna abone oluyoruz, gelen görüntüyü YOLO kullanarak işliyoruz ve algılanan nesneleri algılama ve segmentasyon için yeni konulara yayınlıyoruz.

İlk olarak, gerekli kitaplıkları içe aktarın ve iki model örneği oluşturun: biri segmentasyon ve biri de tespit. Bir ROS düğümü başlatın (şu adla: ultralytics), ROS master ile iletişimi etkinleştirmek için. Kararlı bir bağlantı sağlamak için, düğüme devam etmeden önce bağlantıyı kurması için yeterli zaman tanıyan kısa bir duraklama ekliyoruz.

import time

import rospy

from ultralytics import YOLO

detection_model = YOLO("yolo11m.pt")
segmentation_model = YOLO("yolo11m-seg.pt")
rospy.init_node("ultralytics")
time.sleep(1)

İki ROS konusunu başlat: biri tespit ve biri de segmentasyon. Bu konular, etiketli görüntüleri yayınlamak için kullanılacak ve bu görüntülerin daha fazla işlenmesi için erişilebilir hale getirilmesini sağlayacaktır. Düğümler arasındaki iletişim şu kullanılarak kolaylaştırılır: sensor_msgs/Image mesajları.

from sensor_msgs.msg import Image

det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)
seg_image_pub = rospy.Publisher("/ultralytics/segmentation/image", Image, queue_size=5)

Son olarak, üzerinde mesajları dinleyen bir abone oluşturun /camera/color/image_raw konuyu dinler ve her yeni mesaj için bir geri çağırma fonksiyonunu tetikler. Bu geri çağırma fonksiyonu, türünde mesajlar alır sensor_msgs/Image, kullanarak bunları bir numpy dizisine dönüştürür. ros_numpy, görüntüleri önceden örneklendirilmiş YOLO modelleriyle işler, görüntüleri etiketler ve ardından bunları ilgili konulara geri yayınlar: /ultralytics/detection/image tespit için ve /ultralytics/segmentation/image segmentasyon için.

import ros_numpy


def callback(data):
    """Callback function to process image and publish annotated images."""
    array = ros_numpy.numpify(data)
    if det_image_pub.get_num_connections():
        det_result = detection_model(array)
        det_annotated = det_result[0].plot(show=False)
        det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))

    if seg_image_pub.get_num_connections():
        seg_result = segmentation_model(array)
        seg_annotated = seg_result[0].plot(show=False)
        seg_image_pub.publish(ros_numpy.msgify(Image, seg_annotated, encoding="rgb8"))


rospy.Subscriber("/camera/color/image_raw", Image, callback)

while True:
    rospy.spin()
Tam kod
import time

import ros_numpy
import rospy
from sensor_msgs.msg import Image

from ultralytics import YOLO

detection_model = YOLO("yolo11m.pt")
segmentation_model = YOLO("yolo11m-seg.pt")
rospy.init_node("ultralytics")
time.sleep(1)

det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)
seg_image_pub = rospy.Publisher("/ultralytics/segmentation/image", Image, queue_size=5)


def callback(data):
    """Callback function to process image and publish annotated images."""
    array = ros_numpy.numpify(data)
    if det_image_pub.get_num_connections():
        det_result = detection_model(array)
        det_annotated = det_result[0].plot(show=False)
        det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))

    if seg_image_pub.get_num_connections():
        seg_result = segmentation_model(array)
        seg_annotated = seg_result[0].plot(show=False)
        seg_image_pub.publish(ros_numpy.msgify(Image, seg_annotated, encoding="rgb8"))


rospy.Subscriber("/camera/color/image_raw", Image, callback)

while True:
    rospy.spin()
Hata Ayıklama

ROS (Robot İşletim Sistemi) düğümlerinde hata ayıklamak, sistemin dağıtık yapısı nedeniyle zorlu olabilir. Bu süreçte yardımcı olabilecek çeşitli araçlar bulunmaktadır:

  1. rostopic echo <TOPIC-NAME> : Bu komut, belirli bir konuda yayınlanan mesajları görüntülemenizi sağlayarak veri akışını incelemenize yardımcı olur.
  2. rostopic list: ROS sistemindeki mevcut tüm konuları listelemek ve size aktif veri akışlarına genel bir bakış sunmak için bu komutu kullanın.
  3. rqt_graph: Bu görselleştirme aracı, düğümler arasındaki iletişim grafiğini görüntüleyerek düğümlerin nasıl birbirine bağlı olduğu ve nasıl etkileşimde bulunduğu hakkında bilgi sağlar.
  4. 3D gösterimler gibi daha karmaşık görselleştirmeler için şunları kullanabilirsiniz: RViz. RViz (ROS Görselleştirme), ROS için güçlü bir 3D görselleştirme aracıdır. Robotunuzun ve ortamının durumunu gerçek zamanlı olarak görselleştirmenizi sağlar. RViz ile sensör verilerini (örneğin, sensors_msgs/Image), robot modeli durumları ve diğer çeşitli bilgi türleri dahil olmak üzere robotik sisteminizin davranışını hata ayıklamayı ve anlamayı kolaylaştırır.

Algılanan Sınıfları Şununla Yayınla std_msgs/String

Standart ROS mesajları da şunları içerir: std_msgs/String mesajları. Birçok uygulamada, tüm açıklamalı görüntüyü yeniden yayınlamak gerekli değildir; bunun yerine, yalnızca robotun görüş alanında bulunan sınıflara ihtiyaç vardır. Aşağıdaki örnek, nasıl kullanılacağını gösterir: std_msgs/String mesajları algılanan sınıfları şurada yeniden yayınlamak için /ultralytics/detection/classes konusunu dinler. Bu mesajlar daha hafiftir ve çeşitli uygulamalar için değerli olan temel bilgileri sağlar.

Örnek Kullanım Durumu

Bir kamera ve nesne ile donatılmış bir depo robotu düşünün tespit modeli. Robot, ağ üzerinden büyük etiketli görüntüler göndermek yerine, algılanan sınıfların bir listesini şu şekilde yayınlayabilir: std_msgs/String mesajları. Örneğin, robot "kutu", "palet" ve "forklift" gibi nesneleri algıladığında, bu sınıfları şuraya yayınlar: /ultralytics/detection/classes konusunu dinler. Bu bilgiler daha sonra merkezi bir izleme sistemi tarafından envanteri gerçek zamanlı olarak izlemek, robotun engellerden kaçınmak için yol planlamasını optimize etmek veya algılanan bir kutuyu almak gibi belirli eylemleri tetiklemek için kullanılabilir. Bu yaklaşım, iletişim için gereken bant genişliğini azaltır ve kritik verilerin iletilmesine odaklanır.

Adım Adım Dize Kullanımı

Bu örnek, Ultralytics YOLO paketinin ROS ile nasıl kullanılacağını gösterir. Bu örnekte, bir kamera konusuna abone oluyor, gelen görüntüyü YOLO kullanarak işliyor ve tespit edilen nesneleri yeni bir konuya yayınlıyoruz. /ultralytics/detection/classes kullanarak std_msgs/String mesajları. Şunun ros_numpy paketi, ROS Görüntü mesajını YOLO ile işlenmek üzere bir numpy dizisine dönüştürmek için kullanılır.

import time

import ros_numpy
import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import String

from ultralytics import YOLO

detection_model = YOLO("yolo11m.pt")
rospy.init_node("ultralytics")
time.sleep(1)
classes_pub = rospy.Publisher("/ultralytics/detection/classes", String, queue_size=5)


def callback(data):
    """Callback function to process image and publish detected classes."""
    array = ros_numpy.numpify(data)
    if classes_pub.get_num_connections():
        det_result = detection_model(array)
        classes = det_result[0].boxes.cls.cpu().numpy().astype(int)
        names = [det_result[0].names[i] for i in classes]
        classes_pub.publish(String(data=str(names)))


rospy.Subscriber("/camera/color/image_raw", Image, callback)
while True:
    rospy.spin()

Ultralytics'i ROS Derinlik Görüntüleri ile kullanın

RGB görüntülerine ek olarak, ROS, nesnelerin kameradan uzaklığı hakkında bilgi sağlayan derinlik görüntülerini de destekler. Derinlik görüntüleri, engelden kaçınma, 3B haritalama ve konumlandırma gibi robotik uygulamalar için çok önemlidir.

Bir derinlik görüntüsü, her pikselin kameradan bir nesneye olan uzaklığı temsil ettiği bir görüntüdür. Rengi yakalayan RGB görüntülerinin aksine, derinlik görüntüleri uzamsal bilgileri yakalar ve robotların çevrelerinin 3B yapısını algılamasını sağlar.

Derinlik Görüntüleri Elde Etme

Derinlik görüntüleri çeşitli sensörler kullanılarak elde edilebilir:

  1. Stereo Kameralar: Görüntü farklılığına dayalı olarak derinliği hesaplamak için iki kamera kullanın.
  2. Uçuş Süresi (ToF) Kameraları: Işığın bir nesneden geri dönmesinin ne kadar sürdüğünü ölçün.
  3. Yapılandırılmış Işık Sensörleri: Bir desen yansıtın ve yüzeylerdeki deformasyonunu ölçün.

Derinlik Görüntüleri ile YOLO Kullanımı

ROS'ta, derinlik görüntüleri şu şekilde temsil edilir: sensor_msgs/Image mesaj türü, kodlama, yükseklik, genişlik ve piksel verileri için alanlar içerir. Derinlik görüntüleri için kodlama alanı genellikle piksel başına 16 bit işaretsiz bir tamsayıyı gösteren "16UC1" gibi bir format kullanır; burada her değer nesneye olan uzaklığı temsil eder. Derinlik görüntüleri, ortamın daha kapsamlı bir görünümünü sağlamak için genellikle RGB görüntüleriyle birlikte kullanılır.

YOLO kullanarak, hem RGB hem de derinlik görüntülerinden bilgi çıkarmak ve birleştirmek mümkündür. Örneğin, YOLO bir RGB görüntüsü içindeki nesneleri algılayabilir ve bu algılama, derinlik görüntüsündeki karşılık gelen bölgeleri belirlemek için kullanılabilir. Bu, algılanan nesneler için hassas derinlik bilgilerinin çıkarılmasına olanak tanıyarak robotun çevresini üç boyutta anlama yeteneğini geliştirir.

RGB-D Kameralar

Derinlik görüntüleriyle çalışırken, RGB ve derinlik görüntülerinin doğru şekilde hizalandığından emin olmak önemlidir. Intel RealSense serisi gibi RGB-D kameralar, senkronize RGB ve derinlik görüntüleri sağlayarak her iki kaynaktan gelen bilgileri birleştirmeyi kolaylaştırır. Ayrı RGB ve derinlik kameraları kullanılıyorsa, doğru hizalama sağlamak için bunları kalibre etmek çok önemlidir.

Derinlik Adım Adım Kullanım

Bu örnekte, bir görüntüyü bölümlere ayırmak ve çıkarılan maskeyi derinlik görüntüsündeki nesneyi bölümlere ayırmak için YOLO'yu kullanıyoruz. Bu, ilgilenilen nesnenin her pikselinin kameranın odak merkezinden uzaklığını belirlememizi sağlar. Bu mesafe bilgisini elde ederek, kamera ile sahnedeki belirli nesne arasındaki mesafeyi hesaplayabiliriz. Gerekli kitaplıkları içe aktararak, bir ROS düğümü oluşturarak ve bir segmentasyon modeli ve bir ROS konusu örneklendirerek başlayın.

import time

import rospy
from std_msgs.msg import String

from ultralytics import YOLO

rospy.init_node("ultralytics")
time.sleep(1)

segmentation_model = YOLO("yolo11m-seg.pt")

classes_pub = rospy.Publisher("/ultralytics/detection/distance", String, queue_size=5)

Ardından, gelen derinlik görüntüsü mesajını işleyen bir geri çağırma işlevi tanımlayın. İşlev, derinlik görüntüsü ve RGB görüntü mesajlarını bekler, bunları numpy dizilerine dönüştürür ve RGB görüntüsüne segmentasyon modelini uygular. Daha sonra, algılanan her nesne için segmentasyon maskesini çıkarır ve derinlik görüntüsünü kullanarak nesnenin kameradan ortalama mesafesini hesaplar. Çoğu sensörün, değerlerin sonsuz (inf) olarak temsil edildiği, klip mesafesi olarak bilinen maksimum bir mesafesi vardır (np.inf). İşlemden önce, bu boş değerleri filtrelemek ve bunlara bir değer atamak önemlidir: 0. Son olarak, algılanan nesneleri ortalama mesafeleriyle birlikte yayınlar. /ultralytics/detection/distance konusu.

import numpy as np
import ros_numpy
from sensor_msgs.msg import Image


def callback(data):
    """Callback function to process depth image and RGB image."""
    image = rospy.wait_for_message("/camera/color/image_raw", Image)
    image = ros_numpy.numpify(image)
    depth = ros_numpy.numpify(data)
    result = segmentation_model(image)

    all_objects = []
    for index, cls in enumerate(result[0].boxes.cls):
        class_index = int(cls.cpu().numpy())
        name = result[0].names[class_index]
        mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
        obj = depth[mask == 1]
        obj = obj[~np.isnan(obj)]
        avg_distance = np.mean(obj) if len(obj) else np.inf
        all_objects.append(f"{name}: {avg_distance:.2f}m")

    classes_pub.publish(String(data=str(all_objects)))


rospy.Subscriber("/camera/depth/image_raw", Image, callback)

while True:
    rospy.spin()
Tam kod
import time

import numpy as np
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import String

from ultralytics import YOLO

rospy.init_node("ultralytics")
time.sleep(1)

segmentation_model = YOLO("yolo11m-seg.pt")

classes_pub = rospy.Publisher("/ultralytics/detection/distance", String, queue_size=5)


def callback(data):
    """Callback function to process depth image and RGB image."""
    image = rospy.wait_for_message("/camera/color/image_raw", Image)
    image = ros_numpy.numpify(image)
    depth = ros_numpy.numpify(data)
    result = segmentation_model(image)

    all_objects = []
    for index, cls in enumerate(result[0].boxes.cls):
        class_index = int(cls.cpu().numpy())
        name = result[0].names[class_index]
        mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
        obj = depth[mask == 1]
        obj = obj[~np.isnan(obj)]
        avg_distance = np.mean(obj) if len(obj) else np.inf
        all_objects.append(f"{name}: {avg_distance:.2f}m")

    classes_pub.publish(String(data=str(all_objects)))


rospy.Subscriber("/camera/depth/image_raw", Image, callback)

while True:
    rospy.spin()

Ultralytics'i ROS ile kullanın sensor_msgs/PointCloud2

ROS Gazebo'da Tespit ve Segmentasyon

sensor_msgs/PointCloud2 mesaj türü , ROS'ta 3D nokta bulutu verilerini temsil etmek için kullanılan bir veri yapısıdır. Bu mesaj türü, 3D haritalama, nesne tanıma ve lokalizasyon gibi görevleri etkinleştirerek robotik uygulamalar için ayrılmaz bir öneme sahiptir.

Nokta bulutu, üç boyutlu bir koordinat sistemi içinde tanımlanan veri noktaları koleksiyonudur. Bu veri noktaları, 3D tarama teknolojileri aracılığıyla yakalanan bir nesnenin veya sahnenin dış yüzeyini temsil eder. Buluttaki her noktanın şunları vardır: X, Yve Z uzaydaki konumuna karşılık gelen koordinatlar ve ayrıca renk ve yoğunluk gibi ek bilgiler içerebilir.

Referans çerçevesi

Şununla çalışırken: sensor_msgs/PointCloud2, nokta bulutu verilerinin elde edildiği sensörün referans çerçevesini dikkate almak önemlidir. Nokta bulutu başlangıçta sensörün referans çerçevesinde yakalanır. Bu referans çerçevesini şurayı dinleyerek belirleyebilirsiniz: /tf_static konusu. Ancak, özel uygulama gereksinimlerinize bağlı olarak, nokta bulutunu başka bir referans çerçevesine dönüştürmeniz gerekebilir. Bu dönüşüm, tf2_ros koordinat çerçevelerini yönetmek ve verileri bunlar arasında dönüştürmek için araçlar sağlayan paket.

Nokta bulutları elde etme

Nokta Bulutları çeşitli sensörler kullanılarak elde edilebilir:

  1. LIDAR (Işık Algılama ve Menzil Belirleme): Nesnelere olan mesafeleri ölçmek ve yüksek hassasiyetli 3B haritalar oluşturmak için lazer darbeleri kullanır.
  2. Derinlik Kameraları: Her piksel için derinlik bilgisini yakalar ve sahnenin 3B rekonstrüksiyonuna olanak tanır.
  3. Stereo Kameralar: Üçgenleme yoluyla derinlik bilgisi elde etmek için iki veya daha fazla kamera kullanın.
  4. Yapılandırılmış Işık Tarayıcıları: Bir yüzeye bilinen bir desen yansıtın ve derinliği hesaplamak için deformasyonu ölçün.

Nokta Bulutları ile YOLO Kullanımı

YOLO'yu entegre etmek için sensor_msgs/PointCloud2 tipi mesajlar için, derinlik haritaları için kullanılan yönteme benzer bir yöntem kullanabiliriz. Nokta bulutuna gömülü renk bilgilerinden yararlanarak, 2B bir görüntü çıkarabilir, YOLO kullanarak bu görüntü üzerinde segmentasyon gerçekleştirebilir ve ardından ortaya çıkan maskeyi üç boyutlu noktalara uygulayarak ilgilenilen 3B nesneyi izole edebiliriz.

Nokta bulutlarını işlemek için Open3D'yi kullanmanızı öneririz (pip install open3d), kullanıcı dostu bir python kütüphanesi. Open3D, nokta bulutu veri yapılarını yönetmek, görselleştirmek ve karmaşık işlemleri sorunsuz bir şekilde yürütmek için güçlü araçlar sağlar. Bu kütüphane, süreci önemli ölçüde basitleştirebilir ve YOLO tabanlı segmentasyonla bağlantılı olarak nokta bulutlarını manipüle etme ve analiz etme yeteneğimizi geliştirebilir.

Nokta Bulutları Adım Adım Kullanımı

Gerekli kütüphaneleri içe aktarın ve segmentasyon için YOLO modelini örneklendirin.

import time

import rospy

from ultralytics import YOLO

rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolo11m-seg.pt")

Bir fonksiyon oluşturun pointcloud2_to_array, bir öğesini dönüştüren sensor_msgs/PointCloud2 mesajı iki numpy dizisine dönüştürür. Şunun sensor_msgs/PointCloud2 mesajları içerir n temel alan noktalar width ve height elde edilen görüntünün. Örneğin, bir 480 x 640 görüntüye sahip olacak 307,200 noktaları. Her nokta üç uzamsal koordinat içerir (xyz) ve karşılık gelen renk RGB biçimindedir. Bunlar, iki ayrı bilgi kanalı olarak düşünülebilir.

Fonksiyon şunu döndürür: xyz koordinatlar ve RGB değerleri orijinal kamera çözünürlüğü biçiminde (width x height). Çoğu sensörün, değerlerin inf (sonsuz) olarak temsil edildiği, klip mesafesi olarak bilinen maksimum bir mesafesi vardır.np.inf). İşlemden önce, bu boş değerleri filtrelemek ve bunlara bir değer atamak önemlidir: 0.

import numpy as np
import ros_numpy


def pointcloud2_to_array(pointcloud2: PointCloud2) -> tuple:
    """
    Convert a ROS PointCloud2 message to a numpy array.

    Args:
        pointcloud2 (PointCloud2): the PointCloud2 message

    Returns:
        (tuple): tuple containing (xyz, rgb)
    """
    pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
    split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
    rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
    xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
    xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
    nan_rows = np.isnan(xyz).all(axis=2)
    xyz[nan_rows] = [0, 0, 0]
    rgb[nan_rows] = [0, 0, 0]
    return xyz, rgb

Ardından, şuna abone olun: /camera/depth/points nokta bulutu mesajını almak ve dönüştürmek için. sensor_msgs/PointCloud2 XYZ koordinatlarını ve RGB değerlerini içeren numpy dizilerine mesaj (kullanarak pointcloud2_to_array fonksiyonu). Bölümlere ayrılmış nesneleri çıkarmak için RGB görüntüsünü YOLO modelini kullanarak işleyin. Algılanan her nesne için, segmentasyon maskesini çıkarın ve nesneyi 3B uzayda izole etmek için hem RGB görüntüsüne hem de XYZ koordinatlarına uygulayın.

Maskeyi işlemek basittir, çünkü maske ikili değerlerden oluşur, 1 nesnenin varlığını gösterir ve 0 nesnenin varlığını ve yokluğunu belirtir. Maskeyi uygulamak için orijinal kanalları maskeyle çarpmanız yeterlidir. Bu işlem, görüntüdeki ilgi nesnesini etkili bir şekilde izole eder. Son olarak, bir Open3D nokta bulutu nesnesi oluşturun ve bölümlenmiş nesneyi ilişkili renklerle 3B uzayda görselleştirin.

import sys

import open3d as o3d

ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)

if not len(result[0].boxes.cls):
    print("No objects detected")
    sys.exit()

classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
    mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
    mask_expanded = np.stack([mask, mask, mask], axis=2)

    obj_rgb = rgb * mask_expanded
    obj_xyz = xyz * mask_expanded

    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((ros_cloud.height * ros_cloud.width, 3)))
    pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((ros_cloud.height * ros_cloud.width, 3)) / 255)
    o3d.visualization.draw_geometries([pcd])
Tam kod
import sys
import time

import numpy as np
import open3d as o3d
import ros_numpy
import rospy
from sensor_msgs.msg import PointCloud2

from ultralytics import YOLO

rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolo11m-seg.pt")


def pointcloud2_to_array(pointcloud2: PointCloud2) -> tuple:
    """
    Convert a ROS PointCloud2 message to a numpy array.

    Args:
        pointcloud2 (PointCloud2): the PointCloud2 message

    Returns:
        (tuple): tuple containing (xyz, rgb)
    """
    pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
    split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
    rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
    xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
    xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
    nan_rows = np.isnan(xyz).all(axis=2)
    xyz[nan_rows] = [0, 0, 0]
    rgb[nan_rows] = [0, 0, 0]
    return xyz, rgb


ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)

if not len(result[0].boxes.cls):
    print("No objects detected")
    sys.exit()

classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
    mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
    mask_expanded = np.stack([mask, mask, mask], axis=2)

    obj_rgb = rgb * mask_expanded
    obj_xyz = xyz * mask_expanded

    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((ros_cloud.height * ros_cloud.width, 3)))
    pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((ros_cloud.height * ros_cloud.width, 3)) / 255)
    o3d.visualization.draw_geometries([pcd])

Ultralytics ile Nokta Bulutu Segmentasyonu

SSS

Robot İşletim Sistemi (ROS) nedir?

Robot İşletim Sistemi (ROS), geliştiricilerin sağlam robot uygulamaları oluşturmasına yardımcı olmak için robotikte yaygın olarak kullanılan açık kaynaklı bir çerçevedir. Karmaşık uygulamaların daha kolay geliştirilmesini sağlayarak, robotik sistemler oluşturmak ve bunlarla arayüz oluşturmak için bir kütüphane ve araç koleksiyonu sağlar. ROS, konular veya hizmetler üzerinden mesajlar kullanarak düğümler arasındaki iletişimi destekler.

Gerçek zamanlı nesne algılama için Ultralytics YOLO'yu ROS ile nasıl entegre ederim?

Ultralytics YOLO'yu ROS ile entegre etmek, bir ROS ortamı kurmayı ve sensör verilerini işlemek için YOLO'yu kullanmayı içerir. Aşağıdaki gibi gerekli bağımlılıkları yükleyerek başlayın: ros_numpy ve Ultralytics YOLO:

pip install ros_numpy ultralytics

Ardından, bir ROS düğümü oluşturun ve gelen verileri işlemek için bir görüntü konusuna (image topic) abone olun. İşte минима bir örnek:

import ros_numpy
import rospy
from sensor_msgs.msg import Image

from ultralytics import YOLO

detection_model = YOLO("yolo11m.pt")
rospy.init_node("ultralytics")
det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)


def callback(data):
    array = ros_numpy.numpify(data)
    det_result = detection_model(array)
    det_annotated = det_result[0].plot(show=False)
    det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))


rospy.Subscriber("/camera/color/image_raw", Image, callback)
rospy.spin()

ROS konuları nelerdir ve Ultralytics YOLO'da nasıl kullanılır?

ROS konuları, bir ROS ağındaki düğümler arasında yayınlama-abonelik modeli kullanarak iletişimi kolaylaştırır. Bir konu, düğümlerin mesajları eşzamansız olarak göndermek ve almak için kullandığı adlandırılmış bir kanaldır. Ultralytics YOLO bağlamında, bir düğümü bir görüntü konusuna abone yapabilir, görüntüleri algılama veya segmentasyon gibi görevler için YOLO kullanarak işleyebilir ve sonuçları yeni konulara yayınlayabilirsiniz.

Örneğin, bir kamera konusuna abone olun ve gelen görüntüyü algılama için işleyin:

rospy.Subscriber("/camera/color/image_raw", Image, callback)

ROS'ta Ultralytics YOLO ile derinlik görüntüleri neden kullanılır?

ROS'ta derinlik görüntüleri, şu şekilde temsil edilir: sensor_msgs/Image, engelden kaçınma, 3B haritalama ve konumlandırma gibi görevler için çok önemli olan nesnelerin kameraya olan uzaklığını sağlar. Şunu yaparak: derinlik bilgisini kullanarak RGB görüntülerle birlikte robotlar, 3D ortamlarını daha iyi anlayabilir.

YOLO ile, RGB görüntülerinden segmentasyon maskeleri çıkarabilir ve bu maskeleri derinlik görüntülerine uygulayarak hassas 3B nesne bilgileri elde edebilir, böylece robotun çevresiyle etkileşim ve navigasyon yeteneği geliştirilebilir.

ROS'ta YOLO ile 3B nokta bulutlarını nasıl görselleştirebilirim?

YOLO ile ROS'ta 3B nokta bulutlarını görselleştirmek için:

  1. Dönüştür sensor_msgs/PointCloud2 mesajlarını numpy dizilerine dönüştürür.
  2. RGB görüntülerini bölümlere ayırmak için YOLO'yu kullanın.
  3. Segmentasyon maskesini nokta bulutuna uygulayın.

İşte görselleştirme için Open3D kullanan bir örnek:

import sys

import open3d as o3d
import ros_numpy
import rospy
from sensor_msgs.msg import PointCloud2

from ultralytics import YOLO

rospy.init_node("ultralytics")
segmentation_model = YOLO("yolo11m-seg.pt")


def pointcloud2_to_array(pointcloud2):
    pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
    split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
    rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
    xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
    xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
    return xyz, rgb


ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)

if not len(result[0].boxes.cls):
    print("No objects detected")
    sys.exit()

classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
    mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
    mask_expanded = np.stack([mask, mask, mask], axis=2)

    obj_rgb = rgb * mask_expanded
    obj_xyz = xyz * mask_expanded

    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((-1, 3)))
    pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((-1, 3)) / 255)
    o3d.visualization.draw_geometries([pcd])

Bu yaklaşım, robotik uygulamalarda gezinme ve manipülasyon gibi görevler için yararlı olan bölümlenmiş nesnelerin 3B görselleştirmesini sağlar.



📅 1 yıl önce oluşturuldu ✏️ 4 ay önce güncellendi

Yorumlar