8. ünite / 12
Renk segmentasyonu ve takip: HSV maskesi, leke, iz
inRange ile HSV aralığı, kırmızının sarmalı tonu, maske temizliği, en büyük leke, ağırlık merkezi ve kamerada takip.
Bu ünitenin sonunda
- Bir rengi HSV aralığı olarak tanımlayıp maske çıkarmak
- Kırmızı gibi tonun iki ucunda duran renkleri iki maskeyle birleştirmek
- Maskeyi morfolojiyle temizleyip en büyük lekeyi bulmak
- Lekenin merkezini kareden kareye izleyip yol çizmek
Ders notları
Bir nesneyi rengiyle ayırmak, bilgisayarlı görünün en eski ve hâlâ en kullanışlı yöntemlerinden biridir: top takip eden robotlar, renkli işaretler, meyve ayıklama. Anahtar, BGR yerine HSV çalışmaktır.
H rengi, S rengin ne kadar "dolu" olduğunu, V parlaklığı verir. Gölge V'yi düşürür ama H'yi pek değiştirmez; bu yüzden geniş bir V aralığı ve dar bir H aralığı ışık değişimine dayanıklıdır. Düşük S'li pikseller (gri, beyaz, siyah) için ton anlamsızdır; alt S sınırı onları dışarıda tutar.
Kırmızı özel
OpenCV'de ton 0–179 arasında bir çemberdir ve kırmızı iki uçtadır (0–10 ve 170–179). İki maske alınıp cv2.bitwise_or ile birleştirilir.
Maskeden konuma
- Maskeyi açma ve kapama ile temizle.
- Konturları bul, en büyüğünü seç (ya da
connectedComponentsWithStats). - Momentlerden merkezi al; son N merkezi bir kuyrukta tut ve çiz.
Kamerada bu döngü saniyede 30 kez döner. Leke kaybolursa son konumu bir süre korumak titremeyi azaltır.
Oyun alanı
HSV renk segmentasyonu ve takip
Renk tonu (H), doygunluk (S) ve değer (V) aralığı seç: maske beyaz, en büyük leke kutulanır, merkezinin izi çizilir. Örnek sahnede top hareket eder; ışık değişse de H aralığı BGR'den çok daha kararlıdır.
Kendin dene
Hareketli top sahnesinde H aralığını 5–22, S ≥ 120 yap: top kutulanıyor mu? Işığı 0,5'e indir: maske ne kadar küçüldü? V alt sınırını düşürerek takibi geri getir. Sonra H aralığını 100–130 yap: hangi nesneyi takip etmeye başladı? Kamerayı aç ve elindeki renkli bir nesne için aralığı bul; aralığı not edip Python koduna yaz.
Kod
import cv2
import numpy as np
img = cv2.imread('girdi.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lo = np.array([5, 120, 80]) # turuncu: H 5..20, doygun ve parlak
hi = np.array([20, 255, 255])
mask = cv2.inRange(hsv, lo, hi)
# kırmızı H = 0 çevresinde: iki aralık gerekir
red = cv2.inRange(hsv, (0, 120, 80), (8, 255, 255)) | cv2.inRange(hsv, (170, 120, 80), (179, 255, 255))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8))
print('maske oranı:', round((mask > 0).mean(), 4), 'kırmızı oranı:', round((red > 0).mean(), 4))
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
out = img.copy()
if contours:
big = max(contours, key=cv2.contourArea) # en büyük leke = hedef
(x, y), r = cv2.minEnclosingCircle(big)
print('hedef: x=%d y=%d r=%d' % (x, y, r))
cv2.circle(out, (int(x), int(y)), int(r), (0, 255, 0), 2)
cv2.imwrite('cikti.png', out)import cv2
import numpy as np
from collections import deque
cap = cv2.VideoCapture(0) # kendi bilgisayarında çalıştır
trail = deque(maxlen=40) # son 40 merkez
lo, hi = np.array([5, 120, 80]), np.array([20, 255, 255])
while True:
ok, frame = cap.read()
if not ok:
break
hsv = cv2.cvtColor(cv2.GaussianBlur(frame, (11, 11), 0), cv2.COLOR_BGR2HSV)
mask = cv2.erode(cv2.inRange(hsv, lo, hi), None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if cnts:
M = cv2.moments(max(cnts, key=cv2.contourArea))
if M['m00'] > 300: # çok küçükse hedef yok say
trail.appendleft((int(M['m10'] / M['m00']), int(M['m01'] / M['m00'])))
for i in range(1, len(trail)):
cv2.line(frame, trail[i - 1], trail[i], (0, 0, 255), max(1, 6 - i // 8))
cv2.imshow('track', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): # q ile çık
break
cap.release()
cv2.destroyAllWindows()Sık yapılan hatalar
- Renk aralığını BGR'de tanımlamak: ışık değişince üç kanal birlikte kayar, aralık tutmaz.
- Kırmızı için tek H aralığı (örneğin 170–10) yazmak: inRange sarmalı aralığı anlamaz; iki maske gerekir.
- S alt sınırını 0 bırakmak: beyaz ve gri pikseller rastgele tonlarla maskeye girer.
- Kameranın otomatik beyaz dengesini ve pozlamasını unutmak: renkler kendiliğinden kayar. Mümkünse kilitle.
Yazılım mühendisliği bağlantısı
Renk aralıkları ortama bağlıdır; aynı kod farklı ışıkta farklı sonuç verir. Bunu bir kalibrasyon adımı ile yazılımın parçası yap.
- Aralıkları bir JSON dosyasında sakla, kalibrasyon aracıyla (bu oyun alanı gibi) güncelle.
- Takip döngüsünde kare başına süreyi ölç ve kaydet; gecikme bütçesini (örneğin 33 ms) aşan kareleri say.
Kendini sına
OpenCV'de saf kırmızının tonu (H) hangi bölgelerdedir?
Gölgede kalan turuncu bir topu yakalamak için HSV aralığında ne gevşetilmeli?
S alt sınırının amacı nedir?
Maskede birden çok leke varken hedef nesneyi seçmenin en basit yolu hangisidir?