Skip to content

Latest commit

 

History

History
473 lines (414 loc) · 14.5 KB

633-1189959-视频.sy.md

File metadata and controls

473 lines (414 loc) · 14.5 KB
show version enable_checker
step
1.0
true

opencv

回忆

  • 上次研究了 动画过程的细节
    • 缓动 ease
    • 可以有 缓入和缓出
    • 可有二次、余弦等缓入公式
  • 可以把动画效果保存成视频文件吗?

下载视频

sudo apt install vlc
vlc Code/b2.mp4

图片描述

按帧播放视频

import cv2             
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")
while (video.isOpened()):
    retval, image = video.read()
    cv2.namedWindow("Video",0)
    cv2.resizeWindow("Video",400,300)
    if retval == True: 
        cv2.imshow("Video",image)
    else:              
        break          
    key = cv2.waitKey(1)
    if key == 27:      
        break          
video.release()        
cv2.destroyAllWindows()
  • 运行效果

图片描述

获得视频属性

import cv2                                        
def decode_fourcc(cc):                            
    return "".join([chr((int(cc) >> 8 * i) & 0xFF) for i in range(4)])
                                                  
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
fps = video.get(cv2.CAP_PROP_FPS)                 
frame_count = video.get(cv2.CAP_PROP_FRAME_COUNT) 
frame_width = video.get(cv2.CAP_PROP_FRAME_WIDTH) 
frame_height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
decodes = video.get(cv2.CAP_PROP_FOURCC)          
print("fps=====",fps)                             
print("frame_count=====",frame_count)             
print("frame_width=====",frame_width)             
print("frame_height=====",frame_height)           
print("decodes=====",decodes)                     
print(f"fourcc is: {decodes, decode_fourcc(decodes)}")
  • 运行结果

图片描述

按帧号输出到视频

import cv2                      
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
frame_num = 0                   
while (video.isOpened()):       
    retval, frame = video.read()
    cv2.namedWindow("Video",0)  
    cv2.resizeWindow("Video",400,300)
    if retval == True:          
        cv2.putText(frame,"frame:"+str(frame_num),(30,80),cv2.FONT_HERSHEY_DUPLEX,2,(0,0,255),5)
        cv2.imshow("Video",frame)                                              
    else:                       
        break                   
    key = cv2.waitKey(1)        
    if key == 27:               
        break                   
    frame_num += 1              
video.release()                 
cv2.destroyAllWindows()
  • 效果

图片描述

另存视频文件

import cv2                                                                     
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
out = cv2.VideoWriter('./output.mp4',fourcc ,fps, size)
             
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        out.write(frame)
        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:       
        break
cap.release()                                                                 
out.release()
cv2.destroyAllWindows()

  • output.mp4是随着播放而不断增长的
ffplay -autoexit filename.mp4 #-autoexit是播放完自动关闭

图片描述

修改视频尺寸

import cv2
         
videoCapture = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
fps = 25 
size = (400, 300)
fourcc = cv2.VideoWriter_fourcc("m","p","4","v")
videoWriter = cv2.VideoWriter('resizex1.mp4', fourcc, fps, size)
         
while True:
    success, frame = videoCapture.read()
    if success:
        frame = cv2.resize(frame, (400, 300))
        videoWriter.write(frame)
    else:
        print('end')
        break
videoWriter.release()
cv2.destroyAllWindows()
  • 另存视频

图片描述

在视频上绘制矩形和五角星

import cv2
import random
import numpy as np
cap = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  

# 判断视频是否读取成功
if (cap.isOpened() == False):
    print("Error opening video stream or file")
