Note that working with OpenCV for video I/O purposes can sometimes be tricky. The library isn't built around supporting these kinds of operations, they're just included as a nicety. Typically, OpenCV will be built off ffmpeg
support, and whether or not you have the same codecs to read/write videos as another person is somewhat arbitrary depending on your system. With that said, here's an example so you get the idea of exactly what preprocessing you might do:
import numpy as np
import cv2
# initialize water image
height = 500
width = 700
water_depth = np.zeros((height, width), dtype=float)
# initialize video writer
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
fps = 30
video_filename = 'output.avi'
out = cv2.VideoWriter(video_filename, fourcc, fps, (width, height))
# new frame after each addition of water
for i in range(10):
random_locations = np.random.random_integers(200,450, size=(200, 2))
for item in random_locations:
water_depth[item[0], item[1]] += 0.1
#add this array to the video
gray = cv2.normalize(water_depth, None, 255, 0, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
gray_3c = cv2.merge([gray, gray, gray])
out.write(gray_3c)
# close out the video writer
out.release()
Note that I changed the number of iterations to 10 instead of 1000 just to make sure it worked. Here normalize(..., 255, 0, ...)
scales your image so that the max value is 255 (white) and the min value is 0 (black). This means that when at first all your random points start dotting everything, they turn white. However once one point lands on top of another, that will be the brightest---twice as bright as all other points, so they'll immediately drop to be gray. If that's not what you want, you have to think if you'd have a maximum value that your image might be and assume that your images won't change brightness otherwise.
ffmpeg
).cv2.VideoWriter()
, then yes, you need to scale and convert your array.VideoWriter()
needs RGB images (not single-channel grayscale images like yourwater_depth
) and needs them to be 8-bit. You can scale them appropriately between 0 and 255 withcv2.normalize()
and then you can merge that into a three-channel image withcv2.merge()
.scipy.misc.toimage(water_depth, cmin=0.0, cmax=1.5).save('image\{0}.png'.format(i))
to save my array into image.scipy.misc.toimage
takes care of the required pre-processing by just indicating the min and max of arrays.ffmpeg
. It is C++ rather than Python, but it's only a single line.