Kurs içeriği (3 / 10)
  1. 1 Raspberry Pi ile Tanışma ve Kurulum 80 dk
  2. 2 Makine Öğrenmesi Nedir? İlk Modelimiz 80 dk
  3. 3 Kamera ve Görüntü İşlemenin Temelleri 80 dk
  4. 4 Görüntü Veri Seti Hazırlama 80 dk
  5. 5 Görüntü Tanıma Modeli Eğitip Pi’de Çalıştırma 120 dk
  6. 6 Mikrofon ve Sesin Temelleri 80 dk
  7. 7 Ses Veri Seti Hazırlama 80 dk
  8. 8 Ses Tanıma Modeli ile Sesli Komutlar 120 dk
  9. 9 Yapay Zekâyı Donanıma Bağlama: LED, Buzzer ve Servo 80 dk
  10. 10 Mini Proje: Akıllı Geri Dönüşüm Kutusu 160 dk

Raspberry Pi ile Makine Öğrenmesi: Görüntü ve Ses Tanıma · Ders 3 / 10

Kamera ve Görüntü İşlemenin Temelleri

Konu anlatımı ⏱ 80 dk

Pi Camera Module 3’ü ya da bir USB web kamerasını Raspberry Pi’ye bağlıyor, picamera2 ve cv2.VideoCapture ile görüntü alıyoruz. Bir görüntünün aslında sayılardan oluşan bir dizi olduğunu görüyor; OpenCV ile gri tona çevirme, yeniden boyutlandırma, kırpma, bulanıklaştırma ve renge göre nesne bulma işlemlerini uyguluyoruz.

Bu derste

  • Pi kamera modülünü ya da USB web kamerasını bağlar ve terminalden test eder.
  • picamera2 ile kameradan görüntü alıp dosyaya kaydeder.
  • USB web kamerasından cv2.VideoCapture ile görüntü alır.
  • Bir görüntünün piksellerden oluşan bir NumPy dizisi olduğunu açıklar ve BGR renk sırasını bilir.
  • OpenCV ile gri tona çevirme, yeniden boyutlandırma, kırpma ve renge göre nesne bulma işlemlerini yapar.

Malzemeler

  • Raspberry Pi 5 veya 4
  • Pi Camera Module 3 (Pi 5 için 22–15 pin kamera kablosu) veya USB web kamerası
  • Thonny ve yzenv sanal ortamı
  • picamera2 ve OpenCV

Önceki derste makine öğrenmesinin örneklerden öğrendiğini gördük. Görüntü tanıma modelimizin örnekleri fotoğraflar olacak. Bu derste Raspberry Pi’ye gözlerini takıyor ve bir bilgisayarın bir fotoğrafı nasıl “gördüğünü” keşfediyoruz.

Dersin Amacı ve Kazanımlar

Bu dersin sonunda:

  1. Pi kamera modülünü ya da USB web kamerasını bağlayıp terminalden test edebileceksiniz.
  2. picamera2 ile kameradan görüntü alıp dosyaya kaydedebileceksiniz.
  3. USB web kamerasından cv2.VideoCapture ile görüntü alabileceksiniz.
  4. Bir görüntünün piksellerden oluşan bir NumPy dizisi olduğunu açıklayabileceksiniz.
  5. OpenCV ile gri tona çevirme, yeniden boyutlandırma, kırpma ve renge göre nesne bulma işlemlerini yapabileceksiniz.

Gerekli Malzemeler

Malzeme Açıklama
Raspberry Pi 5 veya 4 Ders 1’deki kurulum yapılmış olmalı
Pi Camera Module 3 Otomatik odaklı resmî kamera. Pi 5’in kamera girişi daha küçüktür; Pi 5 için 22 pin – 15 pin kamera kablosu gerekir. Pi 4’te kutudan çıkan kablo kullanılır.
USB web kamerası (alternatif) Kamera modülü yoksa herhangi bir USB web kamerası iş görür.
picamera2 ve OpenCV Ders 1’de apt ile kuruldu (python3-picamera2, python3-opencv).

💡 İpucu

