La source est https://github.com/osoken/tiltshift_effector
Un script Python qui applique un faux effet d'inclinaison à un fichier vidéo tel que .mov
.
J'ai utilisé «Numpy», «Scipy», «OpenCV», «Pillow». Pour Python 2.7.
Le principe est simple, il suffit de combiner l'image d'origine et l'image floue tout en la masquant. original
masque
Image floue
Après synthèse
Une fonction qui génère un masque.
def gen_mask(sz, t, tc, c, bc):
bounds = (0,limit_value(int(sz[1]*t),0,sz[1]),limit_value(int(sz[1]*(t+tc)),0,sz[1]),limit_value(int(sz[1]*(t+tc+c)),0,sz[1]),limit_value(int(sz[1]*(t+tc+c+bc)),0,sz[1]),sz[1]);
mask = np.array(Image.new('L', sz));
mask[bounds[0]:bounds[1],:] = 255;
for i in range(bounds[1],bounds[2]):
mask[i,:] = 255 - int(255.0/float( bounds[2] - bounds[1] ) * float(i - bounds[1]));
mask[bounds[3]:bounds[2],:] = 0;
for i in range(bounds[3],bounds[4]):
mask[i,:] = int(255.0/float( bounds[4] - bounds[3] ) * float(i - bounds[3]));
mask[bounds[4]:bounds[5],:] = 255;
mask = Image.fromarray(mask);
return mask;
sz
est un taple de (largeur, hauteur)
. «t», «tc», «c», «bc» sont des nombres de «0,0» à «1,0», «t» est la zone blanche supérieure, «c» est la zone noire du milieu, «tc» est » Entre t »et« c »,« bc »exprime la largeur du gradient entre« c »et la zone blanche ci-dessous, le rapport global étant« 1,0 ».
J'ai utilisé le gaussian_filter
dans scipy
pour générer l'image floue.
def gen_blurred_image(image, blur_factor):
if blur_factor == 0:
return image;
im = np.array(image);
return Image.fromarray(ndimage.gaussian_filter(im, sigma=[blur_factor, blur_factor, 0]));
Il est inutile de convertir la variable ʻimage au type
numpy.arrayet de la renvoyer immédiatement au type
PIL type ʻImage
juste pour le filtrage, mais en tenant compte d'autres opérations Ça ressemble à ça ... blur_factor
est la force du flou, donnée sous forme de fraction flottante.
Après avoir généré le masque et l'image floue, combinez-les avec la fonction «coller» de «PIL».
def paste_image(base, layer, mask):
im = base;
im.paste(layer, mask = mask);
return im;
Une fois que vous êtes prêt, tout ce que vous avez à faire est d'ouvrir la vidéo et d'appliquer le même traitement à chaque image.
cap = cv2.VideoCapture('input.mov');
orig_size = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)));
out = cv2.VideoWriter('output.mov', cv2.cv.CV_FOURCC('m','p','4','v'), int(cap.get(cv2.cv.CV_CAP_PROP_FPS)), orig_size);
mask = gen_mask(orig_size, 0.4, 0.15, 0.05, 0.1);
while cap.isOpened():
ret,im_orig = cap.read();
if ret == True:
im = Image.fromarray(im_orig);
im_blur = gen_blurred_image(im, 2.0);
im = np.array(paste_image(im, im_blur, mask));
cv2.imshow('view', im);
out.write(im);
key = cv2.waitKey(1);
if key == 27:
break;
else:
break;
out.release();
cap.release();
cv2.destroyAllWindows();
La version du référentiel gère les options d'entrée, etc., donc le nombre de lignes est grand, mais en substance, c'est comme ça. J'ajuste également la qualité et la saturation de l'image. La dernière clé == 27
de la boucle se termine prématurément par ʻesc`.
Recommended Posts