2016-09-07 9 views
0

Ich arbeite in einem Labor und wir machen oft Zeitreihen (Bild jede Stunde) von Stammzellen. Die aktuelle Idee ist, alle Frames zusammen zu stellen und ein Video zu machen, das diese wachsenden Zellen zeigt (ähnlich dieser youtube video). Was mit OpenCV + Python einfach und cool gemacht werden könnte.Helligkeit/Histogramm Normalisierung für Zeitraffer Bilder

import numpy as np 
import os 
import cv2 

fourcc = cv2.VideoWriter_fourcc(*'XVID') 
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480)) 

timelapse_folder = '../myTimeLapse/' 

for file in os.listdir(timelapse_folder): 
    frame = cv2.imread(timelapse_folder+file, 0) 
    out.write(frame) 

out.release() 

Aber wir haben das Problem, dass alle Bilder ein wenig in der Helligkeit variieren, so dass wir einige Flackern in unserer Video-Ausgang erhalten.

ich nicht erlaubt bin die Videos hochladen, aber hier sind einige einfache Beispiele mit Gimp erzeugt, um das Problem zu visualisieren:

, dass das Video, das ich aus den Rahmen zu bekommen ist

enter image description here

und das ist mein gewünschtes Video (es wäre auch toll das Flackern zu minimieren statt es komplett zu entfernen)

enter image description here

Gibt es eine Möglichkeit, das Histogramm oder die Helligkeit über alle Bilder (oder vielleicht zwischen zwei Bildern) anzupassen, um das Flackern mit OpenCV zu entfernen?

Danke für jede Idee oder Hinweis!

Edit: Die Sequenz gif von Andrew Idee produziert (Antwort unten)

enter image description here

+1

der Annahme, dass alle Bilder 2D-Arrays von Schwimmern/Ints sind, dann könnten Sie ein 3D-Array aller Bilder konstruieren , und normalisieren Sie dann gegen den hellsten '(max (np.average (arr, axis = 2)))'. Dann trittest du durch und schreibst zu dem Video? – Andrew

+0

Hey Ich versuchte 'max_avg = np.max (np.average (Bilder, Achse = 2))' und dann in einer for-Schleife über jedes Bild 'frame = (frame/max_avg) * 255 ', aber es entfernt nicht das Flackern . Oder meinst du eine andere Art der Normalisierung? – Fabian

Antwort

1

Wenn sich Ihre Daten in einem 3D-Array befinden, sollten Sie sie nicht in der Schleife durchlaufen. Mit 5 Bildern von beispielsweise 256 x 256 sollten Sie in der Lage sein, ein Array zu konstruieren, das arr.shape == (256, 256, 5) ist. Mein anfänglicher Kommentar war ein wenig aus, denke ich, aber das folgende Beispiel sollte es tun.

target_array = [] 

for file in os.listdir(timelapse_folder): 
    frame = cv2.imread(timelapse_folder+file, 0) 
    if target_array:#Not entirely happy with this, but it should work 
     target_array = np.dstack((target_array, frame)) 
    elif not target_array: 
     target_array = np.asarray(frame) 
target_array = target_array/np.max(target_array) 
#target_array *= 255 #If you want an intensity value with a more common range here 
for idx in xrange(target_array.shape[2]): 
    out.write(target_array[:, :, idx]) 

EDIT: habe ich this page einige Knicke auszubügeln mit dem Array 3D-Adressierung

+0

Wenn Sie Probleme mit Flackern haben, könnten Sie eine interpolierte Scheibe zwischen jedem Ihrer Datenscheiben hinzufügen was in der Mitte zwischen den beiden Bildern liegt, würde den scheinbaren Flimmereffekt reduzieren. Nicht sicher, ob eine Glättungsfunktion funktionieren würde, abhängig davon, wie viele Frames vorhanden sind. – Andrew

+0

Hey, ich habe versucht, eine solche Normalisierung zwischen den Bildern zu machen und Übergänge hinzuzufügen (interpoliertes Stück) und es sieht jetzt "Ok" aus. Die Normalisierung beseitigt das Flimmern ein wenig, aber ich habe ein Problem mit dem interpolierten Slice, weil die Zellen manchmal nicht nahe genug sind, so dass es wirklich verschwommen aussieht. Ich werde ein GIF mit der Idee Ihrer Antwort auf meine Frage hinzufügen, aber ich werde mit akzeptieren warten - vielleicht hat jemand eine andere Idee. Ansonsten werde ich in ein paar Tagen annehmen. Danke vielmals. – Fabian

+0

Wenn Glätte die Priorität ist, können Sie immer mehrere interpolierte Slices hinzufügen, die während des Dstacks ausgeführt werden können, indem Sie die Anzahl der interpolierten Slices definieren und dann die Anzahl der Arrays erstellen. Dann können Sie wählen, ob Sie linear oder logarithmisch schreiten möchten (vielleicht würde eine Normalverteilung mit 11 Schichten eine optimale Glätte ergeben?). Offensichtlich werden Ihre realen Daten um 11: 1 oder mehr in der Überzahl sein, aber solange Sie gegenüber Wissenschaftlern, die es sehen, offen darüber sind, sehe ich kein Problem. – Andrew

0

Sind diese Bilder RGB oder Grauwerte? Ich würde nur eine Normalisierung in der Schleife durchführt, nachdem jedes Bild zu lesen:

frame = frame/np.max(frame) 

Bei Grauwerten jedes Bild dann Wert zwischen 0 und 1 haben sollte, aber je nachdem, wie Sie Ihre Bilder so aussehen wie Sie auch andere Normierungen könnten versuchen, , z.B unter Verwendung der np.median oder np.mean anstelle von np.max.

+0

Ich habe dies versucht, aber die Helligkeitsdifferenz zwischen allen Bildern bleibt bestehen. Ich denke, ich muss den Durchschnitt aller Bilder respektieren, wie Andrew in seinem Kommentar geschrieben hat, aber ich weiß nicht, wie ich den Durchschnittswert für jeden Frame auf den Durchschnitt aller Frames verschieben kann. Weißt du was ich meine? – Fabian

+0

Ich denke, ich bekomme dein Problem. Haben Sie eine Art von Objekten, die Sie in Ihrem Rahmen vom Hintergrund trennen können (z.Verwenden einer einfachen Schwelle)? Auf diese Weise können Sie versuchen, nur den Hintergrund aller Bilder anzupassen. Beispiel: Nehmen Sie den Mittelwert des Hintergrunds eines beliebigen Frames als Referenz und verschieben Sie alle anderen Frames so, dass die Mittelwerte ihrer Hintergründe mit der Referenz übereinstimmen. –

+0

Gibt es eine einfache numpy oder cv2 Methode, um diese Rahmenwerte zu verschieben? Die Zellen sind nicht komplett weiß, also denke ich, wenn ich nur den Hintergrund justiere, bekomme ich flackernde Zellen (Vordergrund). In späteren Bildern mit höherer Konfluenz (viele Zellen) kann ich den Hintergrund nicht trennen, da nur flackernde Zellen wirklich dicht beieinander liegen. – Fabian