Kamera kablosunu takarken ve çıkarırken Pi’nin gücü mutlaka kapalı olsun. Konnektörün plastik kilidini nazikçe kaldırın, kabloyu sonuna kadar itin ve kilidi kapatın. Kablonun yönü önemlidir; resmî kamera belgelerindeki fotoğrafla karşılaştırın. Ters takılan kabloda kamera hiç görünmez.

Kamerayı Bağlama ve Test Etme

Camera Module 3’ün Raspberry Pi 5’e bağlanması

Kamerayı bağlayıp Pi’yi açtıktan sonra terminalde şu komutları deneyin. Bookworm’da kamera komutlarının adı rpicam- ile başlar (eski kaynaklarda libcamera-hello görebilirsiniz):

# Pi kamerayı görüyor mu?
rpicam-hello --list-cameras

# 5 saniyelik önizleme penceresi
rpicam-hello -t 5000

# Tek fotoğraf çek
rpicam-still -o deneme.jpg

İlk komut kamerayı listeliyorsa bağlantı doğrudur. Camera Module 3 listede imx708 adıyla görünür.

picamera2 ile Fotoğraf Çekme

picamera2, Raspberry Pi kameraları için resmî Python kütüphanesidir. Aşağıdaki programı çalıştırın:

# dosya: kamera_foto.py
from picamera2 import Picamera2
import cv2
import time

picam2 = Picamera2()
ayar = picam2.create_preview_configuration(
    main={"size": (640, 480), "format": "RGB888"})
picam2.configure(ayar)
picam2.start()
time.sleep(2)                 # pozlama ve beyaz dengesi otursun

kare = picam2.capture_array() # görüntü bir NumPy dizisi olarak gelir
picam2.stop()

print("Boyut:", kare.shape, "| Veri türü:", kare.dtype)
cv2.imwrite("ilk_foto.jpg", kare)
print("ilk_foto.jpg kaydedildi.")

Örnek çıktı: (Raspberry Pi 5 ve Camera Module 3 ile örnek çıktı. Terminalde bunlardan önce libcamera’nın INFO ile başlayan bilgi satırları da görünebilir; bunlar hata değildir.)

Boyut: (480, 640, 3) | Veri türü: uint8
ilk_foto.jpg kaydedildi.

Önemli ayrıntı şu: "RGB888" biçimini seçtiğimizde picamera2 pikselleri [Mavi, Yeşil, Kırmızı] sırasıyla verir. Bu, OpenCV’nin beklediği sıranın aynısıdır. Bu yüzden görüntüyü hiç dönüştürmeden cv2.imwrite() ile kaydedebildik.

Canlı görüntü için kareleri bir döngüde sürekli alıp OpenCV pencerelerinde gösteririz. Pencere açıkken q tuşuna basınca program kapanır:

# dosya: canli_goruntu.py  (Pi kamera ile canlı görüntü, çıkmak için q)
from picamera2 import Picamera2
from libcamera import controls
import cv2

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(
    main={"size": (640, 480), "format": "RGB888"}))
picam2.start()
# Yalnızca Camera Module 3 için: sürekli otomatik odak
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})

