1. ünite / 12
Görüntü bir sayı dizisidir: pikseller, kanallar, renk uzayları
Yükseklik × genişlik × kanal; uint8, BGR sırası, gri dönüşüm ve HSV. Dilimleme ve bölge (ROI).
Bu ünitenin sonunda
- Bir görüntünün NumPy dizisi olarak şeklini, veri tipini ve eksen sırasını (satır, sütun) söylemek
- OpenCV'nin BGR sırasını ve bunun yol açtığı hataları tanımak
- Gri dönüşüm formülünü ve HSV'nin neden renk işlerinde kullanıldığını açıklamak
- Dilimleme ile bir bölgeyi (ROI) okumak ve değiştirmek
Ders notları
Bilgisayar için fotoğraf, ışık şiddetlerinden oluşan bir tablodur. OpenCV Python'da bu tablo bir NumPy dizisidir: renkli görüntünün şekli (yükseklik, genişlik, 3), veri tipi çoğunlukla uint8, yani her değer 0–255 arasında bir tam sayı. 640×480 bir kare 921 600 sayı demektir.
Satır önce, sütun sonra
img[y, x] önce satırı (dikey konum), sonra sütunu alır; çizim fonksiyonları ise noktayı (x, y) diye ister. Bu ikilik en sık yapılan hatadır. Dilim (img[50:100, 20:80]) bir görünümdür: kopyalamaz, değiştirirsen asıl görüntü de değişir. Bağımsız kopya için .copy().
BGR, gri ve HSV
OpenCV renkleri tarihsel nedenle B, G, R sırasında tutar; matplotlib ve tarayıcı R, G, B bekler. Gri dönüşüm gözün yeşile daha duyarlı olmasını hesaba katar:
HSV rengi ton (H), doygunluk (S) ve parlaklık (V) olarak ayırır. OpenCV'de H 0–179 aralığındadır (derecenin yarısı, uint8'e sığsın diye). Gölge düşünce B, G, R birlikte azalır ama H neredeyse aynı kalır: renkle nesne ayırmayı (8. ünite) bu kolaylaştırır.
Oyun alanı
Piksel ve kanal gezgini
Görüntü bir sayı dizisidir: yükseklik × genişlik × 3. Bir kanal seç (B, G, R, gri, H, S, V) ve görüntünün üstünde gez: imlecin altındaki pikselin BGR ve HSV değerleri sağda.
Kendin dene
Renkli şekiller sahnesinde kırmızı üçgenin üstüne gel: R yüksek, B ve G düşük mü? Kanalı "B" yap: mavi kare neden beyaz, kırmızı üçgen neden siyah görünüyor? Sonra "H" kanalına geç ve meyve tabağı sahnesini aç: gölgeli sağ yarıda V düşerken H'nin aynı kaldığını üç meyvede ölç.
Kod
import cv2
import numpy as np
img = cv2.imread('girdi.png') # BGR sırasında, uint8
h, w, ch = img.shape
print('şekil:', img.shape, 'dtype:', img.dtype)
b, g, r = img[h // 2, w // 2] # satır (y), sonra sütun (x)
print('orta piksel B,G,R =', b, g, r)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 0.299R + 0.587G + 0.114B
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # H: 0..179, S ve V: 0..255
B, G, R = cv2.split(img)
print('ortalama B/G/R:', B.mean().round(1), G.mean().round(1), R.mean().round(1))
print('ortalama ton (H):', hsv[..., 0].mean().round(1))
roi = img[h // 4: h // 2, w // 4: w // 2] # kesit kopya değil, görünümdür
out = img.copy()
out[h // 4: h // 2, w // 4: w // 2] = 255 - roi # yalnız bölgenin rengini ters çevir
cv2.rectangle(out, (w // 4, h // 4), (w // 2, h // 2), (0, 0, 255), 2)
cv2.imwrite('cikti.png', out)Sık yapılan hatalar
- img[x, y] yazmak: NumPy önce satırı (y) ister; dikdörtgen görüntülerde yanlış piksel ya da IndexError çıkar.
- BGR görüntüyü matplotlib'le göstermek: kırmızı ile mavi yer değiştirir. cv2.cvtColor(img, cv2.COLOR_BGR2RGB) gerekir.
- uint8 aritmetiğinde taşmayı unutmak: NumPy'da 250 + 10 = 4 olur; cv2.add doyurur (255).
- HSV ton aralığını 0–360 sanmak: OpenCV'de 0–179; kırmızı iki uçta (0 civarı ve 179 civarı) durur.
Yazılım mühendisliği bağlantısı
Görüntü işleme kodunda en pahalı hatalar sessiz olanlardır: yanlış kanal sırası programı çökertmez, yalnız yanlış sonuç verir. Bunu önlemenin yolu sözleşme yazmaktır.
- Her fonksiyonun başında girdiyi doğrula:
assert img.ndim == 3 and img.dtype == np.uint8. - Renk sırasını adla taşı (
bgr,rgb,graydeğişken adları ya da küçük bir veri sınıfı). - Bilinen bir pikselin değerini sınayan küçük birim testleri yaz: "saf kırmızı (0, 0, 255) BGR, HSV'de H = 0 verir".
Kendini sına
480 satır, 640 sütunlu renkli bir görüntünün NumPy şekli nedir?
cv2.imread ile okunan bir pikselde değerler [0, 0, 255]. Bu piksel hangi renktir?
Gölge düşen bir nesnede HSV'nin hangi bileşeni en az değişir?
roi = img[10:50, 10:50]; roi[:] = 0 çalıştırıldıktan sonra ne olur?