# Kameralar

LeRobot, video yakalama için birden fazla seçenek sunar:

| Sınıf             | Desteklenen Kameralar                   |
| ----------------- | ----------------------------------- |
| `OpenCVCamera`    | Telefon, yerleşik dizüstü bilgisayar, USB web kameraları |
| `ZMQCamera`       | Ağ bağlantılı kameralar           |
| `RealSenseCamera` | Intel RealSense (derinlik ile)        |
| `Reachy2Camera`   | Reachy 2 robot kameraları              |

> [!TIP]
> `OpenCVCamera` uyumluluk ayrıntıları için [OpenCV ile Video G/Ç Genel Bakış](https://docs.opencv.org/4.x/d0/da7/videoio_overview.html) başlığını inceleyin.

### Kameranızı bulun

Her kamera, birden fazla bağlı cihaz arasında ayrım yapmanıza olanak tanıyan benzersiz bir tanımlayıcı ile örneklenmelidir.

`OpenCVCamera` ve `RealSenseCamera` otomatik algılama özelliğini destekler. Kullanılabilir cihazları ve tanımlayıcılarını listelemek için aşağıdaki komutu çalıştırın. İşletim sisteminize bağlı olarak bu tanımlayıcılar, bilgisayarınızı yeniden başlattıktan veya kamerayı yeniden takıp çıkardıktan sonra değişebilir.

```bash
lerobot-find-cameras opencv # or realsense for Intel Realsense cameras
```

İki kamera bağlıysa çıktı aşağıdaki gibi görünecektir:

```bash
--- Detected Cameras ---
Camera #0:
  Name: OpenCV Camera @ 0
  Type: OpenCV
  Id: 0
  Backend api: AVFOUNDATION
  Default stream profile:
    Format: 16.0
    Width: 1920
    Height: 1080
    Fps: 15.0
--------------------
(more cameras ...)
```

> [!WARNING]
> `macOS` üzerinde Intel RealSense kameralarını kullanırken bu [hatayı](https://github.com/realsenseai/librealsense/issues/12307) alabilirsiniz: `Error finding RealSense cameras: failed to set power state`. Bu sorun, aynı komutu `sudo` izinleriyle çalıştırılarak çözülebilir. `macOS` üzerinde RealSense kameralarının kullanımı istikrarsızdır.

`ZMQCamera` ve `Reachy2Camera` otomatik keşfi desteklemez. Ağ adresi ve portu veya robot SDK ayarları sağlanarak manuel olarak yapılandırılmalıdır.

## Kamera yerleşimi ve aydınlatma

Kamera görüntüleri, politikanızın öğrenme kaynağıdır; bu nedenle yüksek çözünürlükten çok iyi bir kamera kurulumu daha önemlidir:

- **Sahneyi eşit şekilde aydınlatın.** Yayılmış, tutarlı bir ışık kullanın ve doğrudan güneş ışığı, güçlü yansımalar ve hareketli gölgelerden kaçının. Kayıt ve dağıtım arasındaki aydınlatma farkları, bir politikanın başarısız olmasına neden olabilir.
- **Kameraları sabitleyin.** Onları rijit bir şekilde monte edin ve kayıt oturumları arasında veya kayıt ile dağıtım arasında hareket ettirmeyin.
- **Görevi çerçeveleyin.** Nesne, kavrama mekanizması ve hedef en az bir kamerada görünür olmalıdır. İyi bir test: Görevi yalnızca kamera görüntülerine bakarak kendiniz yapabilir misiniz?
- **Çözünürlüğü makul tutun.** Çoğu görev için 640×480 ve 30 fps yeterlidir ve kayıt ile eğitimi hızlı tutar.

## Kameraları kullanın

### Çerçeve erişim modları

Tüm kamera sınıfları, kare yakalama için üç erişim modunu uygular:

| Yöntem                    | Davranış                                                                                                                                                   | Bloklar mı?        | En Uygun Olduğu Alan                                 |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------- |
| `read()`                  | Kamera donanımının bir kare döndürmesini bekler. Kamera ve SDK'ya bağlı olarak uzun süre bloklanabilir.                                                | Evet            | Basit betikler, ardışık yakalama       |
| `async_read(timeout_ms)`  | Arka plan iş parçacığından en son tüketilmemiş çerçeveyi döndürür. Yalnızca tampon boşsa, `timeout_ms` kadar bloklanır. Hiçbir çerçeve gelmezse `TimeoutError` fırlatılır. | Zaman aşımı ile | Kamera FPS'ine senkronize edilmiş kontrol döngüleri |
| `read_latest(max_age_ms)` | Tampondaki en son kareye bakar (esnek olabilir). Kare `max_age_ms` değerinden eskiyse `TimeoutError` fırlatır.                                        | Hayır             | Arayüz görselleştirme, günlük kaydı, izleme    |

### Kullanım örnekleri

Aşağıdaki örnekler, farklı kamera türlerinden kare yapılandırmak ve yakalamak için kamera API'sinin nasıl kullanılacağını gösterir.

- OpenCV tabanlı bir kamera ile **engelleyici ve engelleyici olmayan kare yakalama**
- Intel RealSense kamera ile **Renk ve derinlik yakalama**

> [!WARNING]
> Kameraların temiz bir şekilde bağlantısının kesilmemesi kaynak sızıntılarına neden olabilir. Otomatik temizleme işlemini sağlamak için bağlam yöneticisi protokolünü kullanın:
>
> ```python
> with OpenCVCamera(config) as camera:
>     ...
> ```
>
> `connect()` ve `disconnect()` fonksiyonlarını manuel olarak da çağırabilirsiniz ancak ikincisi için her zaman bir `finally` bloğu kullanın.

```python
from lerobot.cameras.opencv import OpenCVCamera, OpenCVCameraConfig
from lerobot.cameras import ColorMode, Cv2Rotation

# Construct an `OpenCVCameraConfig` with your desired FPS, resolution, color mode, and rotation.
config = OpenCVCameraConfig(
    index_or_path=0,
    fps=15,
    width=1920,
    height=1080,
    color_mode=ColorMode.RGB,
    rotation=Cv2Rotation.NO_ROTATION
)

# Instantiate and connect an `OpenCVCamera`, performing a warm-up read (default).
with OpenCVCamera(config) as camera:

    # Read a frame synchronously — blocks until hardware delivers a new frame
    frame = camera.read()
    print(f"read() call returned frame with shape:", frame.shape)

    # Read a frame asynchronously with a timeout — returns the latest unconsumed frame or waits up to timeout_ms for a new one
    try:
        for i in range(10):
            frame = camera.async_read(timeout_ms=200)
            print(f"async_read call returned frame {i} with shape:", frame.shape)
    except TimeoutError as e:
        print(f"No frame received within timeout: {e}")

    # Instantly return a frame - returns the most recent frame captured by the camera
    try:
        initial_frame = camera.read_latest(max_age_ms=1000)
        for i in range(10):
            frame = camera.read_latest(max_age_ms=1000)
            print(f"read_latest call returned frame {i} with shape:", frame.shape)
            print(f"Was a new frame received by the camera? {not (initial_frame == frame).any()}")
    except TimeoutError as e:
        print(f"Frame too old: {e}")

```

```python
from lerobot.cameras.realsense import RealSenseCamera, RealSenseCameraConfig
from lerobot.cameras import ColorMode, Cv2Rotation

# Create a `RealSenseCameraConfig` specifying your camera’s serial number and enabling depth.
config = RealSenseCameraConfig(
    serial_number_or_name="233522074606",
    fps=15,
    width=640,
    height=480,
    color_mode=ColorMode.RGB,
    use_depth=True,
    # Optional fixed color controls. Omit them to leave the current sensor settings unchanged.
    exposure=120,
    gain=64,
    white_balance=4600,
    rotation=Cv2Rotation.NO_ROTATION
)

# Instantiate and connect a `RealSenseCamera` with warm-up read (default).
camera = RealSenseCamera(config)
camera.connect()

# Capture a color frame via `read()` and a depth map via `read_depth()`.
try:
    color_frame = camera.read()
    depth_map = camera.read_depth()
    print("Color frame shape:", color_frame.shape)
    print("Depth map shape:", depth_map.shape)
finally:
    camera.disconnect()
```

Manuel renk kontrolleri, ilgili otomatik pozlama veya beyaz dengesi modunu devre dışı bırakır. Desteklenen aralıklar kamera modeline göre değişir; geçersiz bir değer, sensörün bildirdiği aralığı içeren bir bağlantı zamanı hatası oluşturur. Desteklenmeyen bir kontrolün istenmesi de hata oluşturur. Atlanan kontroller, sensörün mevcut otomatik veya manuel ayarını değiştirmez. Bu seçenekler `use_rgb=True` gerektirir.

Manuel renk kontrolleri, özel bir RGB modülü gerektirir. RealSense D405 gibi bu modüle sahip olmayan kameralar bu kontrolleri desteklemez ve bağlantı sırasında bir hata oluşturur.

### Derinlikle çalışma

Intel RealSense ve Reachy 2 kameraları, renk ve derinlik verilerini eş zamanlı olarak yakalayabilir. `read()` çağrısı, **renk** çerçevesini `(H, W, 3)` `uint8` olarak döndürür. `read_depth()` çağrısı ise **derinlik haritasını** `(H, W, 1)` `uint16` olarak döndürür; bu haritada her piksel değeri, sensöre olan mesafenin **milimetre** cinsinden ifadesidir. `0` piksel değeri genellikle "ölçüm mevcut değil" (menzil dışı, tıkanmış veya düşük güven) anlamına gelir.

Kayıt sırasında, kontrol döngüsü en güncel tamponlanmış kareleri `read_latest()` (renk) ve `read_latest_depth()` (derinlik) ile engellemeden okur ve derinlik haritasını bir kardeş özellik olarak ekler (ör. `front` yanında `front_depth`).

Bir veri seti kaydedilirken derinlik akışlarının nasıl saklandığı ve kodlandığı hakkında bilgi için, video kodlama kılavuzundaki [Derinlik akışları](./video_encoding_parameters#depth-streams) bölümüne bakın.

## Telefonunuzun kamerasını kullanın

macOS'ta iPhone'unuzu kamera olarak kullanmak için Continuity Camera özelliğini etkinleştirin:

- Mac'inizin macOS 13 veya daha yeni bir sürüm çalıştırdığından ve iPhone'unuzun iOS 16 veya daha yeni bir sürümde olduğundan emin olun.
- Her iki cihazda da aynı Apple Kimliği ile oturum açın.
- Cihazlarınızı bir USB kablosuyla bağlayın veya kablosuz bağlantı için Wi-Fi ve Bluetooth'u açın.

Daha fazla ayrıntı için [Apple destek](https://support.apple.com/en-gb/guide/mac-help/mchl77879b8a/mac) sayfasını ziyaret edin.

OBS ile telefonunuzu kamera olarak kullanmak istiyorsanız, sanal bir kamera kurmak için aşağıdaki adımları izleyin.

1. _(Sadece Linux) `v4l2loopback-dkms` ve `v4l-utils` paketlerini yükleyin_. Bu paketler sanal kamera cihazları oluşturur ve ayarlarını doğrular. Şu komutla yükleyin:

```bash
sudo apt install v4l2loopback-dkms v4l-utils
```

2. _Telefonunuza [DroidCam uygulamasını](https://droidcam.app) yükleyin_. Bu uygulama hem iOS hem de Android için kullanılabilir.
3. _[OBS Studio](https://obsproject.com)'yi indirin ve yükleyin_.
4. _[DroidCam OBS eklentisini](https://droidcam.app/obs) indirin ve yükleyin._
5. _OBS Studio'yu başlatın_.

6. _Telefonunuzu bir kaynak olarak ekleyin_. Talimatlar için [buraya](https://droidcam.app/obs/usage) bakın. Filigranları önlemek için çözünürlüğü `640x480` olarak ayırdığınızdan emin olun.
7. _Çözünürlük ayarlarını değiştirin_. OBS Studio'da `File > Settings > Video` veya `OBS > Preferences... > Video` yolunu izleyin. `Base(Canvas) Resolution` ve `Output(Scaled) Resolution` değerlerini elle yazarak `640x480` olarak değiştirin.
8. _Sanal kamerayı başlatın_. OBS Studio'da [buradaki](https://obsproject.com/kb/virtual-camera-guide) talimatları izleyin.
9. _Sanal kamera kurulumunu ve çözünürlüğünü doğrulayın_.
   - **Linux**: Cihazları listelemek ve çözünürlüğü kontrol etmek için `v4l2-ctl` kullanın:
     ```bash
     v4l2-ctl --list-devices  # find VirtualCam and note its /dev/videoX path
     v4l2-ctl -d /dev/videoX --get-fmt-video  # replace with your VirtualCam path
     ```
     `VirtualCam`'ın listelendiğini ve çözünürlüğün `640x480` olduğunu görmelisiniz.
   - **macOS**: Fotoğraf Kabini veya FaceTime'ı açın ve girdi olarak "OBS Virtual Camera" seçeneğini seçin.
   - **Windows**: Yerel Kamera uygulaması sanal kameraları desteklemez. Bir video konferans uygulaması (Zoom, Teams) kullanın veya doğrulamak için `lerobot-find-cameras opencv` komutunu doğrudan çalıştırın.

Sorun Giderme

> Sanal kamera çözünürlüğü hatalı.

Sanal kamera kaynağını silin ve yeniden oluşturun. Çözünürlük, oluşturulduktan sonra değiştirilemez.

> Arka plan iş parçacığında OpenCVCamera(X) için çerçeve okuma hatası: OpenCVCamera(X) çerçeve genişliği=640 veya yüksekliği=480, yapılandırılmış genişlik=1920 veya yükseklik=1080 ile eşleşmiyor.

Bu hata, yeniden ölçeklendirmeye rağmen OBS Sanal Kamera'nın `1920x1080` çözünürlüğünü bildirmesinden kaynaklanmaktadır. Şu an için tek çözüm, `_postprocess_image()` içindeki genişlik ve yükseklik kontrolünü yorum satırı olarak işaretlemektir.

Her şey doğru şekilde yapılandırıldıysa, telefonunuz standart bir OpenCV kamerası olarak görünecek ve `OpenCVCamera` ile kullanılabilir olacaktır.