while True:
    kare = picam2.capture_array()
    gri = cv2.cvtColor(kare, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Renkli", kare)
    cv2.imshow("Gri", gri)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

picam2.stop()
cv2.destroyAllWindows()

USB Web Kamerası Kullanıyorsanız

USB kamerada picamera2 yerine OpenCV’nin VideoCapture sınıfını kullanırız. Pi 5’te sistemde birçok video aygıtı bulunduğu için kameranızın numarası 0 olmayabilir. Terminalde v4l2-ctl --list-devices komutuyla (gerekirse sudo apt install v4l-utils) USB kameranızın hangi /dev/videoN olduğunu görün ve o sayıyı yazın.

# dosya: webcam_goruntu.py  (USB web kamerası ile, çıkmak için q)
import cv2

kamera = cv2.VideoCapture(0)      # açılmazsa 1, 2 ... deneyin
kamera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
kamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

if not kamera.isOpened():
    print("Kamera açılamadı. Kamera numarasını değiştirip tekrar deneyin.")
else:
    while True:
        basarili, kare = kamera.read()
        if not basarili:
            print("Görüntü alınamadı.")
            break
        cv2.imshow("Web kamerasi", kare)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    kamera.release()
    cv2.destroyAllWindows()

Bu kursun bütün kamera programlarında, picamera2 yerine bu yöntemi kullanabilirsiniz. Değişen tek şey görüntünün nereden alındığıdır; kamera.read() de bize aynı türden, BGR sıralı bir NumPy dizisi verir.

Bilgisayar Bir Görüntüyü Nasıl Görür?

Bilgisayar için bir fotoğraf, sayılarla dolu bir tablodur. Her küçük noktaya piksel denir. Renkli bir görüntüde her pikselin üç değeri vardır: mavi, yeşil ve kırmızı. Her değer 0 ile 255 arasındadır. [0, 0, 255] saf kırmızı, [255, 255, 255] beyaz, [0, 0, 0] siyahtır.

Bir görüntünün piksel matrisi olarak gösterimi

Kameranız olmasa bile bunu kendi çizdiğimiz bir görüntüyle görebiliriz:

Örnek 1: Görüntü Bir Sayı Dizisidir

# dosya: deneme_goruntu.py  (kameranız yoksa da çalışır)
import cv2
import numpy as np

# 300 piksel yüksekliğinde, 400 piksel genişliğinde beyaz bir tuval
img = np.full((300, 400, 3), 255, dtype=np.uint8)
cv2.rectangle(img, (30, 60), (150, 200), (0, 0, 255), -1)    # kırmızı kare (BGR!)
cv2.circle(img, (260, 130), 60, (255, 0, 0), -1)             # mavi daire
cv2.rectangle(img, (320, 200), (380, 270), (0, 200, 0), -1)  # yeşil kare
cv2.imwrite("deneme.png", img)

print("Boyut (yükseklik, genişlik, kanal):", img.shape)
print("Toplam piksel sayısı:", img.shape[0] * img.shape[1])
print("(y=100, x=90) pikseli [B G R]:", img[100, 90])
print("(y=130, x=260) pikseli [B G R]:", img[130, 260])
print("(y=10, x=10) pikseli [B G R]:", img[10, 10])

Beklenen çıktı:

Boyut (yükseklik, genişlik, kanal): (300, 400, 3)
Toplam piksel sayısı: 120000
(y=100, x=90) pikseli [B G R]: [  0   0 255]
(y=130, x=260) pikseli [B G R]: [255   0   0]
(y=10, x=10) pikseli [B G R]: [255 255 255]

Dikkat edin: Piksele img[y, x] diye, önce satırla (yükseklik) sonra sütunla (genişlik) ulaşırız. Kırmızı karenin pikseli [0 0 255] çıktı; çünkü OpenCV’de renk sırası BGR’dir.

Örnek 2: Temel İşlemler

Görüntü tanıma modelleri genellikle sabit boyutta görüntü ister. Teachable Machine modelleri 224×224 piksellik görüntülerle çalışır. Bu yüzden yeniden boyutlandırma ve kırpma, modeli çalıştırmadan önce her karede yapacağımız işlemlerdir.

# dosya: temel_islemler.py
import cv2

img = cv2.imread("deneme.png")

gri = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)     # gri ton
kucuk = cv2.resize(img, (224, 224))             # modeller genelde 224x224 ister
kirpik = img[50:250, 100:300]                   # [y1:y2, x1:x2]
bulanik = cv2.GaussianBlur(img, (15, 15), 0)    # gürültü azaltma
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)      # renk sırasını çevir

print("Gri boyut:", gri.shape)
print("Kırmızı karenin gri değeri:", gri[100, 90])
print("Küçültülmüş boyut:", kucuk.shape)
print("Kırpılmış boyut:", kirpik.shape)
print("Aynı piksel BGR:", img[100, 90], "RGB:", rgb[100, 90])

for ad, resim in [("gri.png", gri), ("kucuk.png", kucuk),
                  ("kirpik.png", kirpik), ("bulanik.png", bulanik)]:
    cv2.imwrite(ad, resim)
print("4 dosya kaydedildi.")

Beklenen çıktı:

Gri boyut: (300, 400)
Kırmızı karenin gri değeri: 76
Küçültülmüş boyut: (224, 224, 3)
Kırpılmış boyut: (200, 200, 3)
Aynı piksel BGR: [  0   0 255] RGB: [255   0   0]
4 dosya kaydedildi.

