Dersler

View on GitHub

EEM-241 İleri Düzey Programlama

2024-2025 Güz Dönemi

Ders 13 - OpenCV II: Görüntü İşleme Hattı

1. Hazırlık ve yardımcı gösterim fonksiyonu

import cv2
import numpy as np
import matplotlib.pyplot as plt
def goster(baslik, goruntu, gri=False):
    fig, ax = plt.subplots()
    if gri:
        ax.imshow(goruntu, cmap="gray", vmin=0, vmax=255)
    else:
        ax.imshow(cv2.cvtColor(goruntu, cv2.COLOR_BGR2RGB))
    ax.set_title(baslik)
    ax.axis("off")
    plt.show()
img = cv2.imread("files/image.jpg")
if img is None:
    raise FileNotFoundError("Görüntü bulunamadı.")

2. Görüntü aritmetiği ve doygunluk

uint8 dizilerde doğrudan NumPy toplaması 255’ten sonra başa dönebilir. cv2.add ise sonucu 0–255 aralığında doyurur.

a = np.array([250], dtype=np.uint8)
b = np.array([20], dtype=np.uint8)

print(a + b)
print(cv2.add(a, b))

Parlaklık artırma ve azaltma:

artis = np.full(img.shape, 50, dtype=np.uint8)
daha_parlak = cv2.add(img, artis)
daha_koyu = cv2.subtract(img, artis)

Parlaklık ve kontrastı birlikte değiştirme:

kontrastli = cv2.convertScaleAbs(img, alpha=1.3, beta=20)

3. Çizim işlemleri

Çizim fonksiyonları verilen görüntüyü yerinde değiştirir. Orijinali korumak için kopya alınır.

cizim = img.copy()

