I'm working in a laboratory and we often make time lapse series (image every hour) of stem cells. The current idea is to put all frames together and make a video showing this growing cells (similar to this youtube video). Which could done simple and cool using OpenCV + Python.
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()
But we have the problem, that all images vary a little bit in brightness, so we get some flickering in our output video.
I'm not allowed to upload the videos but here are some simple examples generated with gimp to visualize the problem:
That's the video I get from the frames
and that's my desired video (it would be also great to minimize the flickering instead of removing it completely)
Is there a way to adjust the histogram or brightness over all images (or maybe between 2 images) to remove those flickering using OpenCV?
Thanks for every idea or hint!
Edit: The gif sequence produced by Andrew's idea (Answer below)
If your data is in a 3D array, you shouldn't need to loop over it to do this. With 5 images of, say 256 x 256, you should be able to construct an array that is arr.shape == (256, 256, 5)
. My initial comment was a little off I think, but the below example should do it.
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: I used this page to iron out some kinks with addressing the 3D array