Created
June 15, 2016 06:06
-
-
Save robinsloan/9ddcb758a7c7aa0ae1aec5f425f7dbf8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess as sp | |
import numpy as np | |
import signal | |
from PIL import Image | |
### TUKEY WINDOW | |
# https://leohart.wordpress.com/2006/01/29/hello-world/ | |
def tukey_window(window_length, alpha=0.5): | |
# Special cases | |
if alpha <= 0: | |
return np.ones(window_length) #rectangular window | |
elif alpha >= 1: | |
return np.hanning(window_length) | |
# Normal case | |
x = np.linspace(0, 1, window_length) | |
w = np.ones(x.shape) | |
# first condition 0 <= x < alpha/2 | |
first_condition = x<alpha/2 | |
w[first_condition] = 0.5 * (1 + np.cos(2*np.pi/alpha * (x[first_condition] - alpha/2) )) | |
# second condition already taken care of | |
# third condition 1 - alpha / 2 <= x <= 1 | |
third_condition = x>=(1 - alpha/2) | |
w[third_condition] = 0.5 * (1 + np.cos(2*np.pi/alpha * (x[third_condition] - 1 + alpha/2))) | |
return w | |
### END TUKEY WINDOW | |
# using ffmpeg, slick | |
# from http://zulko.github.io/blog/2013/09/27/read-and-write-video-frames-in-python-using-ffmpeg/ | |
FFMPEG_BIN = "ffmpeg" | |
command = [ FFMPEG_BIN, | |
'-i', 'test.mov', | |
'-f', 'image2pipe', | |
'-pix_fmt', 'rgb24', | |
'-vcodec', 'rawvideo', '-'] | |
cmd = 'ffmpeg -i test.mov -f image2pipe -pix_fmt rgb24 -vcodec rawvideo -' | |
pipe = sp.Popen(cmd, shell=True, stdout=sp.PIPE, bufsize=10**8) | |
x_res = 1080 | |
y_res = 1920 | |
fps = 24 | |
duration = 5 | |
num_frames = 100 | |
print "num frames?", num_frames | |
frames = [] | |
while True: | |
# x_res*y_res*3 bytes (= 1 frame) | |
raw_image = pipe.stdout.read(x_res*y_res*3) | |
if len(raw_image) < x_res*y_res*3: | |
print "No data!" | |
break | |
# transform the byte read into a numpy array | |
image = np.fromstring(raw_image, dtype='uint8') | |
image = image.reshape((y_res,x_res,3)) # those dims always backwards, dunno why! | |
# throw away the data in the pipe's buffer. | |
frames.append(image) | |
pipe.stdout.flush() | |
pipe.send_signal(signal.SIGINT) | |
print "got frames:", len(frames) | |
OVERLAP_FACTOR = 0.75 | |
window_factor = 0.75 | |
window_width = 128 # this is really what i'm going to be tuning, based on fps etc. | |
window_stride = int(window_width * (1-OVERLAP_FACTOR)) | |
print "window width:", window_width | |
print "window stride:", window_stride | |
pano_width = len(frames)*window_stride | |
pano_img = Image.new("RGBA", (pano_width, y_res)) | |
mask_array = np.ndarray(shape=(y_res, window_width), dtype="uint8") | |
tukey_template = tukey_window(window_width, window_factor) * 255 | |
""" | |
import matplotlib.pyplot as plot | |
plot.plot(tukey_template) | |
axes = plot.gca() | |
margin = 10 | |
axes.set_xlim([-margin,slice_x+margin]) | |
axes.set_ylim([-margin,255+margin]) | |
plot.show() | |
""" | |
for i in xrange(y_res): | |
mask_array[i, :] = tukey_template | |
mask = Image.fromarray(mask_array, "L") | |
for i in xrange(len(frames)): | |
begin_window_x = i*window_stride | |
end_window_x = begin_window_x+window_width | |
if end_window_x > pano_width: | |
break | |
frame_slice = Image.fromarray(frames[i][:,x_res/2-window_width/2:x_res/2+window_width/2,:]) | |
pano_img.paste(frame_slice, (i*window_stride, 0), mask=mask) | |
pano_img.save("test-pano.jpg") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment