For a visually pleasing time lapse, there are many things you can try. I'd additionally recommend a temporal blur (motion blur) to even out local lighting changes and fast-moving objects. That also reproduces the impression of a normal video, which always has some non-zero exposure time, i.e. motion blur.
This code approximately works in a linear space, tries to balance colors (color temperature) and brightness. All this isn't physically accurate but close to what's doable with the information given. One glaring defect: I'm not "tone-mapping" here, so anything that's too bright is simply clipped to white.
The "Gray world" is just one possible way to estimate color balance. There are a bunch more, variously complex. Your original pictures may already be color-balanced okay...
def gamma_decompress(im):
return np.power(im, 2.2)
def gamma_compress(im):
return np.power(im, 1/2.2)
def measure_gray_world(im):
avg = np.mean(im, axis=(0, 1))
return avg
for im in images:
im = gamma_decompress(im / 255)
avg = measure_gray_world(im) # or im[height // 3:]
im = im / avg * 0.3 # move mean down so picture isn't blown out
im = gamma_compress(im)
imshow(im)

You could also only respect certain areas of the picture for the color balance... say the lower two thirds, mostly ignoring the sky. That'll make the picture look colder because most of it is adjusted to be more neutral, and the sky gets to be very blue.
