Okullar için Robotik ve Mühendislik · anaokulundan liseye

7. ünite / 12

Konturlar ve şekil öznitelikleri: say, ölç, sınıflandır

findContours, alan ve çevre, momentler ve ağırlık merkezi, sınırlayıcı kutu, approxPolyDP, dairesellik ve dışbükeylik.

Bu ünitenin sonunda

  • İkili maskeden konturları bulmak ve nesneleri saymak
  • Alan, çevre, ağırlık merkezi ve sınırlayıcı kutuyu hesaplamak
  • Douglas-Peucker ile konturu çokgene indirip köşe sayısından şekil tahmin etmek
  • Dairesellik ve dışbükeylik (solidity) ile ölçeğe bağımsız öznitelikler kurmak

Ders notları

Kontur, bir nesnenin sınırını izleyen nokta dizisidir. cv2.findContours ikili görüntüde beyaz bölgelerin sınırlarını bulur; RETR_EXTERNAL yalnız dış sınırları, RETR_TREE iç içe delikleri de hiyerarşiyle verir.

Ölçüler

  • Alan (contourArea): ayakkabı bağı formülü, ½·|Σ(xiyi+1 − xi+1yi)|.
  • Çevre (arcLength): ardışık noktalar arası uzaklıkların toplamı.
  • Momentler: m00 alan, ağırlık merkezi (m10/m00, m01/m00).
  • Sınırlayıcı kutu (boundingRect) ve en küçük döndürülmüş kutu (minAreaRect).

Şekil tanıma

approxPolyDP (Douglas-Peucker) konturu, her noktası en fazla ε uzakta kalacak biçimde daha az köşeli bir çokgene indirir; ε genelde çevrenin %1–3'üdür. Üç köşe üçgen, dört köşe dörtgen (en/boy oranı ≈ 1 ise kare), çok köşe ve yüksek dairesellik daire demektir.

dairesellik = 4π · A / P²   (daire 1, kare ≈ 0,785)    solidity = A / Adışbükey örtü

Bu oranlar ölçekten bağımsızdır: nesne kameraya yaklaşsa da değişmez. Bu yüzden basit sınıflandırıcılar için iyi özniteliklerdir.

Oyun alanı

Konturlar ve şekil öznitelikleri

Eşiklenmiş görüntüde her nesnenin dış sınırı bulunur. Alan, çevre, dairesellik (4πA/P²), sınırlayıcı kutu ve çokgen yaklaşımındaki köşe sayısı sağdaki tabloda; köşe sayısına göre şekil adı tahmin edilir.

Önce: ikili maske
Sonra: konturlar, çokgen ve kutu
#AlanÇevreDairesellikKöşeKutuŞekil
15039260.50.93879×79daire
24353257.70.82466×66kare
34317269.70.75490×48dikdörtgen
44205249.10.85680×70altıgen
53751239.10.82574×71beşgen
61903199.70.60364×56üçgen
nesne sayısı: 6

Kendin dene

Renkli şekillerde tablodaki köşe sayılarına ve daireselliğe bak: hangi şekil en yuvarlak? ε oranını %1'den %8'e çıkar: altıgen ve daire hangi değerde yanlış sınıflanmaya başlıyor? Sonra gürültülü pullara geç: önce kontur sayısını, sonra en küçük alan sınırını 50 yapınca kalan sayıyı yaz. Kendi fotoğrafını (beyaz kâğıtta birkaç nesne) yükle ve aynı sayımı dene.

Kod

Python: konturlar, momentler ve şekil adı
import cv2
import numpy as np

img = cv2.imread('girdi.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, bw = cv2.threshold(cv2.GaussianBlur(gray, (5, 5), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
if (bw > 0).mean() > 0.5:
    bw = 255 - bw                                 # nesneler beyaz, arka plan siyah olmalı

contours, hierarchy = cv2.findContours(bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
out = img.copy()
for cnt in contours:
    A = cv2.contourArea(cnt)
    if A < 200:                                   # küçük gürültüyü atla
        continue
    P = cv2.arcLength(cnt, True)
    circ = 4 * np.pi * A / (P * P)                # daire 1, kare yaklaşık 0,785
    approx = cv2.approxPolyDP(cnt, 0.02 * P, True)
    M = cv2.moments(cnt)
    cx, cy = int(M['m10'] / M['m00']), int(M['m01'] / M['m00'])
    v = len(approx)
    name = {3: 'tri', 4: 'quad'}.get(v, 'circle' if circ > 0.8 else f'{v}-gon')
    x, y, w, h = cv2.boundingRect(cnt)
    print(f'{name:7s} A={A:7.0f} P={P:6.1f} circ={circ:.2f} merkez=({cx},{cy}) box={w}x{h}')
    cv2.drawContours(out, [approx], -1, (0, 0, 255), 2)
    cv2.putText(out, name, (cx - 20, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
cv2.imwrite('cikti.png', out)

Sık yapılan hatalar

  • findContours'a gri ya da renkli görüntü vermek: ikili (0/255) tek kanallı görüntü ister. Önce eşikle.
  • Siyah nesne beyaz zeminde: OpenCV beyaz bölgeleri nesne sayar, zemini tek dev kontur olarak bulursun. Maskeyi ters çevir.
  • Küçük gürültü konturlarını süzmemek: sayım şişer. En küçük alan sınırı koy ya da önce açma uygula.
  • approxPolyDP'de sabit ε (piksel) kullanmak: büyük nesnede çok köşe, küçükte az köşe çıkar. ε'yi çevreye oranla.

Yazılım mühendisliği bağlantısı

Kontur öznitelikleri basit bir kural tabanlı sınıflandırıcıya girer. Kuralları kodun içine dağıtma; bir tabloda topla.

  • Kuralları (köşe sayısı, dairesellik aralığı) veri olarak tut, her kural için bir test yaz.
  • Yanlış sınıflanan örnekleri bir klasörde biriktir; kural değiştikçe bu "regresyon seti" ile sına.

Kendini sına

  1. Yarıçapı 10 px olan bir dairenin dairesellik değeri (4πA/P²) yaklaşık kaçtır?

  2. Kenar uzunluğu 20 px olan bir karenin dairesellik değeri yaklaşık kaçtır?

  3. approxPolyDP'de ε neden çevrenin bir oranı olarak seçilir?

  4. Ağırlık merkezi momentlerden nasıl bulunur?

Bu üniteden sonra bitirme projesinde

  • Köşe bulma: kose_bul ve kose_sirala; altın sette G1 ölçümü ve başarısız örneklerin listesi.
Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç