Ich benutze numpy und scipy, um eine Anzahl von Bildern zu verarbeiten, die mit einer CCD-Kamera aufgenommen wurden. Diese Bilder haben eine Anzahl von heißen (und toten) Pixeln mit sehr großen (oder kleinen) Werten. Diese stören andere Bildverarbeitung, so dass sie entfernt werden müssen. Obwohl ein paar der Pixel auf 0 oder 255 stecken und in allen Bildern immer den gleichen Wert haben, gibt es leider einige Pixel, die vorübergehend für einige Minuten auf anderen Werten stecken bleiben (die Datenspannen) viele Stunden).Automatisch heiße/tote Pixel von einem Bild in Python entfernen
Ich frage mich, ob es eine Methode zum Identifizieren (und Entfernen) der heißen Pixel gibt, die bereits in Python implementiert sind. Wenn nicht, frage ich mich, was wäre eine effiziente Methode dafür. Die heißen/toten Pixel sind relativ leicht zu identifizieren, indem sie mit benachbarten Pixeln verglichen werden. Ich konnte sehen, wie man eine Schleife schreibt, die jedes Pixel betrachtet und seinen Wert mit dem seiner 8 nächsten Nachbarn vergleicht. Oder es scheint netter zu sein, eine Art von Faltung zu verwenden, um ein glatteres Bild zu erzeugen, und dieses dann von dem Bild mit den heißen Pixeln zu subtrahieren, wodurch sie leichter zu identifizieren sind.
Ich habe diese "Unschärfe-Methode" im folgenden Code ausprobiert, und es funktioniert in Ordnung, aber ich bezweifle, dass es am schnellsten ist. Außerdem wird es am Rand des Bildes verwirrt (wahrscheinlich, da die Gaußsche_Filter-Funktion eine Faltung nimmt und die Faltung in der Nähe der Kante merkwürdig wird). Also, gibt es einen besseren Weg, dies zu tun?
Beispielcode:
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()
Und die Ausgabe:
einen einfacheren Fall Versuchen: ein weiteres Bild mit Medianfilterung machen (zum Beispiel durch ein Muster 3x3) und berechnet absoluten Wert von differense zwischen Ihr Bild und gefiltertes Bild. Ersetze Pixel des Originalbildes mit großen Werten dieser Differenz (z. B. 100) durch gefilterte Werte. Der Wert des Grenzwerts kann automatisch durch Differenzstatistiken ermittelt werden. –
@Eddy_Em, vielen Dank für den Median-Filter - das scheint eine bessere Methode als der Gauss-Filter. Außerdem gefällt mir die Idee, den Schwellenwert unter Verwendung der Statistik des Differenzarrays zu setzen. Ich habe versucht, die Standardabweichung zu nehmen, und das schien gut zu funktionieren. (Ich setze den Schwellenwert auf das 5-fache der Standardabweichung.) Ich bin jedoch verwirrt über Ihren Vorschlag, ein Vielfaches des Differenz-Arrays zum Bild-Array hinzuzufügen. Was macht das? – DanHickstein
Oh, nein: Ich meine nur, dass Sie Pixel suchen, um im Differenz-Array um einen Schwellenwert zu bereinigen. –