Kurs içeriği (5 / 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 5 / 10

Görüntü Tanıma Modeli Eğitip Pi’de Çalıştırma

Uygulama ⏱ 120 dk

Topladığımız fotoğraflarla Teachable Machine’de bir görüntü tanıma modeli eğitiyor, modeli TensorFlow Lite biçiminde dışa aktarıyoruz. Modeli Raspberry Pi’de LiteRT (ai-edge-litert) ile çalıştıran, labels.txt dosyasını okuyan, güven puanı ve FPS gösteren canlı bir tanıma programı yazıyoruz.

Bu derste

  • Teachable Machine’de görüntü projesi oluşturur, fotoğraf yükler ve model eğitir.
  • Eğitilen modeli TensorFlow Lite biçiminde dışa aktarır ve Raspberry Pi’ye taşır.
  • Bir görüntüyü modelin beklediği biçime getirir (kırpma, 224×224, RGB, [-1, 1] aralığı).
  • LiteRT ile modeli çalıştırır; labels.txt dosyasından etiketleri okur ve güven puanını yorumlar.
  • Canlı görüntüde tahmin, güven eşiği ve FPS gösteren bir program yazar.

Malzemeler

  • Raspberry Pi 5 veya 4 ve kamera
  • Ders 4’te toplanan veri seti
  • İnternet bağlantılı bir bilgisayar ve Chrome/Edge tarayıcı
  • Teachable Machine (teachablemachine.withgoogle.com)
  • ai-edge-litert (yzenv içinde)

Fotoğraflarımız hazır. Bu derste en heyecanlı adımı atıyoruz: Bu fotoğraflardan bir görüntü tanıma modeli eğitecek ve modeli Raspberry Pi’de, internete ihtiyaç duymadan, canlı kamera görüntüsü üzerinde çalıştıracağız.

Dersin Amacı ve Kazanımlar

Bu dersin sonunda:

  1. Teachable Machine’de görüntü projesi oluşturup model eğitebileceksiniz.
  2. Modeli TensorFlow Lite biçiminde dışa aktarıp Raspberry Pi’ye taşıyabileceksiniz.
  3. Bir görüntüyü modelin beklediği biçime getirebileceksiniz.
  4. LiteRT ile modeli çalıştırıp güven puanını yorumlayabileceksiniz.
  5. Canlı görüntüde tahmin, güven eşiği ve FPS gösteren bir program yazabileceksiniz.

Gerekli Malzemeler

Malzeme Açıklama
Raspberry Pi ve kamera Veri toplarken kullandığınız kamera ve düzenek
Veri seti Ders 4’te toplanan veri/ klasörü (kagit, plastik, metal, bos)
Bilgisayar ve tarayıcı Teachable Machine eğitimi tarayıcıda yapar. Okul bilgisayarı Pi’den daha hızlı eğitir; Chrome veya Edge önerilir.
USB bellek Fotoğrafları bilgisayara, modeli Pi’ye taşımak için
ai-edge-litert Ders 1’de sanal ortama kuruldu.

💡 İpucu

Teachable Machine projenizi kaydetmeyi unutmayın. Sayfa kapanırsa bütün fotoğraflar ve model kaybolur. Sol üstteki menüden (☰) Save project to Drive ile projeyi Google Drive’a kaydedebilir ya da Download project as file ile bilgisayarınıza dosya olarak indirebilirsiniz.

1. Adım: Teachable Machine’de Modeli Eğitme

Teachable Machine, Google’ın tarayıcıda çalışan ücretsiz model eğitme aracıdır. Arka planda aktarımlı öğrenme (transfer learning) kullanır: Milyonlarca fotoğrafla önceden eğitilmiş bir modelin (MobileNet) görmeyi bilen kısmını alır, yalnızca son katmanı bizim sınıflarımızla yeniden eğitir. Bu yüzden birkaç yüz fotoğrafla bile iyi sonuç verir.

  1. Ders 4’te topladığınız veri klasörünü USB belleğe kopyalayıp bilgisayara takın.
  2. teachablemachine.withgoogle.com adresine gidin, Get Started düğmesine tıklayın. New Project ekranında Image Project kartını, açılan pencerede de Standard image model seçeneğini seçin (Embedded image model mikrodenetleyiciler içindir; 96×96 gri tonlu görüntü kullanır).
  3. Class 1 yazısına tıklayıp adını kagit yapın. Aynı şekilde plastik, metal ve bos sınıflarını oluşturun (Add a class). Adları veri klasörlerinizle birebir aynı yazın.
  4. Her sınıf kutusunda Add Image Samples: altındaki Upload düğmesine tıklayın. Choose images from your files, or drag & drop here alanına tıklayıp o sınıfın klasöründeki bütün fotoğrafları seçin ya da fotoğrafları bu alana sürükleyip bırakın. (Fotoğraflarınız Google Drive’daysa Import images from Google Drive seçeneğini kullanabilirsiniz.) Yükleme bitince sınıf kutusunda örnek sayısı görünür, örneğin “120 Image Samples”.
  5. Training kutusundaki Train Model düğmesine basın. Eğitim bitene kadar sekmeyi kapatmayın ve başka sekmeye geçmeyin. Eğitim bitince düğmede Model Trained yazar. Epoch sayısı gibi ayarlar Advanced bölümündedir; varsayılan değerler bu proje için yeterlidir.
  6. Sağdaki Preview bölümünde Input anahtarı ON konumundayken modeli deneyin: Yanındaki listeden Webcam seçerek bilgisayarın kamerasıyla ya da File seçerek fotoğraf yükleyerek. Sonuçlar Output bölümündeki çubuklarda görünür.

Teachable Machine’de dört sınıflı görüntü projesi

2. Adım: Modeli Dışa Aktarma

  1. Preview bölümündeki Export Model düğmesine tıklayın.
  2. Açılan pencerenin üstünde üç sekme vardır: Tensorflow.js, Tensorflow ve Tensorflow Lite. Tensorflow Lite sekmesini seçin.
  3. Model conversion type: (Model dönüştürme türü) bölümünde üç seçenek vardır: Floating point, Quantized ve EdgeTPU. Floating point seçili olsun ve Download my model düğmesine basın.
  4. Dönüştürme Google’ın sunucularında yapılır ve bir iki dakika sürebilir. Sonunda converted_tflite.zip dosyası iner.

Teachable Machine’de TensorFlow Lite olarak dışa aktarma

Zip dosyasını USB bellekle Pi’ye taşıyıp proje klasörünüze açın:

cd ~/geri_donusum
unzip converted_tflite.zip -d model
ls model
labels.txt  model_unquant.tflite

labels.txt dosyasının her satırında bir sınıf numarası ve adı vardır: 0 kagit, 1 plastik gibi. Model bize yalnızca sayılar verir; hangi sayının hangi sınıf olduğunu bu dosyadan öğreniriz.

3. Adım: Modeli Python’da Çalıştırma

Modelin kurallarını iyi bilmemiz gerekir. Teachable Machine’in görüntü modeli:

  • 224×224 piksellik, RGB sıralı görüntü ister.
  • Piksel değerlerini 0–255 değil, -1 ile 1 arasında bekler. Bunun için her değeri 127,5’e bölüp 1 çıkarırız.
  • Girişi (1, 224, 224, 3) biçiminde, yani “bir görüntülük bir paket” olarak ister.

Kameramız ise 640×480, BGR sıralı görüntü veriyor. Aradaki dönüşümü yapan kodu ayrı bir dosyaya, goruntu_model.py dosyasına yazacağız. Böylece bu dosyayı sonraki derslerde başka programlardan import ile kullanabileceğiz.

Kameradan tahmine giden adımlar

# dosya: goruntu_model.py
# Teachable Machine'den indirilen TensorFlow Lite modelini yükler ve kullanır.
import cv2
import numpy as np
from ai_edge_litert.interpreter import Interpreter
# tflite-runtime kurduysanız üstteki satır yerine:
# from tflite_runtime.interpreter import Interpreter

MODEL_DOSYASI = "model/model_unquant.tflite"
ETIKET_DOSYASI = "model/labels.txt"


def etiketleri_oku(dosya):
    etiketler = []
    with open(dosya, encoding="utf-8") as f:
        for satir in f:
            satir = satir.strip()
            if satir:
                etiketler.append(satir.split(" ", 1)[-1])   # "0 kagit" -> "kagit"
    return etiketler


etiketler = etiketleri_oku(ETIKET_DOSYASI)
yorumlayici = Interpreter(model_path=MODEL_DOSYASI, num_threads=4)
yorumlayici.allocate_tensors()
giris = yorumlayici.get_input_details()[0]
cikis = yorumlayici.get_output_details()[0]
YUKSEKLIK, GENISLIK = int(giris["shape"][1]), int(giris["shape"][2])


def hazirla(kare):
    """BGR kareyi modelin beklediği biçime getirir."""
    h, w = kare.shape[:2]
    kenar = min(h, w)                           # 1) ortadan kare kırp
    y0, x0 = (h - kenar) // 2, (w - kenar) // 2
    kare = kare[y0:y0 + kenar, x0:x0 + kenar]
    kare = cv2.resize(kare, (GENISLIK, YUKSEKLIK))   # 2) 224x224
    kare = cv2.cvtColor(kare, cv2.COLOR_BGR2RGB)    # 3) BGR -> RGB
    veri = kare.astype(np.float32) / 127.5 - 1.0    # 4) 0..255 -> -1..1
    if giris["dtype"] != np.float32:                # "Quantized" model seçildiyse
        olcek, sifir = giris["quantization"]
        sinir = np.iinfo(giris["dtype"])
        veri = np.clip(np.round(veri / olcek + sifir), sinir.min, sinir.max)
        veri = veri.astype(giris["dtype"])
    return np.expand_dims(veri, axis=0)             # 5) (1, 224, 224, 3)


def tahmin_et(kare):
    """(etiket, güven, bütün olasılıklar) döndürür."""
    yorumlayici.set_tensor(giris["index"], hazirla(kare))
    yorumlayici.invoke()
    sonuc = yorumlayici.get_tensor(cikis["index"])[0]
    if cikis["dtype"] != np.float32:
        olcek, sifir = cikis["quantization"]
        sonuc = (sonuc.astype(np.float32) - sifir) * olcek
    i = int(np.argmax(sonuc))
    return etiketler[i], float(sonuc[i]), sonuc

Kodun en önemli kısmı tahmin_et() fonksiyonudur. Önce hazırlanmış görüntüyü modelin girişine koyar (set_tensor), modeli çalıştırır (invoke) ve çıkıştaki olasılıkları okur (get_tensor). En yüksek olasılığın sırasını np.argmax() bulur; bu sıra numarası labels.txt dosyasındaki sınıfa karşılık gelir. Teachable Machine’den Quantized modeli indirirseniz giriş ve çıkış 0–255 arasında tam sayı olur. Koddaki if blokları bu dönüşümü de yapar; yani program iki model türüyle de çalışır.

Tek Fotoğrafla Deneme

Canlı görüntüye geçmeden önce modeli veri setinizden bir fotoğrafla deneyin:

# dosya: foto_test.py  (tek bir fotoğrafla modeli dene)
import cv2
from goruntu_model import tahmin_et, etiketler, giris

DOSYA = "veri/plastik/plastik_012.jpg"

kare = cv2.imread(DOSYA)
etiket, guven, olasiliklar = tahmin_et(kare)

print("Model girişi:", giris["shape"], giris["dtype"].__name__)
print("Dosya:", DOSYA)
print(f"Tahmin: {etiket} (%{guven * 100:.1f})")
for ad, p in zip(etiketler, olasiliklar):
    print(f"  {ad:<8} %{p * 100:5.1f}")

Örnek çıktı: (Raspberry Pi 5 üzerinde örnek çıktı. Yüzdeler sizin veri setinize ve modelinize göre farklı olacaktır. Çıktının başında “INFO: Created TensorFlow Lite XNNPACK delegate for CPU.” satırı da görünebilir; bu bir hata değil, LiteRT’nin bilgi mesajıdır.)

Model girişi: [  1 224 224   3] float32
Dosya: veri/plastik/plastik_012.jpg
Tahmin: plastik (%97.8)
  kagit    %  0.9
  plastik  % 97.8
  metal    %  1.1
  bos      %  0.2

Dört olasılığın toplamı yaklaşık %100 eder. Model plastikten çok emin; ama her zaman böyle olmayacak. Kamera bir nesneyi ilk kez görüyorsa olasılıklar sınıflara dağılabilir.

4. Adım: Canlı Görüntü Tanıma

# dosya: canli_tanima.py  (canlı görüntü tanıma, çıkmak için q)
from picamera2 import Picamera2
import cv2
import time
from goruntu_model import tahmin_et

ESIK = 0.70        # bu güvenin altındaki tahminlere "emin değilim" diyeceğiz

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(
    main={"size": (640, 480), "format": "RGB888"}))
