Intel RealSense Derinlik Kamerası, derinlik bilgisine sahip görüntüler üretebilme yeteneğine sahip, robotik çalışmalarla oldukça popüler olan bir derinlik kamerasıdır. Piyasada bu kameranın farklı modelleri bulunmaktadır. Bizler bu yazıda Intel RealSense D435 modelini kullanacağız. Bu model oldukça yüksek çözünürlükte ve yüksek hassasiyette çekimler yapabilmektedir.
Peki biz bir derinlik kamerası ile neler yapabiliriz ?
- Tüm görüntüye dair mesafe bilgisi veren ısı haritaları çıkartabiliriz.
- Görüntülerdeki nesnelerin kameraya olan gerçek mesafesini ölçebiliriz.
- ROS2 tabanlı gelişmiş paketler kullanarak 3 boyutlu ortam haritalama yapabiliriz.
- Nesneleri tarayarak 3 boyutlu modellerini oluşturabiliriz. Kim bilir belki bazılarımız bunu 3 boyutlu yazıcılar ile yazdırmayı da deneyebilir.
Ben bu yazıda sizlere D435 kamerasını kullanarak nasıl mesafe tespiti yapabileceğinizi anlatacağım. Ayrıca bir YOLOv8 mimarisini kullanarak spesifik nesnelerin mesafelerini de ölçeceğiz.
1. Kurulumlar
Bu aşamadan itibaren yapacağımız işlemlerin hatasız ilerlemesi için belirttiğim spesifik sürümlerin kullanılması oldukça önemlidir. Öncelikle Python 3.10.x sürümünü kullandığınızdan emin olun Ardından aşağıdaki komutlarla kurulumları yapın :
pip install numpy
pip install pyrealsense2
pip install opencv-python
Eğer Windows üzerinde çalışıyorsanız pyrealsense için aşağıdaki sürümü kurunuz. Windows için farklı bir sürüm kurduğunuz taktirde error:402 hatası ateşlenebilir. :
pip install pyrealsense2==2.53.1.4623
Numpy ve OpenCV kütüphaneleri görüntüyü işleyebilmemiz için gereken temel kütüphanelerdir. Pyrealsense ise kameraya ve özelliklerini erişebilmemizi sağlayan kütüphanedir. Kütüphanelerin kurulumu aşamasında hatalar aldıysanız yorumlar kısmında bunları bana iletmeyi unutmayın. Ayrıca tüm bu işlemler size karmaşık gelmeye başladıysa yukarıdaki videoyu da takip ederek yapabilirsiniz.
Şimdi bilgisayarınızın herhangi dizininde realsense isimli bir klasör açın. Bu klasörün içinde realsense.py isimli ana betiğinizi (script) oluşturun. Artık kodlarımızı yazmaya hazırız !
2. Görüntü İşleme
Şimdi kameraya bağlanıp görüntüleri almaya ve işlemeye başlayabiliriz. Öncelikle realsense.py dosyamızı açıp kütüphaneleri ekleyelim:
import cv2
import numpy as np
import pyrealsense2 as rs
Ardından kameramızı başlatacak kodları ekleyelim. Bu kısımda kameraya (640,360) boyutunda bir yayın istediğimizi bildiriyoruz.:
pipe = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, 640,480, rs.format.bgr8, 30)
cfg.enable_stream(rs.stream.depth, 640,480, rs.format.z16, 30)
pipe.start(cfg)
Şimdi bir while döngüsü kurarak kareleri okumaya ve yayınlamaya başlayalım:
while True:
frame = pipe.wait_for_frames()
depth_frame = frame.get_depth_frame()
color_frame = frame.get_color_frame()
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())
depth_cm = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha = 0.5), cv2.COLORMAP_JET)
cv2.imshow('rgb', color_image)
cv2.imshow('depth', depth_cm)
if cv2.waitKey(1) == ord('q'):
break
pipe.stop()
Yukarıdaki While döngüsünde frame.get_depth_frame() ile derinlik analizi yapılan kareleri; frame.get_color_frame() ile de RGB kareleri elde ediyoruz. Ardından bunları OpenCV ile ekranda gösterebilmek np.asanyarray ve cv2.applyColorMap ile için uygun formata çeviriyoruz. Son olarak pipe.stop() ile tüm çalışma adımlarını tamamladıktan sonra kameranın yayını durdurmasını sağlıyoruz.
3. Derinlik Tespiti
Bir önceki başlıkta yaptığımız işlemleri anladıysanız, artık bu aşamadan sonra yapacaklarımız sizler için bir çocuk oyuncağı olacak !
Aldığımız karelerdeki herhangi bir noktanın (pikselin) kameraya olan uzaklığını tespit etmek için get_distance() metodunu kullancağız. Basitçe depth_frame.get_distance(x, y) yazarak herhangi bir (x,y) noktasındaki nesnenin kameraya olan uzaklığını yüksek hassasiyetle ölçebiliriz.
Bir önceki başlıkta anlatılan koddaki while döngüsü içerisine aşağıdaki birkaç satırı ekleyerek istediğimiz herhangi bir noktanın kameraya uzaklığını ölçebiliriz:
x, y = 320, 240
cv2.circle(color_image, (x, y), 4, (0, 0, 255))
depth_value = depth_frame.get_distance(x, y)
print(f"Pixel ({x}, {y}) depth: {depth_value:.2f} metre")
Mesafe ölçen kodun tam haline aşağıdan ulaşabilirsiniz.
distance.py adında yeni bir betik oluşturarak aşağıdaki kodu kopyala-yapıştır yapalım:
import pyrealsense2 as rs
import numpy as np
import cv2
pipe = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, 640,480, rs.format.bgr8, 30)
cfg.enable_stream(rs.stream.depth, 640,480, rs.format.z16, 30)
pipe.start(cfg)
while True:
frame = pipe.wait_for_frames()
depth_frame = frame.get_depth_frame()
color_frame = frame.get_color_frame()
if not depth_frame:
continue
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())
depth_cm = cv2.applyColorMap(cv2.convertScaleAbs(depth_image,
alpha = 0.5), cv2.COLORMAP_JET)
x, y = 320, 240
cv2.circle(color_image, (x, y), 4, (0, 0, 255))
depth_value = depth_frame.get_distance(x, y)
print(f"Piksel: ({x}, {y}) - Derinlik: {depth_value:.2f} metre")
cv2.imshow('rgb', color_image)
cv2.imshow('depth', depth_cm)
if cv2.waitKey(1) == ord('q'):
break
pipe.stop()
4. Nesne Tanıma & Mesafe Ölçümü
Bu adımda nesnelerin kameraya olan mesafesini ölçeceğiz. Bunun için nesne tanıma işlemi gerçekleştireceğiz. Ardından tespit edilen nesnenin kameraya olan mesafesini ölçeceğiz. Amacımız yüz tespiti yapmak ve yüzün kameraya olan mesafesini ölçmek olacak. O zaman haydi başlayalım. 🔥
Nesne tanıma işlemi için haar cascade yöntemini kullanacağız. Bu yöntem oldukça temel düzey ve basit bir algoritmadır. Eğer isterseniz YOLOv8 gibi daha gelişmiş nesne tanıma mimarilerini kullanarak da aşağıdaki işlemi gerçekleştirebilirsiniz. Özellikle endüstriyel bir çalışma yapıyorsanız veya bir yarışmaya hazırlanıyorsanız kesinlikle YOLO mimarisini kullanmanızı tavsiye ederim. Bu konuda destek almak isterseniz, sitemizde iletişim formu veya e-posta adresimiz üzerinden bana ulaşabilirsiniz.
Haar Cascade yöntemi ile nesne tanıma işlemi aslında oldukça kolay bir işlemdir. Betiğimize önceden hazırlanmış haar cascade dosyasını ekleyip bu dosyanın sağladığı işlevsellik ile nesne tanıma gerçekleştiririz. Öncelikli betiğimize haar cascade dosyamızı aşağıdaki gibi ekleyeceğiz:
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
Ardından detectMultiScale() metodu ile görüntüdeki yüzün kordinatlarını veya konumu tespit edebiliyoruz. Tespit ettiğimiz koordinatları da bir for döngüsü ile dolaşarak görüntü üzerine işleyebiliriz:
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.05, minNeighbors=5, minSize=(30, 30))
for (x, y, w, h) in faces:
cv2.rectangle(color_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
center_x = x + w // 2
center_y = y + h // 2
center = (center_x, center_y)
cv2.circle(color_image, center, 4, (0, 255, 0))
depth_value = depth_frame.get_distance(center_x, center_y)
print(f"Piksel ({x}, {y}) Mesafe: {depth_value:.2f} metre")
text = f"Mesafe: {depth_value:.2f} m"
cv2.putText(color_image, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(0, 255, 0), thickness=2)
Kodun tam haline aşağıdan ulaşabilirsiniz. detect.py adında yeni bir betik oluşturarak aşağıdaki kodu kopyala-yapıştır yapalım:
# requirements: python 3.10
import pyrealsense2 as rs
import numpy as np
import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
pipe = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, 640,480, rs.format.bgr8, 30)
cfg.enable_stream(rs.stream.depth, 640,480, rs.format.z16, 30)
pipe.start(cfg)
while True:
frame = pipe.wait_for_frames()
depth_frame = frame.get_depth_frame()
color_frame = frame.get_color_frame()
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())
depth_cm = cv2.applyColorMap(cv2.convertScaleAbs(depth_image,
alpha = 0.5), cv2.COLORMAP_JET)
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1,
minNeighbors=7, minSize=(50, 50))
for (x, y, w, h) in faces:
cv2.rectangle(color_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
center_x = x + w // 2
center_y = y + h // 2
center = (center_x, center_y)
cv2.circle(color_image, center, 4, (0, 255, 0))
depth_value = depth_frame.get_distance(center_x, center_y)
print(f"Piksel ({x}, {y}) Mesafe: {depth_value:.2f} metre")
text = f"Mesafe: {depth_value:.2f} m"
cv2.putText(color_image, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(0, 255, 0), thickness=2)
cv2.imshow('rgb', color_image)
cv2.imshow('depth', depth_cm)
if cv2.waitKey(1) == ord('q'):
break
pipe.stop()
Son olarak şunu belirtmemde fayda var: Haar Cascade yöntemi günümüzde yaygın kullanıma sahip olmayan, ilkel bir tekniktir. Bizim blog yazımızda kullanmamızın nedeni sizlerin donanım sorunlarına takılmadan hızlı şekilde nesne tanıma ve mesafe ölçümünün mantığını kavramanızı istememizdir.
5. Endüstriyel Uygulamalar
Bu blog yazısında, D435 derinlik kamerasının kullanımına ve birkaç eğlenceli uygulamasına göz attık. Bu bilgiler ışığında sizlerin geliştireceği projeleri görmeyi dört gözle bekliyorum !
Son olarak, burada paylaşılan kodlar temel seviyede çalışmaları ifade etmektedir. Endüstriyel çalışmalara uygun algoritmalar geliştirmek ve sorunlarınıza hızlı bir şekilde çözüm üretmek için iletişim formu üzerinden benimle iletişime geçebilirsiniz.