Próbuję dopasować histogram za pomocą Pythona, aby poprawić proces mozaikowania wielu nakładających się rastrów. Opieram swój kod na tym, który znajduje się w:
http://www.idlcoyote.com/ip_tips/histomatch.html
Do tej pory udało mi się przyciąć nakładający się obszar dwóch sąsiednich rastrów i spłaszczyć tablicę.
więc mam dwie tablice jednowymiarowe o tej samej długości.
Następnie napisałem następujący kod na podstawie tego, który znaleziono na powyższej stronie internetowej. W pokazanym kodzie podstawiłem dwa bardzo małe zestawy danych dla obrazów gd i bd.
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
bins = range(0,100, 10)
gd_hist = [1,2,3,4,5,4,3,2,1]
bd_hist = [2,4,6,8,10,8,6,4,2]
nPixels = len(gd_hist)
# here we are creating the cumulative distribution frequency for the bad image
cdf_bd = []
for k in range(0, len(bins)-1):
b = sum(bd_hist[:k])
cdf_bd.append(float(b)/nPixels)
# here we are creating the cumulative distribution frequency for the good image
cdf_gd = []
for l in range(0, len(bins)-1):
g = sum(gd_hist[:l])
cdf_gd.append(float(g)/nPixels)
# we plot a histogram of the number of
plt.plot(bins[1:], gd_hist, 'g')
plt.plot(bins[1:], bd_hist, 'r--')
plt.show()
# we plot the cumulative distribution frequencies of both images
plt.plot(bins[1:], cdf_gd, 'g')
plt.plot(bins[1:], cdf_bd, 'r--')
plt.show()
z = []
# loop through the bins
for m in range(0, len(bins)-1):
p = [cdf_bd.index(b) for b in cdf_bd if b < cdf_gd[m]]
if len(p) == 0:
z.append(0)
else:
# if p is not empty, find the last value in the list p
lastval = p[len(p)-1]
# find the bin value at index 'lastval'
z.append(bins[lastval])
plt.plot(bins[1:], z, 'g')
plt.show()
# look into the 'bounds_error'
fi = interp1d(bins[1:], z, bounds_error=False, kind='cubic')
plt.plot(bins[1:], gd_hist, 'g')
plt.show
plt.plot(bins[1:], fi(bd_hist), 'r--')
plt.show()
Mój program z powodzeniem drukuje histogramy i skumulowane rozkłady częstotliwości ... i pomyślałem, że miałem część, aby uzyskać poprawną funkcję transformacji „z” .... ale potem, gdy używam funkcji dystrybucji „fi” na „bd_hist” aby spróbować dopasować go do zestawu danych gd, wszystko ma kształt gruszki.
Nie jestem matematykiem i jest bardzo prawdopodobne, że przeoczyłem coś dość oczywistego.
cdf_bd = np.cumsum(bd_hist) / float(np.sum(bd_hist))
Odpowiedzi:
Chociaż nie mogę komentować sugerowanej implementacji, możesz sprawdzić istniejącą implementację dopasowania histogramu wykonaną dla GRASS GIS 7 (tutaj dodatek):
https://trac.osgeo.org/grass/browser/grass-addons/grass7/imagery/i.histo.match
Aby zapoznać się z instrukcją i przykładem, patrz
http://grass.osgeo.org/grass70/manuals/addons/i.histo.match.html
Kod jest opublikowany na licencji GPL2 +.
źródło
Jak dzika krówka; Nie jestem pewien, czy potrzebujesz pliku PDF, jeśli masz dane zliczania w kategoriach ...
Czy możesz przekonwertować liczby każdej wartości dla każdego innego histogramu na wartości XY, a następnie użyć jakiegoś wskaźnika regresji, aby sprawdzić to dopasowanie? To znaczy, dla dwóch idealnie identycznych histogramów, analiza korelacji zapewniłaby, a R wyniósłoby 1,0.
źródło
niektóre przykładowe dane byłyby fajne, ponieważ mogą się różnić od sat do sat. oto jeden prosty skrypt, który napisałem, próbując wyrównać histogramy:
https://github.com/rupestre-campos/histogram_equalize
Może uda ci się uzyskać wgląd.
Oblicza również format cdf tak jak ty, ale jak próbowałem, oszaleje, jeśli wyliczysz band-per-band, więc wziąłeś pod uwagę cały raster.
Wygląda na to, że tracisz równowagę odniesienia kolorów i profil spektralny. Trzeba też nie liczyć żadnych pikseli danych, trzeba je następnie usunąć z całkowitej liczby pikseli obrazu, aby poprawnie obliczyć pdf.
Po kilku testach spodobały mi się wyniki wizualne z wykorzystaniem całego podejścia rastrowego do 3-4 pasm Landsat8 i konwersji z 16-bitowego na 8-bitowy zakres 0-255.
źródło