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)
- Ortalama filtre genel yumuşatma yapar.
- Gaussian filtre doğal görüntülerde sık kullanılan bir başlangıçtır.
- Medyan filtre, tuz-biber gürültüsünde başarılıdır.
Ö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)
- Açma: küçük beyaz gürültüleri azaltır.
- Kapama: nesne içindeki küçük siyah boşlukları kapatır.
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ı
- Aynı görüntünün orijinal, parlak ve koyu sürümlerini yan yana gösterin.
- Dairesel bir maske ile yalnızca görüntünün merkezini görünür bırakın.
- Gürültülü bir görüntüde ortalama, Gaussian ve medyan filtreyi karşılaştırın.
- Bir görüntüye Otsu eşikleme uygulayıp morfolojik açma ile küçük gürültüleri temizleyin.
- Kameradan alınan karelerde kontur alanı belirli bir sınırdan büyük nesnelerin çevresine dikdörtgen çizin.