cv2.line(cizim, (50, 50), (300, 150), (0, 255, 0), 3)
cv2.rectangle(cizim, (80, 80), (250, 200), (0, 0, 255), 2)
cv2.circle(cizim, (350, 180), 60, (255, 0, 0), -1)
cv2.putText(cizim, "EEM-241", (30, 40),
            cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

Renkler BGR, noktalar (x, y) sırasındadır. Kalınlık -1 verilirse kapalı şeklin içi doldurulur.

4. Maskeler ve bit düzeyi işlemler

Maske, hangi piksellerin işleme katılacağını belirleyen tek kanallı uint8 görüntüdür. Seçili alanlar 255, diğerleri 0 yapılır.

maske = np.zeros(img.shape[:2], dtype=np.uint8)
merkez = (img.shape[1] // 2, img.shape[0] // 2)
cv2.circle(maske, merkez, 100, 255, -1)

maskelenmis = cv2.bitwise_and(img, img, mask=maske)

Küme mantığını göstermek için:

dikdortgen = np.zeros((400, 600), dtype=np.uint8)
daire = np.zeros((400, 600), dtype=np.uint8)

cv2.rectangle(dikdortgen, (50, 50), (300, 350), 255, -1)
cv2.circle(daire, (350, 200), 150, 255, -1)

kesisim = cv2.bitwise_and(dikdortgen, daire)
birlesim = cv2.bitwise_or(dikdortgen, daire)
farkli_bolgeler = cv2.bitwise_xor(dikdortgen, daire)

5. Gürültü azaltma ve yumuşatma

İşlem sırası önemlidir: gürültü azaltma genellikle eşikleme veya kenar bulmadan önce yapılır.

gri = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ortalama_filtre = cv2.blur(gri, (5, 5))
gauss_filtre = cv2.GaussianBlur(gri, (5, 5), 0)
medyan_filtre = cv2.medianBlur(gri, 5)

Özel çekirdek ile filtreleme:

kernel = np.ones((3, 3), dtype=np.float32) / 9
filtrelenmis = cv2.filter2D(gri, -1, kernel)

6. Eşikleme

Bu bölümde gradient.jpg görüntüsü kullanılacaktır.

gradient = cv2.imread("files/gradient.jpg", cv2.IMREAD_GRAYSCALE)
if gradient is None:
    raise FileNotFoundError("gradient.jpg bulunamadı.")

esik, ikili = cv2.threshold(gradient, 127, 255, cv2.THRESH_BINARY)
_, ters_ikili = cv2.threshold(gradient, 127, 255, cv2.THRESH_BINARY_INV)

Eşiğin veriden otomatik belirlenmesi için Otsu yöntemi:

_, otsu = cv2.threshold(
    gradient, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU
)

Aydınlatmanın görüntü boyunca değiştiği durumda uyarlamalı eşikleme kullanılabilir:

uyarlamali = cv2.adaptiveThreshold(
    gradient, 255,
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY,
    11, 2
)

7. Morfolojik işlemler

Morfolojik işlemler ikili görüntülerde küçük boşlukları veya gürültü noktalarını düzenlemek için kullanılır.

kernel = np.ones((3, 3), dtype=np.uint8)

acilmis = cv2.morphologyEx(otsu, cv2.MORPH_OPEN, kernel)
kapanmis = cv2.morphologyEx(otsu, cv2.MORPH_CLOSE, kernel)

8. Kenar bulma

gri = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
yumusak = cv2.GaussianBlur(gri, (5, 5), 0)
kenarlar = cv2.Canny(yumusak, 50, 150)

Canny eşikleri görüntüye göre ayarlanır. Gürültülü görüntüde doğrudan Canny uygulamak çok sayıda sahte kenar üretebilir.

9. Kontur bulma

Konturlar, ikili görüntüdeki nesne sınırlarını temsil eder.

konturlar, _ = cv2.findContours(
    kenarlar, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)

sonuc = img.copy()

for kontur in konturlar:
    alan = cv2.contourArea(kontur)
    if alan > 100:
        x, y, w, h = cv2.boundingRect(kontur)
        cv2.rectangle(sonuc, (x, y), (x + w, y + h), (0, 255, 0), 2)

Alan filtresi, küçük gürültü konturlarını elemek için basit bir yöntemdir.

10. Kameradan görüntü alma

cap = cv2.VideoCapture(0)

if not cap.isOpened():
    raise RuntimeError("Kamera açılamadı.")

try:
    while True:
        basarili, kare = cap.read()
        if not basarili:
            print("Kare okunamadı.")
            break

        cv2.imshow("Video", kare)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
finally:
    cap.release()
    cv2.destroyAllWindows()

Kaynağın finally içinde serbest bırakılması, hata durumunda kameranın kilitli kalmasını önler.

11. Gerçek zamanlı işleme hattı

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    raise RuntimeError("Kamera açılamadı.")

try:
    while True:
        basarili, kare = cap.read()
        if not basarili:
            break

        gri = cv2.cvtColor(kare, cv2.COLOR_BGR2GRAY)
        yumusak = cv2.GaussianBlur(gri, (5, 5), 0)
        kenarlar = cv2.Canny(yumusak, 50, 150)

        cv2.imshow("Kenarlar", kenarlar)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
finally:
    cap.release()
    cv2.destroyAllWindows()

İşleme hattı: oku → doğrula → dönüştür → gürültüyü azalt → özellik çıkar → göster/kaydet.

Ders sonu alıştırmaları

  1. Aynı görüntünün orijinal, parlak ve koyu sürümlerini yan yana gösterin.
  2. Dairesel bir maske ile yalnızca görüntünün merkezini görünür bırakın.
  3. Gürültülü bir görüntüde ortalama, Gaussian ve medyan filtreyi karşılaştırın.
  4. Bir görüntüye Otsu eşikleme uygulayıp morfolojik açma ile küçük gürültüleri temizleyin.
  5. Kameradan alınan karelerde kontur alanı belirli bir sınırdan büyük nesnelerin çevresine dikdörtgen çizin.