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

9. ünite / 12

Geometrik ve perspektif dönüşümler: döndür, ölçekle, düzle

Afin matris (2×3), getRotationMatrix2D, ara değerleme; homografi (3×3), dört nokta çifti ve belge düzleme.

Bu ünitenin sonunda

  • Döndürme, ölçekleme ve kaydırmayı tek bir 2×3 afin matrisle yazmak
  • Ters eşlemenin ve ara değerlemenin neden gerektiğini açıklamak
  • Dört nokta çiftinden 3×3 homografiyi çözmek
  • Eğik çekilmiş bir belgeyi yukarıdan bakılmış gibi düzlemek

Ders notları

Geometrik dönüşüm piksellerin değerini değil yerini değiştirir. Afin dönüşüm doğruları doğru, paralelleri paralel tutar ve 2×3 bir matrisle yazılır:

[x′; y′] = [a b tx; c d ty] · [x; y; 1]

cv2.getRotationMatrix2D(merkez, açı, ölçek) bu matrisi verir; OpenCV'de pozitif açı saat yönünün tersidir. Afin dönüşüm üç nokta çiftinden de bulunur (getAffineTransform).

Ters eşleme ve ara değerleme

warpAffine her hedef pikseli ters matrisle kaynağa götürür ve oradan örnekler; ileri eşlemede hedefte delikler kalırdı. Kaynak konumu genelde tam sayı değildir: en yakın komşu hızlıdır ama basamaklı kenar verir, çift doğrusal dört komşunun ağırlıklı ortalamasıdır ve daha yumuşaktır.

Perspektif (homografi)

Bir düzleme açılı bakınca dikdörtgen yamuk görünür; paralellik bozulur. Bunu 3×3 bir homografi düzeltir: [x′w; y′w; w] = H·[x; y; 1]. H'nin 8 serbest değeri vardır; dört nokta çifti (her biri iki denklem) yeter: getPerspectiveTransform. Belge tarayıcıda dört köşe bulunur, sol üst–sağ üst–sağ alt–sol alt sırasına konur ve hedef dikdörtgene eşlenir.

Oyun alanları

Geometrik dönüşümler: döndür, ölçekle, kaydır

2×3 afin matrisi sağda. Açıyı, ölçeği ve kaydırmayı değiştir; ara değerleme (en yakın komşu ya da çift doğrusal) farkını kenarlarda gör.

Önce
Sonra: warpAffine
M (2×3) 0.866 0.500 -38.564 -0.500 0.866 96.077 α = s·cosθ = 0.866 β = s·sinθ = 0.500

Perspektif düzeltme (belge)

Belgenin dört köşesini sürükle ya da "Köşeleri bul" ile otomatik bulmasını iste. 3×3 homografi dört nokta çiftinden çözülür ve belge yukarıdan çekilmiş gibi düzlenir.

Önce: köşeler (sürükle)
Sonra: warpPerspective
H (3×3) 1.275 0.249 -106.117 -0.145 1.347 -38.788 -0.000 0.002 1.000

Köşeleri sürükle. Kırmızı nokta sol üst köşe olarak sıralandı.

3B masa ve sanal kamera

Masada A4 bir belge ve iğne deliği modeliyle bir kamera. Kamerayı yükselt, döndür, yaklaştır: görüntü bu kameradan gerçekten üretilir (her pikselin ışını masa düzlemiyle kesiştirilir). Sonra köşe bulma ve perspektif düzeltme aynı görüntüye uygulanır; gerçek köşelerle karşılaştırılır.

Masa, belge ve sanal kamera (pembe: görüş piramidi, yeşil: köşe ışınları) · sürükle: döndür, iki parmak / tekerlek: yakınlaş
Sanal kameranın görüntüsü (iğne deliği modeli)
Köşe bulma + warpPerspective (A4)
gerçek köşeler (kırmızı) ile bulunanlar (yeşil) en büyük hata: 2.3 px K = [[300, 0, 160], [0, 300, 120], [0, 0, 1]]

Kendin dene

