我现在正在尝试使用光流插值视频。我能够通过参考this question并将其用作参考来插入视频。 所以我的问题是:是否可以使用原始帧和光流帧以 1/4 为单位更好地插值视频? 提前谢谢你。
我试过将光流框减半,重新映射到原图,但是没有用。 (当然,这很明显,但是……)。
next image
是通过将 previous image
向右平移创建的(我希望它是可见的)。
现在,让我们计算两个图像之间的光流并绘制流矢量。
optical_flow = cv2.calcOpticalFlowFarneback(img1, img2, None, pyr_scale = 0.5, levels = 3, winsize = 200, iterations = 3, poly_n = 5, poly_sigma = 1.1, flags = 0)
我已经采用了
previous image
并在其顶部绘制了流向量。
这张图片显示,previous image
是通过将next image
向左平移形成的。
如果你遵循这个,就很容易完成手头的任务。即在这两个帧之间插入帧
本质上,光流矢量告诉我们每个像素,像素来自
previous image
的位置。让我们谈谈一个特定的像素,它从 (100, 100) 移动到 (200, 100),即向正确的方向移动了 100 个像素。
问题是如果这两帧之间有匀速运动,这个像素会在哪里?
示例:如果这两帧之间有 4 帧,则像素将位于位置
initial location = (100, 100)
interpolated frame 1 = (120, 100)
interpolated frame 2 = (140, 100)
interpolated frame 3 = (160, 100)
interpolated frame 4 = (180, 100)
final location. = (200, 100)
废话少说,让我给你看一些代码。
def load_image(image_path):
"Load the image and convert it into a grayscale image"
img = cv2.imread(image_path)
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
def plot_flow_vectors(img, flow):
"""
Plots the flow vectors
"""
img = img.copy()
h, w = img.shape[:2]
step_size = 40
cv2.imshow("original_image", img)
for y in range(0, h, step_size):
for x in range(0, w, step_size):
# Get the flow vector at this point
dx, dy = flow[y, x]
# Draw an arrow to represent the flow vector
cv2.arrowedLine(img, (x, y), (int(x + dx), int(y + dy)), (0, 255, 0), 1, cv2.LINE_AA, tipLength=0.8)
cv2.imshow("image_with_flow_vectors", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img1 = load_image('first.jpeg') // load previous image
img2 = load_image('second.jpeg') // load next image
optical_flow = cv2.calcOpticalFlowFarneback(img1, img2, None, pyr_scale = 0.5, levels = 3, winsize = 200, iterations = 3, poly_n = 5, poly_sigma = 1.1, flags = 0) // calculate optical flow
plot_flow_vectors(img1, optical_flow) // plot flow vectors
// Generate frames in between
num_frames = 10
h, w = optical_flow.shape[:2]
for frame_num in range(1, num_frames+1):
alpha = frame_num / num_frames
flow = alpha * optical_flow
flow[:,:,0] += np.arange(w)
flow[:,:,1] += np.arange(h)[:,np.newaxis]
interpolated_frame = cv2.remap(img2, flow, None, cv2.INTER_LINEAR)
cv2.imshow("intermediate_frame", interpolated_frame)
cv2.waitKey(0)
PS:光流矢量也显示了 y 方向的运动(如果没有)。我认为这是两帧之间大运动的产物。视频中的帧通常不是这种情况。
编辑:我创建了一个 github 存储库来在两个视频帧之间插入帧,以增加视频 fps 或从输入视频中获取慢动作视频。看看在这里