Overlay directly on a movie using numpy and mencoder

So, this should be a comment on this topic , but it is obviously closed, so here it is. I played quite successfully with matplotlib and numpy and mencoder, as suggested here. Since then, I have adopted the Voki Codder buffer as a stdin solution , which greatly speeds up the whole process. The fact is that I could not find the documentation on the -format = "bgra" part of this command. This means that the bytes on the right and left are blue-green red alpha, on the right. They must be uint32 or something else. The problem is that I draw colormaps float, so I try to convert them to shades of gray, but I get a lot of weird patterns that make me firmly believe that I'm doing something wrong. I wrote this function to convert from float to uint32 within a range. But the result is not what I expected, am I doing something terribly stupid?

def grayscale(x, min, max): return np.uint32((x-min)/(max-min)*0xffffff) 
+6
source share
1 answer

I think you are confused about what uint32 represents. These are 4 stripes from uint8 integers.

If you have floating point data and want to represent it in grayscale, you do not want to rescale it to the full 32-bit range, you want to rescale it to the 8-bit range and repeat this for the red, green and blue stripes (and then presumably placed in a constant alpha band).

You can also use a different byte. Y8 is just one shade of gray, an 8-bit range, and Y16 is a single 16-bit range in shades of gray. (Look at the output of mencoder -rawvideo format=help for a complete (albeit somewhat confusing) listing.)

Just to illustrate the use of numpy to view a 32-bit integer as four ranges of 8-bit integers:

 import numpy as np height, width = 20,20 # Make an array with 4 bands of uint8 integers image = np.zeros((height, width, 4), dtype=np.uint8) # Filling a single band (red) b,g,r,a = image.T r.fill(255) # Fill the image with yellow and leave alpha alone image[...,:3] = (255, 255, 0) # Then when we want to view it as a single, 32-bit band: image32bit = image.reshape(-1).view(np.uint32).reshape(height, width) # (Note that this is a view. In other words, we could change "b" above # and it would change "image32bit") 

In your case, however, you probably want to do something more like this:

 import numpy as np from videosink import VideoSink height, width = 20,20 numframes = 1000 data = np.random.random((height, width, numframes)) # Rescale your data into 0-255, 8-bit integers # (This could be done in-place if you need to conserve memory) d ata_rescaled = 255.0 / (data.max() - data.min()) * (data - data.min()) data_rescaled = data_rescaled.astype(np.uint8) # The key here is the "Y8" format. It 8-bit grayscale. video = VideoSink((height,width), "test", rate=20, byteorder="Y8") # Iterate over last axis for frame in data.T: video.run(frame.T) video.close() 
+5
source

Source: https://habr.com/ru/post/894919/


All Articles