Created
April 21, 2025 21:15
-
-
Save me-suzy/d887c6cb8a83a4978bcd8caf56c52320 to your computer and use it in GitHub Desktop.
Ken Burns (zoom si pan) Face Video cu Subtitrare de la o Imagine (dar mareste si micsoreaza imaginea)
This file contains hidden or 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 cv2 | |
import numpy as np | |
import time | |
import os | |
from PIL import Image, ImageEnhance, ImageFilter | |
# Calea către imaginea ta | |
image_path = "d:/family-hugging.jpg" | |
# Verificăm dacă imaginea există | |
if not os.path.exists(image_path): | |
print(f"Nu s-a putut găsi imaginea la calea: {image_path}") | |
exit() | |
# Citirea imaginii | |
img = cv2.imread(image_path) | |
if img is None: | |
print(f"Nu s-a putut citi imaginea de la calea: {image_path}") | |
exit() | |
# Obținem dimensiunile imaginii | |
height, width, _ = img.shape | |
# Setăm parametrii pentru video | |
fps = 30 | |
duration = 10 # secunde | |
total_frames = fps * duration | |
# Configurăm scriitorul video | |
fourcc = cv2.VideoWriter_fourcc(*'XVID') # Cod pentru format AVI | |
output_path = "d:/family_animation.avi" | |
video_writer = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) | |
# Funcție pentru aplicarea efectelor AI | |
def apply_ai_effects(image): | |
# Convertim din BGR în RGB pentru PIL | |
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
# Convertim la PIL Image pentru efecte | |
pil_img = Image.fromarray(image_rgb) | |
# Îmbunătățim contrastul | |
enhancer = ImageEnhance.Contrast(pil_img) | |
pil_img = enhancer.enhance(1.2) | |
# Îmbunătățim culorile | |
enhancer = ImageEnhance.Color(pil_img) | |
pil_img = enhancer.enhance(1.15) | |
# Îmbunătățim luminozitatea | |
enhancer = ImageEnhance.Brightness(pil_img) | |
pil_img = enhancer.enhance(1.05) | |
# Adăugăm claritate | |
enhancer = ImageEnhance.Sharpness(pil_img) | |
pil_img = enhancer.enhance(1.3) | |
# Convertim înapoi la numpy array pentru OpenCV (RGB) | |
enhanced_rgb = np.array(pil_img) | |
# Convertim înapoi în BGR pentru OpenCV | |
enhanced_bgr = cv2.cvtColor(enhanced_rgb, cv2.COLOR_RGB2BGR) | |
return enhanced_bgr | |
# Aplicăm efectele AI pe imaginea originală | |
img_enhanced = apply_ai_effects(img) | |
# Funcție pentru a adăuga text pe imagine | |
def add_text(image, text, position, font_scale=1.5, thickness=2): | |
# Facem o copie pentru a nu modifica originalul | |
img_copy = image.copy() | |
# Adăugăm un fundal semi-transparent pentru text pentru lizibilitate | |
overlay = img_copy.copy() | |
pt1 = (0, position[1]-40) | |
pt2 = (width, position[1]+10) | |
cv2.rectangle(overlay, pt1, pt2, (0, 0, 0), -1) | |
cv2.addWeighted(overlay, 0.5, img_copy, 0.5, 0, img_copy) | |
# Adăugăm textul | |
cv2.putText(img_copy, text, position, cv2.FONT_HERSHEY_SIMPLEX, | |
font_scale, (255, 255, 255), thickness, cv2.LINE_AA) | |
return img_copy | |
print("Crearea animației a început...") | |
start_time = time.time() | |
# Generăm și scriem fiecare cadru | |
for frame_num in range(total_frames): | |
# Calculăm timpul curent în animație | |
t = frame_num / fps | |
# Primul efect: Zoom in (0-3 secunde) | |
if t < 3: | |
progress = t / 3.0 | |
zoom = 1.0 + (0.2 * progress) # Zoom de la 1.0 la 1.2 | |
offset_x = int(width * 0.1 * progress) # Mișcare spre dreapta | |
offset_y = int(height * 0.05 * progress) # Mișcare în jos | |
text = "Amintiri de familie" | |
# Al doilea efect: Pan spre dreapta (3-6 secunde) | |
elif t < 6: | |
progress = (t - 3) / 3.0 | |
zoom = 1.2 # Păstrăm zoom-ul | |
offset_x = int(width * (0.1 + 0.1 * progress)) # Continuăm mișcarea spre dreapta | |
offset_y = int(height * 0.05) # Păstrăm poziția verticală | |
text = "Amintiri de familie" | |
# Al treilea efect: Zoom out ușor și pan în sus (6-10 secunde) | |
else: | |
progress = (t - 6) / 4.0 | |
zoom = 1.2 - (0.05 * progress) # Zoom out ușor | |
offset_x = int(width * 0.2) # Păstrăm poziția orizontală | |
offset_y = int(height * (0.05 - 0.05 * progress)) # Mișcare în sus | |
text = "Momente prețioase" | |
# Calculăm noile dimensiuni bazate pe zoom | |
new_width = int(width * zoom) | |
new_height = int(height * zoom) | |
# Redimensionăm imaginea | |
img_zoomed = cv2.resize(img_enhanced, (new_width, new_height), interpolation=cv2.INTER_CUBIC) | |
# Calculăm poziția de crop pentru a păstra centrul de interes | |
center_x = int(new_width / 2 - width / 2 + offset_x) | |
center_y = int(new_height / 2 - height / 2 + offset_y) | |
# Ne asigurăm că nu ieșim din limite | |
center_x = max(0, min(center_x, new_width - width)) | |
center_y = max(0, min(center_y, new_height - height)) | |
# Crop pentru a obține dimensiunea originală | |
img_cropped = img_zoomed[center_y:center_y + height, center_x:center_x + width] | |
# Adăugăm efect de pulsație subtilă bazat pe timp | |
brightness_factor = 1.0 + 0.03 * np.sin(t * 2.0) | |
img_pulse = np.clip(img_cropped * brightness_factor, 0, 255).astype(np.uint8) | |
# Adăugăm text | |
text_opacity = 1.0 | |
# Facem fade in/out pentru text | |
if t < 1: # Fade in primul text | |
text_opacity = t | |
elif t > 5 and t < 6: # Fade out primul text | |
text_opacity = 6 - t | |
elif t > 6 and t < 7: # Fade in al doilea text | |
text_opacity = t - 6 | |
elif t > 9: # Fade out al doilea text | |
text_opacity = 10 - t | |
if text_opacity > 0: | |
# Calculăm opacitatea (0-255) | |
opacity = int(255 * text_opacity) | |
# Adăugăm textul cu opacitatea calculată | |
img_with_text = add_text(img_pulse, text, (int(width * 0.1), int(height * 0.9))) | |
# Combinăm cu imaginea originală folosind opacitatea | |
if opacity < 255: | |
alpha = opacity / 255.0 | |
img_pulse = cv2.addWeighted(img_with_text, alpha, img_pulse, 1 - alpha, 0) | |
else: | |
img_pulse = img_with_text | |
# Scriem cadrul în video | |
video_writer.write(img_pulse) | |
# Afișăm progresul | |
if frame_num % 30 == 0: | |
progress_percent = (frame_num / total_frames) * 100 | |
print(f"Progres: {progress_percent:.1f}% ({frame_num}/{total_frames} cadre)") | |
# Eliberăm resursele | |
video_writer.release() | |
end_time = time.time() | |
print(f"Animația a fost creată cu succes la calea: {output_path}") | |
print(f"Timp total de procesare: {end_time - start_time:.2f} secunde") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment