python - 如何将视频转 n 度
问题描述
我有一个需要旋转 n 度的视频(不仅仅是 90 或 180,我可以使用 ffmpeg 进行旋转,例如 1 或 10)。怎么能做到这一点?
我用谷歌搜索过,似乎没有这样的工具可以免费获得。
解决方案
我已经找到了一种不太优雅的方法,但它对我有用,所以我想分享它。
首先,我根据 learnopencv.com 的代码扭曲了视频:
# source learnopencv.com
import numpy as np
import cv2
from tqdm import tqdm
def fixBorder(frame):
s = frame.shape
# Scale the image 4% without moving the center
T = cv2.getRotationMatrix2D((s[1] / 2, s[0] / 2), 0, 1.04)
frame = cv2.warpAffine(frame, T, (s[1], s[0]))
return frame
def straighten_vid(input_name, output_name, d_dx=0, d_dy=0, d_da=0):
d_da *= np.pi / 180.
# Read input video
cp = cv2.VideoCapture(input_name)
# To get number of frames
n_frames = int(cp.get(cv2.CAP_PROP_FRAME_COUNT))
# To check the number of frames in the video
width = int(cp.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cp.get(cv2.CAP_PROP_FRAME_HEIGHT))
# get the number of frames per second
fps = cp.get(cv2.CAP_PROP_FPS)
# Try doing 2*width
out = cv2.VideoWriter(output_name, 0x7634706d, fps, (width, height))
transforms_smooth = np.zeros((n_frames - 1, 3), np.float32)
for i in tqdm(range(n_frames - 2)):
transforms_smooth[i] = [d_dx, d_dy, d_da]
# Reset stream to first frame
cp.set(cv2.CAP_PROP_POS_FRAMES, 0)
# Write n_frames-1 transformed frames
for i in range(n_frames - 2):
# Read next frame
success, frame = cp.read()
if not success:
break
# Extract transformations from the new transformation array
dx = transforms_smooth[i, 0]
dy = transforms_smooth[i, 1]
da = transforms_smooth[i, 2]
# Reconstruct transformation matrix accordingly to new values
m = np.zeros((2, 3), np.float32)
m[0, 0] = np.cos(da)
m[0, 1] = -np.sin(da)
m[1, 0] = np.sin(da)
m[1, 1] = np.cos(da)
m[0, 2] = dx
m[1, 2] = dy
# Apply affine wrapping to the given frame
frame_stabilized = cv2.warpAffine(frame, m, (width, height))
# Fix border artifacts
frame_stabilized = fixBorder(frame_stabilized)
# Write the frame to the file
frame_out = frame_stabilized #cv2.hconcat([frame, frame_stabilized])
# If the image is too big, resize it.
if (frame_out.shape[1] > 1920):
frame_out = cv2.resize(frame_out, (frame_out.shape[1] // 2, frame_out.shape[0] // 2))
# cv2.imshow("Before and After", frame_out)
# cv2.waitKey(10)
out.write(frame_out)
# Release video
cp.release()
out.release()
# Close windows
cv2.destroyAllWindows()
d_da 是转动的角度,d_dx 和 d_dy 用于使视频居中。但是,这会留下一个没有声音的文件。要重新添加它,我这样做:
import moviepy.editor as mpe
input_folder = "my_folder\\my_folder\\"
file_name = "my_file_name.MOV"
input_file = input_folder + file_name
output_file = input_folder + file_name.replace(".MOV", "_straightened.MOV")
output_file_final = input_folder + file_name.replace(".MOV", "_straightened_with_sound.mp4")
straighten_vid(input_file, output_file, 0, -70, 0.1)
my_clip = mpe.VideoFileClip(output_file)
audio_background = mpe.VideoFileClip(input_file).audio
final_clip = my_clip.set_audio(audio_background)
final_clip.write_videofile(output_file_final)
推荐阅读
- openssl - 具有向下兼容 API 的 OpenSSL 1.1.1(至 1.0.2)
- r - 当给定的数据集中缺少“预测”列时,如何使用随机森林预测测试数据?
- optimization - 无法在起点评估约束
- spring-mvc - 如何在 Spring Boot 2x Actuator 中启用 Spring MVC 指标
- python - 如何在并行运行所有脚本时运行特定命令
- python - 可选与鸭子打字
- optimization - 优化超大HashMap的内存使用
- python - HTTP Google Cloud Functions 上的 Python 和“导入请求”
- python - 识别股票组合中的股票并以相反的顺序对特定股票应用数字运算
- c++ - SourceLink:PDB 文件名大小写与存储库不匹配,破坏 SourceLink