Dönüşüm aracında açıyı 30°, ölçeği 1,5 yap ve matrisin a, b değerlerinin cos ve sin ile ilişkisini doğrula. Ara değerlemeyi en yakın komşuya çevirip yıldızın kenarındaki basamakları gör. Perspektif aracında köşeleri bul, sonra bir köşeyi bilerek 15 px kaydır: düzlenmiş belgede satırlar ne oldu? Kendi çektiğin eğik bir sayfa fotoğrafını yükle ve köşeleri elle yerleştir.

Kod

Python: döndür, ölçekle, kaydır (afin)
import cv2
import numpy as np

img = cv2.imread('girdi.png')
h, w = img.shape[:2]
M = cv2.getRotationMatrix2D((w / 2, h / 2), 30, 0.8)   # merkez, açı (derece, saat yönü tersine), ölçek
M[:, 2] += (20, -10)                              # üstüne kaydırma
print('afin matris:', np.round(M, 3).tolist())

near = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_NEAREST)
lin = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
x, y = 10, 10
print('(10,10) ->', np.round(M @ np.array([x, y, 1.0]), 1))   # bir noktayı dönüştür
Minv = cv2.invertAffineTransform(M)               # geri dönüşüm
back = cv2.warpAffine(lin, Minv, (w, h))
cv2.imwrite('cikti.png', np.hstack([near, lin, back]))
Python: belgenin köşelerini bul, perspektifi düzelt
import cv2
import numpy as np

def order(pts):
    s, d = pts.sum(1), np.diff(pts, axis=1).ravel()
    return np.float32([pts[s.argmin()], pts[d.argmin()], pts[s.argmax()], pts[d.argmax()]])   # sol üst, sağ üst, sağ alt, sol alt

img = cv2.imread('girdi.png')
gray = cv2.GaussianBlur(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), (5, 5), 0)
edges = cv2.dilate(cv2.Canny(gray, 50, 150), None)
cnts, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
quad = None
for cnt in sorted(cnts, key=cv2.contourArea, reverse=True)[:5]:
    approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True)
    if len(approx) == 4:                          # ilk dört köşeli büyük kontur: belge
        quad = order(approx.reshape(4, 2).astype(np.float32))
        break
h, w = img.shape[:2]
if quad is None:
    quad = np.float32([[0, 0], [w - 1, 0], [w - 1, h - 1], [0, h - 1]])   # bulunamazsa tüm görüntü
W, H = 420, 594                                   # A4 oranı (1 : 1,414)
dst = np.float32([[0, 0], [W - 1, 0], [W - 1, H - 1], [0, H - 1]])
Hm = cv2.getPerspectiveTransform(quad, dst)       # 4 nokta çifti: 8 bilinmeyen
print('köşeler:', quad.astype(int).tolist())
print('homografi:', np.round(Hm, 3).tolist())
cv2.imwrite('cikti.png', cv2.warpPerspective(img, Hm, (W, H)))

Sık yapılan hatalar

  • Köşe sırasını karıştırmak: dört nokta çapraz eşlenirse düzlenmiş görüntü ters ya da kelebek biçiminde çıkar. Önce sırala.
  • warpAffine'e (yükseklik, genişlik) vermek: dsize (genişlik, yükseklik) ister.
  • Döndürmede görüntünün köşelerinin kesildiğini fark etmemek: yeni boyutu cos/sin ile hesaplayıp matrisin kaydırmasını düzelt.
  • Perspektifi afinle düzeltmeye çalışmak: afin paralellikleri korur, yamuk bir sayfayı düzeltemez.

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

Geometri kodunda birim ve koordinat sistemi karışıklığı (x/y, satır/sütun, derece/radyan) en sık hata kaynağıdır.

  • Gidiş-dönüş testi yaz: bir noktayı H ile götür, H⁻¹ ile geri getir; aynı nokta olmalı.
  • Dört köşenin hedefe tam oturduğunu sınayan bir test, köşe sıralama hatalarını anında yakalar.

Kendini sına

  1. Bir homografiyi (3×3, ölçek serbest) çözmek için en az kaç nokta çifti gerekir?

  2. warpAffine neden ters eşleme kullanır?

  3. Afin dönüşüm hangi özelliği korur?

  4. Eğik çekilmiş bir sayfayı düzlemek için hangisi gerekir?

Bu üniteden sonra bitirme projesinde

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ç