【实操】python opencv将图片合成视频,并插入音频

简介:将一组图片合成视频,并插入音频。用到opencv,ffmpy,pydub等库。

目录

一、统一图片大小及类型,并按数字排序

二、图片合成视频

三、音频的合并与剪裁

四、音视频融合

opencv基本使用


一、统一图片大小及类型,并按数字排序

python对不同尺寸图像改成同一尺寸图像_自动化所副盐的博客-CSDN博客

import cv2
import os

path = './test'    #源目录
out_path = './image'    #修改之后的目录
dirs = os.listdir(path)
i=1
# 输出所有文件和文件夹
for item in dirs:
    image_path = './test/{}'.format(item)
    #print(image_path)
    image = cv2.imread(image_path)
    image = cv2.resize(image, (480, 320), interpolation=cv2.INTER_CUBIC)
    image_path = './image/{}.jpg'.format(str(i))
    cv2.imwrite(image_path, image)
    print(image_path)
    i+=1
    print(item)
    #打印原始名字
    print(i)
    #打印处理后照片名字
print("##################   Resize done     ########################")  

二、图片合成视频

如何将多张图片合成mp4视频格式,并加入背景音乐..._Python 集中营的博客-CSDN博客

import cv2
import os
import sys
from itertools import cycle
from ffmpy import FFmpeg
 

frame_path = "./image"      #图片目录。    图片像素大小需一致
filenames = os.listdir(frame_path)

# 通过itertools.cycle生成一无限循环的迭代器,每次迭代都输出下一章图像对象
img_iter = cycle([cv2.imread(os.sep.join([frame_path, x])) for x in filenames])

# 定义编码方式并创建VideoWriter对象 
fourcc = cv2.VideoWriter_fourcc(*'MJPG')# *'XVID'           视频编解码器
outfile = cv2.VideoWriter("./output.avi", fourcc, 5, (480, 320))    #大小必须和图片大小一致,且所以图片大小必须一致   -- photo_resize.py      
for i in range(100): 
    outfile.write(next(img_iter)) # 视频文件写入一帧
    #cv2.imshow('frame', next(img_iter)) 
    if cv2.waitKey(1) == 27: # 按下Esc键,程序退出(Esc的ASCII值是27,即0001  1011)
        break 
cv2.destroyAllWindows()
print("##################   Video done     ########################")        

其中包含了幻灯片播放的功能:

# OpenCV窗口循环显示
frame_path = "./test"
filenames = os.listdir(frame_path)
print(filenames)

# 通过itertools.cycle生成一无限循环的迭代器,每次迭代都输出下一章图像对象
img_iter = cycle([cv.imread(os.sep.join([frame_path, x])) for x in filenames])
print(img_iter)

key = 0
# 按ESC键结束循环播放,ESC的ASCII码为27,即0001  1011
while key & 0xFF != 27:
	#cv.namedWindow可以使窗口统一,但是图像会失真,不加则窗口大小不同
    cv.namedWindow('Kawaii Small Animals',cv.WINDOW_NORMAL)
    cv.imshow('Kawaii Small Animals', next(img_iter))
    key = cv.waitKey(500)
# cv.waitKey()参数不为0的时候则可以和循环结合产生动态画面
cv.destroyAllWindows()

三、音频的合并与剪裁

可以根据需要自己修改合成自己需要的音频:拼接,合并,叠加,添加静音,音频切割等。

注:合并需音频的通道数,采样率,音频时长是一致

Python-混音、叠加音频、拼接音频及批处理_zkw_1998的博客-CSDN博客_python 音频拼接

python 语音处理工具包AudioSegment的基本使用_王延凯的博客的博客-CSDN博客_audiosegment python
AudioSegment的方法_casanava18的博客-CSDN博客

from pydub import AudioSegment

#拼接音频
print("-----")
sound1 = AudioSegment.from_wav('a.wav')        #绝对路径
sound2 = AudioSegment.from_wav('b.wav')        #绝对路径
output = sound1 + sound2  # sound1拼接sound2
output.export("c.wav", format="wav")  # 保存文件

#添加静音
silence_ring = AudioSegment.silent(int(3*1000))
output = sound1 + silence_ring + sound2
output.export("d.wav", format="wav")  # 保存文件

#音频切割
sound= AudioSegment.from_wav("c.wav")
duration = sound.duration_seconds  #音频时长s
cut_wav = sound[0:10*1000]   #以毫秒为单位截取[begin, end]区间的音频
#cut_wav.export(filePath+ 'test.wav', format='wav')   #存储新的wav文件
cut_wav.export('f.wav', format='wav')   #存储新的wav文件
print("----contact done----")

