Dopasowywanie histogramów przy użyciu Pythona w celu usprawnienia procesu mozaikowania wielu nakładających się rastrów?

11

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.

Becky
źródło
Nie wiem wiele o dopasowywaniu histogramów, ale czy twoje CDF muszą sumować się do 1 (z definicji)? cdf_bd = np.cumsum(bd_hist) / float(np.sum(bd_hist))
Jeff G

Odpowiedzi:

1

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.

Mox
źródło
0

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.

ckc
źródło