Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make video from an updating numpy array in Python

I have a loop that modifies elements of a 2D numpy array water_depth with type float. The array contains water depth for each pixel and the range is usually between 0 to 1.5m. I would like to make a video out of this changing array: each iteration can be a frame in the video. I only found this link explaining a similar question and suggests using cv2 VideoWriter. The problem is that my numpy array is a float, not integer. Does this mean that I need to do some sort of pre-processing on my array in each iteration?

import numpy as np

water_depth = np.zeros((500,700), dtype=float)

for i in range(1000):
    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
like image 591
Behzad Jamali Avatar asked Aug 19 '18 05:08

Behzad Jamali


People also ask

How do I export from NumPy?

You can save your NumPy arrays to CSV files using the savetxt() function. This function takes a filename and array as arguments and saves the array into CSV format. You must also specify the delimiter; this is the character used to separate each variable in the file, most commonly a comma.

Can you create a Pandas series from NumPy array?

A pandas Series is very similar to a 1-dimensional NumPy array, and we can create a pandas Series by using a NumPy array. To do this we need to import the NumPy module, as it is a prerequisite for the pandas package no need to install it separately. It is automatically installed by our package installer.


1 Answers

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.

like image 160
alkasm Avatar answered Nov 14 '22 23:11

alkasm