##############   音频合并   音频叠加   ############
#音频合并: 先确认通道数,采样率,音频时长是否一致
sound3 = AudioSegment.from_wav('t.wav')        #绝对路径
sound = sound3
print("")
print("t.wav")
#取得音频的声道数
channel_count = sound.channels
print(channel_count)
#取得音频文件采样频率
frames_per_second = sound.frame_rate
print(frames_per_second)
#取得音频的持续时间,同 len()
print(sound.duration_seconds)
print((len(sound) / 1000.0))
t3=sound.duration_seconds

sound = sound1
silence_ring = AudioSegment.silent(int(sound3.duration_seconds*1000-sound1.duration_seconds*1000))  #ms
output = sound + silence_ring
output.export("a1.wav", format="wav")  # 保存文件
print("")
print("a.wav")
print(sound1.channels)
print(sound1.frame_rate)
print(sound1.duration_seconds)

sound_1 = AudioSegment.from_wav('a1.wav')        #绝对路径
print("")
print("a1.wav")
print(sound_1.channels)     #通道数
sound_1.frame_rate = 8000   #修改采样率
print(sound_1.frame_rate)   #采样率
sound_1 = sound_1[:(t3*1000)]   #截取指定时长音频
print(sound_1.duration_seconds) #音频时长
sound_1.export("a2.wav", format="wav")  # 保存文件

sound_2 = AudioSegment.from_wav('a2.wav')        #绝对路径
print("")
print("a2.wav")
print(sound_2.channels)
print(sound_2.frame_rate)
print(sound_2.duration_seconds)

# 把sound1和sound2合并成两通道音频
output = AudioSegment.from_mono_audiosegments(sound_2, sound3) #1,2的时长,帧率必须相同,且为单通道
output.export("mono.wav", format="wav")  # 保存文件
print("")
print("mono.wav")
print(output.channels)          #合并后变双通道
print(output.frame_rate)
print(output.duration_seconds)


# 叠加: 把sound2叠加到sound1上面
output = sound1.overlay(sound3)  
# output = sound1.overlay(sound2,position=5000)  # 把sound2叠加到sound1上面,从第5秒开始叠加
output.export("overlay.wav", format="wav")  # 保存文件
print("")
print("overlay.wav")
print(output.channels)      #还是sound1的音频信息 channels  frame_rate duration_seconds
print(output.frame_rate)    
print(output.duration_seconds)

output = sound3.overlay(sound1)  
output.export("overlay2.wav", format="wav")  # 保存文件
print("")
print("overlay2.wav")
print(output.channels)      #还是sound3的音频信息 channels  frame_rate duration_seconds
print(output.frame_rate)    
print(output.duration_seconds)

四、音视频融合

测试发现:音频与视频融合时,以时间短的为最终视频长度(len_audio, len_vedio),所以最好两者长度一致。

Python 视频添加音频(附代码) | Python工具_剑客阿良_ALiang的博客-CSDN博客_python 视频音频

from ffmpy import FFmpeg

video_path="./output.avi"
audio_path="./f.wav"
_codec = 'aac'
result="va.avi"
ff = FFmpeg(executable='C:\\Users\\***\\Python\\Python39\\Lib\\site-packages\\imageio_ffmpeg\\binaries\\ffmpeg-win64-v4.2.2.exe',inputs={video_path: None, audio_path: None},outputs={result: '-map 0:v -map 1:a -c:v copy -c:a {} -shortest'.format(_codec)})      #若修改环境变量,则不需要指定ffmpeg程序路径
print(ff.cmd)
ff.run()

opencv基本使用

import cv2 

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

img = cv2.imread('./a.jpeg')    #读BGR彩图       加cv2.IMREAD_GRAYSCALE,读灰度图
print(img.shape)    #三维结构:高度、宽度、颜色通道个数
print(img.size)     #像素点个数

img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)     #BGR彩图转换成灰度图        COLOR_BGR2RGB BGR转RGB
print(img2.shape)
print(img2.size)
cv2.imwrite('./gray.jpg',img2)    #保存图片
#cv_show('winName',img)
#cv_show('winName',img2)

pho = img[1000:1200,1000:1920]  # 剪裁 -- 进行切片 高100到800 宽200到800 -- 图像以左上角为起点,纵高右宽
#cv_show('win2',pho)

b,g,r = cv2.split(img)      # b.shape g.shape r.shape 都为 (1080, 1920)
#cv_show('win3',g)          # 或者填 b、r       是灰色亮度

#显示单一颜色
cur_img = img.copy()
cur_img[:,:,0] = 0 # B不要了 设置为0
cur_img[:,:,1] = 0 # G不要了 设置为0
#cur_img[:,:,2] = 0 # R不要了 设置为0
#cv_show('winR',cur_img)

猜你喜欢

转载自blog.csdn.net/lr94V587/article/details/127629669