· Hakan Çelik · OpenCV / İleri Konular · 4 dk okuma
Histogram Geri Projeksiyonu

OpenCV Serisi 26/64
- 1. Boya Fırçası Olarak Fare
- 2. Canny Kenar Algılama
- 3. Görüntü Geçişleri
- 4. Görüntü Piramitleri
- 5. Görüntülerde Aritmetik İşlemler
- 6. Görüntülerle İlgili Temel İşlemler
- 7. Görüntünün Geometrik Dönüşümleri
- 8. Görüntüyü Yumuşatma - ( Smoothing Images )
- 9. Histogramlar
- 10. Konturler ( Contours )
- 11. Morfolojik Dönüşümler
- 12. Opencv Nedir Ve Kurulumu
- 13. Opencv Resim Işlemleri
- 14. Opencv Video Işlemleri
- 15. Opencv'de Çizim Fonksiyonları
- 16. Performans Ölçüm Ve Geliştirme Teknikleri
- 17. Renk Alanlarını Değiştirme
- 18. Renk Paleti Olarak Parça Çubuğu ( Trackbar )
- 19. Resim Eşikleme
- 20. Şablon Eşleştirme
- 21. Hough Doğru Dönüşümü
- 22. Hough Daire Dönüşümü
- 23. Fourier Dönüşümü
- 24. Histogram Eşitleme
- 25. 2B Histogramlar
- 26. Histogram Geri Projeksiyonu
- 27. Kontur Özellikleri
- 28. Kontur Nitelikleri
- 29. Konturlerle Daha Fazla İşlev
- 30. Kontur Hiyerarşisi
- 31. GrabCut ile Etkileşimli Ön Plan Çıkarma
- 32. Watershed Algoritması ile Görüntü Segmentasyonu
- 33. Özellikleri Anlamak
- 34. Harris Köşe Tespiti
- 35. Shi-Tomasi Köşe Dedektörü ve İzlenecek İyi Özellikler
- 36. SIFT'e Giriş (Ölçek Değişmez Özellik Dönüşümü)
- 37. SURF'e Giriş (Hızlandırılmış Sağlam Özellikler)
- 38. Köşe Tespiti için FAST Algoritması
- 39. BRIEF — İkili Sağlam Bağımsız Temel Özellikler
- 40. ORB (Yönlü FAST ve Döndürülmüş BRIEF)
- 41. Özellik Eşleştirme
- 42. Özellik Eşleştirme + Nesneleri Bulmak için Homografi
- 43. Meanshift ve Camshift ile Nesne Takibi
- 44. Optik Akış
- 45. Arka Plan Çıkarma
- 46. Kamera Kalibrasyonu
- 47. Poz Tahmini
- 48. Epipolar Geometri
- 49. Stereo Görüntülerden Derinlik Haritası
- 50. k-En Yakın Komşuyu Anlamak
- 51. kNN ile El Yazısı OCR
- 52. SVM'yi Anlamak
- 53. SVM ile El Yazısı OCR
- 54. K-Ortalamalar Kümeleme'yi Anlamak
- 55. OpenCV'de K-Ortalamalar Kümeleme
- 56. Görüntü Gürültü Giderme
- 57. Görüntü Onarımı (Inpainting)
- 58. Yüksek Dinamik Aralık (HDR) Görüntüleme
- 59. Haar Cascade ile Yüz Tespiti
- 60. pip ile OpenCV Kurulumu
- 61. Ubuntu'da OpenCV-Python Kurulumu
- 62. Fedora'da OpenCV-Python Kurulumu
- 63. Windows'ta OpenCV-Python Kurulumu
- 64. OpenCV-Python Bağlayıcıları Nasıl Çalışır?
Histogram Geri Projeksiyonu
Hedefler
Bu bölümde öğrenecekleriniz:
- Histogram geri projeksiyonu hakkında bilgi edinmek
Teori
Histogram geri projeksiyonu, Michael J. Swain ve Dana H. Ballard tarafından “Indexing via color histograms” (Renk Histogramları Aracılığıyla İndeksleme) adlı makalelerinde önerilmiştir.
Basit bir anlatımla ne işe yarar? Görüntü segmentasyonu veya bir görüntüdeki ilgi alanındaki nesneleri bulmak için kullanılır. Kısaca, girdi görüntümüzle aynı boyutta (ancak tek kanallı) bir görüntü oluşturur; burada her piksel, o pikselin nesnemize ait olma olasılığına karşılık gelir. Daha da basit bir ifadeyle çıktı görüntüsü, ilgi alanındaki nesneyi kalan kısmın dışında daha beyaz olarak gösterir. Histogram Geri Projeksiyonu; CamShift algoritması gibi algoritmalarda kullanılır.
Nasıl yapılır? İlgi alanındaki nesneyi içeren bir görüntünün histogramını oluşturursunuz (bizim durumumuzda zemin — oyuncu ve diğer şeyler hariç). Nesne, daha iyi sonuçlar için görüntüyü mümkün olduğunca doldurmalıdır. Gri tonlamalı histogram yerine renk histogramı tercih edilir, çünkü nesnenin rengi, gri tonlama yoğunluğuna kıyasla nesneyi tanımlamak için daha iyi bir yoldur. Ardından bu histogramı, nesneyi bulmamız gereken test görüntüsü üzerinde “geri projesyon” yaparız; yani her pikselin zemine ait olma olasılığını hesaplar ve gösteririz.
NumPy ile Algoritma
- Bulmak istediğimiz nesnenin (
M) ve içinde arama yapacağımız görüntünün (I) renk histogramlarını hesaplaın:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# roi: bulmamız gereken nesne veya nesne bölgesi
roi = cv.imread('rose_red.png')
assert roi is not None, "Dosya okunamadı, os.path.exists() ile kontrol edin"
hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
# target: içinde arama yaptığımız görüntü
target = cv.imread('rose.png')
assert target is not None, "Dosya okunamadı, os.path.exists() ile kontrol edin"
hsvt = cv.cvtColor(target, cv.COLOR_BGR2HSV)
# calcHist kullanarak histogramları bul
M = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
I = cv.calcHist([hsvt], [0, 1], None, [180, 256], [0, 180, 0, 256])R = M / Ioranını bulun. Ardından R’yi geri projesyon yapın; yani R’yi palet olarak kullanın ve her pikseli, hedef olma olasılığı ile yeni bir görüntü oluşturun. YaniB(x,y) = R[h(x,y), s(x,y)], ardındanB(x,y) = min[B(x,y), 1]koşulunu uygulayın:
R = M / (I + 1e-5) # Sıfıra bölmeyi önlemek için küçük bir değer ekle
h, s, v = cv.split(hsvt)
B = R[h.ravel(), s.ravel()]
B = np.minimum(B, 1)
B = B.reshape(hsvt.shape[:2])- Daire disk çekirdeğiyle konvolüsyon uygulayın (
B = D * B):
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
cv.filter2D(B, -1, disc, B)
B = np.uint8(B)
cv.normalize(B, B, 0, 255, cv.NORM_MINMAX)- Şimdi maksimum yoğunluğun konumu bize nesnenin konumunu verir. Görüntüde bir bölge bekliyorsak uygun bir değer için eşikleme iyi bir sonuç verir:
ret, thresh = cv.threshold(B, 50, 255, 0)OpenCV ile Geri Projeksiyon
OpenCV, cv2.calcBackProject() adında yerleşik bir fonksiyon sağlar. Parametreleri cv2.calcHist() fonksiyonuyla neredeyse aynıdır. Parametrelerinden biri, bulmamız gereken nesnenin histogramıdır ve geri projeksiyon fonksiyonuna aktarmadan önce normalize edilmesi gerekir. Olasılık görüntüsünü döndürür. Ardından görüntüyü bir disk çekirdeğiyle konvolüsyon yapıyoruz ve eşikleme uyguluyoruz:
import numpy as np
import cv2 as cv
roi = cv.imread('rose_red.png')
assert roi is not None, "Dosya okunamadı, os.path.exists() ile kontrol edin"
hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
target = cv.imread('rose.png')
assert target is not None, "Dosya okunamadı, os.path.exists() ile kontrol edin"
hsvt = cv.cvtColor(target, cv.COLOR_BGR2HSV)
# Nesne histogramını hesapla
roihist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
# Histogramı normalize et ve geri projeksiyon uygula
cv.normalize(roihist, roihist, 0, 255, cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt], [0, 1], roihist, [0, 180, 0, 256], 1)
# Daire diskle konvolüsyon uygula
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
cv.filter2D(dst, -1, disc, dst)
# Eşikle ve ikili AND uygula
ret, thresh = cv.threshold(dst, 50, 255, 0)
thresh = cv.merge((thresh, thresh, thresh))
res = cv.bitwise_and(target, thresh)
res = np.vstack((target, thresh, res))
cv.imwrite('res.jpg', res)Aşağıda üzerinde çalıştığım bir örnek yer almaktadır. Mavi dikdörtgenin içindeki bölgeyi örnek nesne olarak kullandım ve tam zemini çıkarmak istedim:

Ek Kaynaklar
- “Indexing via color histograms”, Swain, Michael J., Third International Conference on Computer Vision, 1990.
Hakan Çelik


