HİSTOGRAM EŞİTLEME
Piksel değerleri belirli bir aralıkta olan bir görüntüyü düşünün.Örneğin çok parlak bir görüntü tüm piksellerin yüksek değerlerle sınırlı kalmasına neden olur. Ancak iyi bir görüntü demek resmin tüm bölgelerinden piksellere sahip olmak demektir.Dolayısıyla histogramı başlangıç ve bitiş noktalarına dağıtmak zorunda kalabilirsiniz.İşte Histogram eşitleme işleminin yaptığı budur.Bu işlem normalde görüntünün kontrastını değiştirir.
Bu konuda ayrıntılı bilgiye buradan ulaşabilirsiniz.
Bir resimin histogram aralığını inceleyelim;
Giriş resmi:
Kod:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cv2.imshow('img',img)
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
Sonuç: import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cv2.imshow('img',img)
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
Resmin histogramına bakıldığı zaman pikseller daha parlak bir noktada toplanmıştır.Fakat tam bir spektruma ihtiyaç vardır.Bunun için parlak bölgenin giriş piksellerini tam bölgedeki çıktı piksellerine eşleyen bir dönüşüm fonksiyonuna ihtiyaç vardır.Histogram eşitleme işlemi bunu yapmaktadır.
İlk adım olarak minimum histogram değeri bulunur(0 hariç).Ardından histogram eşitleme işlemi uygulanır.
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
Bu işlemden sonra giriş piksel değerleri için çıktı piksel değeri hakkında bilgi veren bir arama tablosuna sahip olunur.
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
img2 = cdf[img]
Yukarıdaki Giriş resmi için histogram eşitleme işlemini uygulayalım;Kod:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
img2 = cdf[img]
cv2.imshow('img',img2)
plt.plot(cdf_normalized, color = 'b')
plt.hist(img2.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
Sonuç:import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
img2 = cdf[img]
cv2.imshow('img',img2)
plt.plot(cdf_normalized, color = 'b')
plt.hist(img2.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
Yeni resimin histogramına bakıldığı zaman pikseller düzgün bir şekilde dağılmış histogram eşitliği sağlanmış ve ideal bir görüntü elde edilmiştir.
Histogram eşitleme işlemi nesne bulmada resimlerdeki aranacak nesnenin parlaklık oranının bütün resimlerde aynı olmasını sağlar nesne tanımada önemli bir rol oynar.
Yukarıdaki kodda yapılan uzun işlemler sonucunda histogram eşitleme sağlanmıştır.Fakat OpenCV'de bu işlemi tek satırda yapan özel bi fonksiyon bulunmaktadır.Bu fonksiyon cv2.equalizeHist() fonksiyonudur.
Yine aynı giriş resmi için bu yöntemi uygulayalım:;
Kod:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
cv2.imwrite('res.png',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
Sonuç:import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
cv2.imwrite('res.png',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
CLAHE(Kontras Sınırlı Histogram Eşitlemesi)
Önceki histogram eşitlemeleri görüntünün genel kontrastını göze alır.Çoğu durumda bu iyi bir fikir değildir. Örnek olarak bir resimde anlatmak gerekirse;
Yukarıdaki resime önceki histogram eşitleme yöntemi uygulandığında yüzün daha çok kaybolduğu görülmektedir.Bunun nedeni ise histogramın belirli bir bölgeyle sınırlı kalmamasıdır.
Bu sorunu çözmek için CLAHE yöntemi kullanılır.Burada giriş resmi 8x8'lik bölgelere ayrılmıştır. Ardından herbir bölge önceki aşamalardaki gibi histogram eşitlemesine tabi tutulmuştur.Buradaki amaç her bir histogram eşitlemeyi küçük bir bölgede uygulamaktır. Fakat dezavantaj olarak resimdeki gürültü oranı artacaktır.Bunu önlemek için ise kontrast sınırlaması uygulanır. Herhangi bir bölgenin kontrast değeri sınırın üstündeyse bu pikseller histogram eşitlemesi uygulanmadan önce kesilir ve diğer bölgelere eşit olarak paylaştırılır.Eşitleme sonrasında ise bölgelerin çıkarılabilmesi için bilinear enterpolasyon uygulanır.
Yukarıdaki giriş resmini bu eşitlemeye sokar isek;
Kod:
import numpy as np
import cv2
img = cv2.imread('image.jpg',0)
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv2.imwrite('clahe_2.jpg',cl1)
cv2.waitKey(0)
cv2.destroyAllWindows()
Sonuç:import cv2
img = cv2.imread('image.jpg',0)
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv2.imwrite('clahe_2.jpg',cl1)
cv2.waitKey(0)
cv2.destroyAllWindows()
Sonuca bakıldığı zaman yüz heykeli detayları kaybedilmeden histogram eşitleme yapılmıştır.
Ders:21⬅ ➤Ders:23
0 yorum:
Yorum Gönder