Używam numpy i scipy do przetwarzania wielu zdjęć wykonanych aparatem CCD. Obrazy te mają wiele gorących (i martwych) pikseli o bardzo dużych (lub małych) wartościach. Zakłóca to inne przetwarzanie obrazu, dlatego należy je usunąć. Niestety, chociaż kilka pikseli utknęło na 0 lub 255 i zawsze mają tę samą wartość na wszystkich obrazach, istnieją pewne piksele, które tymczasowo utknęły w innych wartościach przez okres kilku minut (rozpiętość danych wiele godzin).Automatyczne usuwanie gorących/martwych pikseli z obrazu w pytonie
Zastanawiam się, czy istnieje metoda identyfikacji (i usuwania) gorących pikseli już zaimplementowanych w pythonie. Jeśli nie, zastanawiam się, jaka byłaby to skuteczna metoda. Gorące/martwe piksele są stosunkowo łatwe do zidentyfikowania przez porównanie ich z sąsiednimi pikselami. Widziałem, jak napisałem pętlę, która patrzy na każdy piksel, porównując jej wartość z 8 najbliższymi sąsiadami. Lub, wydaje się, że lepiej jest użyć jakiegoś splotu, aby uzyskać gładszy obraz, a następnie odjąć go od obrazu zawierającego gorące piksele, dzięki czemu łatwiej je zidentyfikować.
Próbowałem tej "metody zamazywania" w kodzie poniżej i działa dobrze, ale wątpię, że jest to najszybszy. Ponadto pojawia się pomyłka na krawędzi obrazu (prawdopodobnie od tego, że funkcja gaussian_filter przyjmuje splot, a splot staje się dziwny blisko krawędzi). Czy istnieje lepszy sposób na zrobienie tego?
Przykładowy kod:
import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage
plt.figure(figsize=(8,4))
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
#make a sample image
x = np.linspace(-5,5,200)
X,Y = np.meshgrid(x,x)
Z = 255*np.cos(np.sqrt(x**2 + Y**2))**2
for i in range(0,11):
#Add some hot pixels
Z[np.random.randint(low=0,high=199),np.random.randint(low=0,high=199)]= np.random.randint(low=200,high=255)
#and dead pixels
Z[np.random.randint(low=0,high=199),np.random.randint(low=0,high=199)]= np.random.randint(low=0,high=10)
#Then plot it
ax1.set_title('Raw data with hot pixels')
ax1.imshow(Z,interpolation='nearest',origin='lower')
#Now we try to find the hot pixels
blurred_Z = scipy.ndimage.gaussian_filter(Z, sigma=2)
difference = Z - blurred_Z
ax2.set_title('Difference with hot pixels identified')
ax2.imshow(difference,interpolation='nearest',origin='lower')
threshold = 15
hot_pixels = np.nonzero((difference>threshold) | (difference<-threshold))
#Don't include the hot pixels that we found near the edge:
count = 0
for y,x in zip(hot_pixels[0],hot_pixels[1]):
if (x != 0) and (x != 199) and (y != 0) and (y != 199):
ax2.plot(x,y,'ro')
count += 1
print 'Detected %i hot/dead pixels out of 20.'%count
ax2.set_xlim(0,200); ax2.set_ylim(0,200)
plt.show()
a wyjście:
Spróbuj bardziej prosty przypadek: zrobić kolejne zdjęcie z filtrowaniem środkowej (na przykład przez 3x3 deseń) i obliczyć wartość bezwzględną differense między Twój obraz i filtrowany obraz. Zastąp piksele oryginalnego obrazu dużymi wartościami tej różnicy (powiedzmy 100) przez przefiltrowane wartości. Wartość progu, którą można uzyskać automatycznie, według statystyk różnic. –
@Eddy_Em, dziękuję za sugestię filtra median - to wydaje się lepszą metodą niż filtr Gaussa. Poza tym podoba mi się pomysł ustawienia progu za pomocą statystyk z tablicy różnic. Próbowałem przyjąć odchylenie standardowe i wydawało się, że działa dobrze. (Ustawiłem próg na 5-krotność odchylenia standardowego.) Jednak nie jestem pewien co do sugestii dodania wielokrotności tablicy różnic do tablicy obrazów. Co to robi? – DanHickstein
O, nie: Chodzi mi o to, że piksele są wyszukiwane w tablicy różnic przez pewną wartość progową. –