# 获取帧
while (cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    #设置颜色
    i = random.randint(0, 255)
    j = random.randint(0, 255)
    k = random.randint(0, 255)
    #设置线条宽度
    width = random.randint(4, 10)
    flag = random.randint(0, 1)
    if ret == True:
        # 在每一帧上画矩形和五角星,frame帧,(四个坐标参数),(颜色),宽度
        if flag == 0:
            cv2.rectangle(frame, (int(200), int(300)), (int(400), int(500)), (i, j, k), width)
        else:
            pts = np.array([[70, 190], [222, 190], [280, 61], [330, 190], [467, 190],
                            [358, 260], [392, 380], [280, 308], [138, 380], [195, 260]])
            pts = pts.reshape((-1, 1, 2))  # reshape为10x1x2的numpy
            print(pts.shape)  # (10, 1, 2)
            cv2.polylines(frame, [pts], True, (i, j, k), width)
        # 显示视频
        cv2.imshow('Frame', frame)
        # 刷新视频
        cv2.waitKey(10)

        # 按q退出
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break

    # 退出循环
    else:
        break
  • 直接绘制

图片描述

  • 可以在时间上截取片段吗?

从时间上截取视频片段

import cv2 
import imageio
import time
frame_num = 0 
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
image_list = []
while (video.isOpened()):
    frame_num += 1
    retval, image = video.read()
    if frame_num <= 200:
        continue
    print(frame_num)
    cv2.namedWindow("Video",0)
    cv2.resizeWindow("Video",400,300)
    if retval == True:
        cv2.putText(image,"frame:"+str(frame_num),(30,80),cv2.FONT_HERSHEY_DUPLEX,2,(0,0,255),5)
        cv2.imshow("Video",image)
        image2 = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
        image_list.append(image2)
    else:
        break
    key = cv2.waitKey(1)
    if key == 27 or frame_num>=300:
        break
    time.sleep(1/24)
video.release()
cv2.destroyAllWindows()
imageio.mimsave("./kunkun.gif",image_list,fps=24)
  • 从200帧到300帧
    • 帧号 写在画面上
    • 输出到gif中

图片描述

  • 可以从空间上截取gif吗?

从空间上截取画面

import cv2                        
import imageio                    
import time                       
frame_num = 0                     
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
image_list = []                   
while (video.isOpened()):         
    frame_num += 1                
    retval, image = video.read()  
    if frame_num <= 200:          
        continue                  
    print(frame_num)              
    cv2.namedWindow("Video",0)    
    cv2.resizeWindow("Video",400,300)
    if retval == True:            
        cv2.putText(image,"frame:"+str(frame_num),(30,80),cv2.FONT_HERSHEY_DUPLEX,2,(0,0,255),5)
        image2 = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
        image3 = image2[100:270,300:800]
        cv2.imshow("Video",image3)
        image_list.append(image3) 
    else:                         
        break                     
    key = cv2.waitKey(1)          
    if key == 27 or frame_num>=300:
        break                     
    time.sleep(1/24)              
video.release()                   
cv2.destroyAllWindows()           
imageio.mimsave("./kunkun.gif",image_list,fps=24)
  • 结果

图片描述

最后在截取的动画上一个随机圆

import cv2                                        
import imageio                                    
import time                                       
from random import randint                        
frame_num = 0                                     
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
image_list = []                                   
while (video.isOpened()):                         
    frame_num += 1                                
    retval, image = video.read()                  
    if frame_num <= 200:                          
        continue                                  
    print(frame_num)                              
    cv2.namedWindow("Video",0)                    
    cv2.resizeWindow("Video",400,300)             
    if retval == True:                            
        cv2.putText(image,"frame:"+str(frame_num),(30,80),cv2.FONT_HERSHEY_DUPLEX,2,(0,0,255),5)
        image2 = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
        image3 = image2[100:270,300:800]          
        r = randint(35,70)                        
        cv2.circle(image3,(85,85),r,(255,255,0),-1)
        cv2.imshow("Video",image3)                
        image_list.append(image3)                 
    else:                                         
        break                                     
    key = cv2.waitKey(1)                          
    if key == 27 or frame_num>=300:               
        break                                     
    time.sleep(1/24)                              
video.release()                                   
cv2.destroyAllWindows()                           
imageio.mimsave("./kunkun.gif",image_list,fps=24)
  • 最终效果

图片描述

更复杂的圆

import cv2                       
import imageio                   
import time                      
import numpy as np               
import random                    
import math                      
frame_num = 0                    
video = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
image_list = []                  
while (video.isOpened()):        
    frame_num += 1               
    retval, image = video.read() 
    if frame_num <= 20:          
        continue                 
    print(frame_num)             
    cv2.namedWindow("Video",0)   
    cv2.resizeWindow("Video",400,300)
    if retval == True:           
        cv2.putText(image,"frame:"+str(frame_num),(30,80),cv2.FONT_HERSHEY_DUPLEX,1,(0,255,255),1)
        image2 = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
        image3 = image2[0:500,500:900]
        for num in range(0,360,15):
            radius = math.radians(num)
            x = int(150 + math.cos(radius) * 100)
            y = int(150 + math.sin(radius) * 100)
            r = random.randint(20,100)
            color = np.random.randint(0,256,size=(3,)).tolist()
            print("num:",num,"~color",color,"~(x,y)",(x,y),"~r",r)
            image3 = cv2.circle(image3,(x, y),r,color,1)
        image4 = cv2.cvtColor(image3,cv2.COLOR_RGB2BGR)
        cv2.imshow("Video",image4)
        image_list.append(image3)
    else:                        
        break                    
    key = cv2.waitKey(1)         
    if key == 27 or frame_num>=150:
        break                    
    time.sleep(1/24)             
video.release()                  
cv2.destroyAllWindows()          
imageio.mimsave("./kun.gif",image_list,fps=24)
  • 最终效果

图片描述

9.为视频添加字幕效果

import cv2
from random import randint
import numpy as np
import time

#把时间转化成毫秒计时
def timestamp(txt):
    s_t=list(map(int, txt.split(':')))
    return s_t[0]*60000+s_t[1]*1000+s_t[2]
#打开源文件,并读取一些视频信息
cap = cv2.VideoCapture("/home/shiyanlou/Code/b2.mp4")  
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
fps = cap.get(cv2.CAP_PROP_FPS)
#print(fps)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
#设置导出视频的内容
out = cv2.VideoWriter('./output.mp4',fourcc ,fps, size)
#对字幕的文件进行解析
captions =[]
with open('cap.txt', 'r',encoding='UTF-8') as f:
    for line in f:
        l = line.strip().split(' ')
        t = list(map(timestamp, l[0].split('-')))
        txt = l[1]
        for word in l[2:]:
            txt = txt + ' '+ word
        print(t,txt)
        captions.append([t,txt])
#对每一帧进行加工
now = 0
cap_now = 0
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        #输出随机乱码
        for x in range(int(width/8)):
            for y in range(int(height/20)):
                if randint(0, 127) < 36:
                    r = randint(20,127)
                    color = np.random.randint(256,size=(3),dtype=np.uint8).tolist()
                    #print(color)
                    cv2.putText(frame,chr(r),(x*8,y*20-1),cv2.FONT_HERSHEY_DUPLEX,0.4,color,1)
        #输出字幕
        if cap_now < len(captions) and now >= captions[cap_now][0][1]:
            cap_now = cap_now + 1
        if cap_now < len(captions) and now >= captions[cap_now][0][0] and now <= captions[cap_now][0][1]:
            #print(captions[cap_now][1])
            cv2.putText(frame,captions[cap_now][1],(0,int(height*0.75)),cv2.FONT_HERSHEY_DUPLEX,1,(256,256,256),1,cv2.LINE_AA, True)
        #显示画面
        cv2.imshow('frame',frame)
        out.write(frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:       
        break
    now = now + fps
cap.release()                                                                 
out.release()
cv2.destroyAllWindows()
  • 下面为cap.txt
00:00:00-00:00:03 Hello, I'm SDDL
00:00:03-00:00:06 Today show something you like
00:00:06-1000:59:59 Tap to text
  • 运行结果

图片描述

  • 可以把字幕放上去

总结 🤔

  • 这次研究了视频的修改
    • 视频另存
    • 视频大小调整
    • 视频空间裁剪
    • 视频时间截取
    • 在原视频上画别的
    • 在原视频上添加字幕
  • opencv 确实很强大
  • 还能做点什么?🤔
  • 下次再说👋