picam2.start()

fps = 0.0
onceki = time.time()
while True:
    kare = picam2.capture_array()
    etiket, guven, _ = tahmin_et(kare)

    simdi = time.time()
    fps = 0.9 * fps + 0.1 * (1 / (simdi - onceki))   # yumuşatılmış FPS
    onceki = simdi

    if guven >= ESIK:
        yazi, renk = f"{etiket} %{guven * 100:.0f}", (0, 200, 0)
    else:
        yazi, renk = "emin degilim", (0, 0, 255)
    cv2.putText(kare, yazi, (10, 35), cv2.FONT_HERSHEY_SIMPLEX, 1.1, renk, 2)
    cv2.putText(kare, f"FPS: {fps:.1f}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)
    cv2.imshow("Goruntu tanima", kare)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

picam2.stop()
cv2.destroyAllWindows()

Program her karede tahmin yapar ve sonucu görüntünün üzerine yazar. İki yeni fikir var:

  • Güven eşiği: En yüksek olasılık %70’in altındaysa model aslında kararsızdır. Böyle durumlarda yanlış bir cevap vermek yerine “emin değilim” demek daha doğrudur. Eşiği projenize göre ayarlayabilirsiniz.
  • FPS (saniyedeki kare sayısı): İki kare arasındaki süreden hesaplanır. Sayı her karede biraz oynadığı için eski değerle yeni değeri karıştırarak yumuşatıyoruz. Pi 5’te bu model için genellikle saniyede onlarca kare görürsünüz; Pi 4’te bu sayı daha düşüktür.

Pi ekranında canlı görüntü tanıma

⚠️ Önemli Not

OpenCV’nin putText fonksiyonu Türkçe karakterleri (ç, ğ, ı, ö, ş, ü) çizemez, onların yerine soru işareti çıkar. Bu yüzden sınıf adlarını Türkçe karaktersiz verdik ve ekrana “emin degilim” yazdık. Teachable Machine’de dışa aktarma sırasında “Something went wrong while converting” gibi bir hata alırsanız birkaç dakika sonra tekrar deneyin ya da başka bir tarayıcıyla, gizli pencerede deneyin; dönüştürme Google’ın sunucularında yapıldığı için bazen geçici sorunlar yaşanabiliyor.

Sıra Sizde

  1. Kolay: ESIK değerini 0.5 ve 0.9 yaparak programı çalıştırın. Hangi değerde daha sık “emin degilim” yazısını görüyorsunuz? Neden?
  2. Orta: canli_tanima.py programına, s tuşuna basıldığında o anki kareyi tahmin edilen sınıfın adıyla kayit/ klasörüne kaydeden bir özellik ekleyin.
  3. Zor: Ekrana yalnızca en yüksek tahmini değil, dört sınıfın olasılığını da küçük çubuklar hâlinde çizin. (İpucu: cv2.rectangle() ile genişliği olasılıkla orantılı dikdörtgenler çizin.)

Kendini Dene

  1. Teachable Machine görüntü modeli girişte hangi boyutta ve hangi renk sırasında görüntü ister?
  2. labels.txt dosyası ne işe yarar?
  3. Modelin en yüksek olasılığı %45 çıktıysa programımız ne yapar? Bu neden iyi bir davranıştır?

Cevaplar

  1. 224×224 piksellik, RGB sıralı görüntü ister. Piksel değerleri de -1 ile 1 arasına getirilmelidir.
  2. Modelin çıkışındaki sıra numaralarının hangi sınıfa karşılık geldiğini söyler. Ör. 1 numaralı çıkış “plastik” sınıfıdır.
  3. %45, %70’lik eşiğin altında olduğu için “emin degilim” yazar. Model kararsızken yanlış bir cevap vermek yerine bunu söylemesi, ileride kutunun yanlış bölmeyi açmasını önler.