Gri tonda her pikselin tek bir parlaklık değeri vardır, bu yüzden görüntünün üçüncü boyutu kaybolur. Kırmızının gri değeri 76 çıktı; OpenCV gri değeri hesaplarken yeşile en çok, maviye en az ağırlık verir. Son satırda aynı pikselin BGR ve RGB yazılışını görüyoruz: Değerler aynı, yalnızca sırası farklı.

Örnek 3: Renge Göre Nesne Bulma

Belirli bir rengi bulmak için görüntüyü HSV renk uzayına çeviririz. HSV’de H (ton) rengin kendisini, S (doygunluk) canlılığını, V (değer) parlaklığını tutar. Böylece “mavi ama biraz karanlık” bir pikseli de mavi olarak yakalayabiliriz.

# dosya: renk_bul.py  (görüntüdeki mavi nesneyi bul)
import cv2
import numpy as np

img = cv2.imread("deneme.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# OpenCV'de ton (H) 0-179 arasıdır; mavi yaklaşık 100-130
alt = np.array([100, 120, 70])
ust = np.array([130, 255, 255])
maske = cv2.inRange(hsv, alt, ust)    # mavi pikseller 255, diğerleri 0
cv2.imwrite("maske.png", maske)

mavi_piksel = cv2.countNonZero(maske)
oran = mavi_piksel / maske.size * 100
print(f"Mavi piksel: {mavi_piksel} (görüntünün %{oran:.1f}'i)")

konturlar, _ = cv2.findContours(maske, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for k in konturlar:
    x, y, w, h = cv2.boundingRect(k)
    print(f"Mavi nesne: x={x}, y={y}, genişlik={w}, yükseklik={h}")
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 0), 2)
cv2.imwrite("bulunan.png", img)

Beklenen çıktı:

Mavi piksel: 11289 (görüntünün %9.4'i)
Mavi nesne: x=200, y=70, genişlik=121, yükseklik=121

Bu yöntem kurallarla yapılan bir görüntü işlemedir: Mavinin aralığını biz söyledik. Işık değişince ya da mavi bir arka plan olunca bu kural bozulur. Önümüzdeki derslerde aynı işi örneklerden öğrenen bir modele yaptıracağız.

OpenCV işlemlerinin önce ve sonra görünümü

⚠️ Önemli Not

OpenCV renkleri BGR, matplotlib ve Teachable Machine modelleri ise RGB sırasıyla kullanır. Bir görüntüyü matplotlib ile gösterdiğinizde kırmızılar mavi görünüyorsa ya da modeliniz renkleri karıştırıyorsa önce cv2.cvtColor(img, cv2.COLOR_BGR2RGB) ile dönüşüm yapıp yapmadığınızı kontrol edin.

Sıra Sizde

  1. Kolay: kamera_foto.py programını, çektiği fotoğrafın gri tonlu bir kopyasını da ilk_foto_gri.jpg adıyla kaydedecek şekilde değiştirin.
  2. Orta: renk_bul.py programını mavi yerine yeşil kareyi bulacak şekilde değiştirin. (İpucu: Yeşilin ton aralığı yaklaşık 40–80’dir.)
  3. Zor: Canlı görüntü programına renk bulmayı ekleyin: Kameraya mavi bir nesne gösterdiğinizde etrafına dikdörtgen çizilsin ve terminale nesnenin kaplama oranı yazılsın.

Kendini Dene

  1. picamera2’de "RGB888" biçimi pikselleri hangi sırayla verir?
  2. 640×480 boyutundaki renkli bir görüntünün shape değeri nedir?
  3. img[50:250, 100:300] ifadesi ne yapar?

Cevaplar

  1. [Mavi, Yeşil, Kırmızı] yani BGR sırasıyla verir; bu OpenCV ile uyumludur.
  2. (480, 640, 3): Önce yükseklik, sonra genişlik, en sonda 3 renk kanalı gelir.
  3. Görüntünün 50. ile 250. satırları ve 100. ile 300. sütunları arasındaki bölgeyi kırpar. Sonuç 200×200 piksellik bir görüntüdür.