python音视频开发_Python音视频开发:消除抖音短视频Logo的图形化工具实现
一、引言
在《Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解》节介绍了怎么通过Python+Moviepy+OpenCV实现消除视频Logo的四种方法,并提供了详细的实现思路和实现代码,但这种原生态的应用不适合开发人员以外的其他人员使用,提供一个图形界面的工具程序是比较好的解决方案,本文就介绍实现这样一个图形化工具的步骤。
二、图形界面设计
2.1、主界面
从上面截图可以看到,主界面处理公共框架的功能外,提供了三大类功能,分别是消除准备(包括选择Logo、选择替换图)、查看功能(包括查看Logo图、查看替换图)、视频Logo消除(包括基于帧的预览、视频预览以及视频输出)。
2.2、图形化信息预览窗
该窗口可以用于预览图像及信息的展现,使用QGraphicView来实现:
三、程序实现
3.1、主界面派生类定义及相关初始化方法
class mainWin(QtWidgets.QMainWindow,ui_mainWin.Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.initValues()
self.initSignalAndSlots()
self.initPublicFrame()
def initWidgetSatus(self):#初始化界面元素状态
self.action_selectReplaceRegion.setEnabled(False)
self.action_selectLog.setEnabled(False)
self.action_previewOneFrame.setEnabled(False)
self.action_viewLogoImg.setEnabled(False)
self.action_videoPreview.setEnabled(False)
self.action_viewReplaceImg.setEnabled(False)
self.action_outputVideo.setEnabled(False)
def initOperations(self):#当选择不同的视频文件时要作废原视频操作的相关记录
self.logoSelected = False
self.replaceRegSelected =False
if self.srcFName:
self.videoOperation = CSubVideoImg(self.srcFName)
self.replaceObject = None
self.logoObjList = None
self.destFNameManuChanged = False
def initValues(self):#部分实例变量初始化
self.initWidgetSatus()
self.videoOperation = None
self.srcFName = None
self.destFName = None
self.srcDir = ""
self.destDir = ""
self.showHelpInfo = True #是否显示操作提示信息
self.destFNameManuChanged = False #输出文件是否手工修改标记
self.ridLogoManner = ridLogoManner_inpaint #缺省消除方式
self.imgInfW = imgInfoWin.imgInfoWin() #创建图像信息展示窗
self.fileDialog = QtWidgets.QFileDialog(self)
self.initOperations()
def initPublicFrame(self):#公共框架初始化
self.toggleOperationInfObject = self.actionshowHideOpInf # 显隐操作信息窗的开关对象如按钮、动作等,必须可以使用setText方法
self.connectShowInfoSignal = self.actionshowHideOpInf.triggered # 用于触发打开或关闭输出信息窗的信号
self.connectAboutSignal = self.actionAbout.triggered # 用于触发打开about提示窗的信号
self.needShowHints = False # 如果需要在运行窗口显示初始的操作提示信息,则将此置为True,并在本类中提供showOperationHints(displayMsgWin)实例方法
def initSignalAndSlots(self): #信号和槽连接,所有重要操作都会重新触发界面元素状态设置
self.btn_choiceSrc.clicked.connect(self.chooseFile) #选择源文件
self.videoFile.textChanged['QString'].connect(self.verifyWidgetStatus)
self.destFile.textEdited.connect(self.verifyWidgetStatus) #目标文件修改了
self.btn_choiceDest.clicked.connect(self.chooseFile)
self.destFile.textEdited.connect(self.manuChangeDestFName) #输出文件如果手工修改了则不会根据选择的视频文件自动同步
self.action_selectLog.triggered.connect(self.selectLog) #选择Logo区域信号连接
self.action_previewOneFrame.triggered.connect(self.previewOneFrame) #帧预览信号连接
self.action_videoPreview.triggered.connect(self.videoPreview) #视频预览信号连接
self.action_help.triggered.connect(self.help) #帮助信号连接
self.action_selectReplaceRegion.triggered.connect(self.selectReplaceRegion) #替换图像选择信号连接
self.action_viewLogoImg.triggered.connect(self.viewLogoImg) #查看Logo图像信号连接
self.action_viewReplaceImg.triggered.connect(self.viewReplaceImg) #查看替换图像信号连接
self.action_outputVideo.triggered.connect(self.convertVideo) #输出处理视频信号连接
#消除方式变化信号连接
self.radioButton_staticImg.toggled.connect(self.ridLogoMannerSelected)
self.radioButton_frameImg.toggled.connect(self.ridLogoMannerSelected)
self.radioButton_inpaint.toggled.connect(self.ridLogoMannerSelected)
self.radioButton_multiSampleInpaint.toggled.connect(self.ridLogoMannerSelected)
3.2、信息显示方法
def showHelp(self,helpinf): #显示帮助信息
print(helpinf)
if self.checkBox_showOperHint.isChecked():
QMessageBox.information(self, '操作提示', helpinf, QMessageBox.Ok )
def showInfo(self,info):#显示提示信息
print(info)
QMessageBox.information(self, '操作提示', info, QMessageBox.Ok )
def showImgInf(self,*showObjs): #在图像信息窗按顺序显示相关图像或文本
imgInfW = self.imgInfW
for showObj in showObjs:
if showObj is None: continue
if isinstance(showObj,str):
imgInfW.showText(showObj)
else:
qtimg = imgInfW.showCVImg(showObj)
imgInfW.show()
3.3、部件状态设置方法
def verifyWidgetStatus(self): #根据当前操作确认界面元素的状态
self.initWidgetSatus()
videoFName = self.videoFile.text().strip()
if len(videoFName):
dir = QtCore.QDir("")
if(dir.exists(videoFName)):
self.action_selectLog.setEnabled(True)
if self.ridLogoManner in [ridLogoManner_staticImg,ridLogoManner_frameImg]:
if self.logoSelected:
self.action_selectReplaceRegion.setEnabled(True)
if videoFName!=self.srcFName:
self.srcFName = videoFName
self.initOperations()
if self.logoSelected and (self.replaceRegSelected or self.ridLogoManner in [ridLogoManner_inpaint,ridLogoManner_multiSampleInpaint] ):
self.action_previewOneFrame.setEnabled(True)
self.action_videoPreview.setEnabled(True)
destFName = self.destFile.text().strip()
if len(destFName):
self.action_outputVideo.setEnabled(True)
self.destFName = destFName
if self.replaceRegSelected:
if self.ridLogoManner in [ridLogoManner_staticImg,ridLogoManner_frameImg]:
self.action_viewReplaceImg.setEnabled(True)
if self.logoSelected:
self.action_viewLogoImg.setEnabled(True)
3.4、消除准备相关动作槽方法示例
下面是准备消除操作的一个关键槽方法–选择Logo图像的槽方法:
def selectLog(self): #实现Logo图像选择
fps = int(self.lineEdit_logoSelectFps.text().strip())
if self.ridLogoManner != ridLogoManner_multiSampleInpaint:
helpstr = "将弹出新窗口按设定的帧率播放视频图像,请在显示的视频上使用鼠标左键选择Logo图像的范围。注意:\n" + \
"1、选择时会有蓝色边框的矩形确认选择范围,当选择完成时松开鼠标即可确认选择;\n" + \
"2、视频选择时会停止播放,可以选择完成后通过鼠标右键点击或鼠标双击恢复视频播放\n" + \
"3、如果选择错了可以重新选择;\n" + \
"4、如果确认选择结束,按ESC或Q、q三者中的一个退出选择操作,系统将记录选择的Logo图像;\n" + \
"5、选择的Logo图像可以通过查看菜单下的相关菜单进行查看。\n\n" + \
"本提示信息可以通过界面“显示操作提示信息”复选框关闭。"
else:
helpstr = "将弹出新窗口按设定的帧率播放视频图像,请在显示的视频上使用鼠标左键选择Logo图像的范围。注意:\n" + \
"1、选择时会有蓝色边框的矩形确认选择范围,当选择完成时松开鼠标即可确认选择;\n" + \
"2、视频选择时会停止播放,可以选择完成后通过鼠标右键点击或鼠标双击恢复视频播放\n" + \
"3、如果选择错了可以重新选择;\n" + \
"4、如果确认选择,按n、N、s、S将保存当前选择Logo图像,恢复播放后可以再选择Logo再保存,以支持选择多个Logo图像" \
"5,按ESC或Q、q三者中的一个退出选择操作,退出时已选择图像会保存,系统将不剔重的记录选择的所有Logo图像;\n" + \
"6、选择的Logo图像可以通过查看菜单下的相关菜单进行查看。\n\n" + \
"本提示信息可以通过界面“显示操作提示信息”复选框关闭。"
self.showHelp(helpstr)
logobjs,frame = self.videoOperation.getROI("select multiLogo Imgs Range",fps)
if logobjs is not None and len(logobjs):
self.logoSelected = True
self.logoObjList = (logobjs, frame)
self.verifyWidgetStatus()
self.frameMask = self.videoOperation.genMultiLogoFrameMask([logobjs[-1]],frame)
self.multiFrameMask = self.videoOperation.genMultiLogoFrameMask(logobjs, frame)
self.frame = frame
else:
self.showInfo("本次操作没有选择对应Logo图像,如果要执行后续操作,请重新选择。")
3.5、查看动作槽方法示例
def viewLogoImg(self): #查看Logo图像
if not self.logoSelected:
self.showInfo("当前视频文件尚未选择Logo图像")
return
self.showImgInf( f"截取的Logo共计{len(self.logoObjList[0])}个,除了多采样图像修复术外,其他消除方法都只取最后一个。各图像如下:\n ")
count = 0
logoObjs = self.logoObjList[0]
for logoobj in logoObjs:
self.showImgInf(f" 第{count + 1}个:",logoobj[0])
count += 1
3.6、视频输出槽方法
def convertVideo(self): #输出视频
self.setEnabled(False)
if self.ridLogoManner in [ridLogoManner_staticImg,ridLogoManner_frameImg]:
ret, inf = self.videoOperation.convertVideo(self.destFName, self.ridLogoManner, self.logoObjList, self.replaceObject)
elif self.ridLogoManner == ridLogoManner_inpaint:
ret,inf = self.videoOperation.convertVideo( self.destFName, self.ridLogoManner, self.logoObjList, frameMask=self.frameMask)
else:
ret,inf = self.videoOperation.convertVideo( self.destFName, self.ridLogoManner, self.logoObjList, frameMask=self.multiFrameMask)
print(inf)
self.setEnabled(True)
四、主程序代码
if __name__=='__main__':
app = QtWidgets.QApplication(sys.argv)
w = mainWin()
loadWin = loadApp.loadAppWin(w,"视频Logo消除", True, True)
w.show()
sys.exit(app.exec_())
五、运行截图
1、初始界面
2、选择Logo图像的截图
3、查看Logo图像的截图
4、输出视频文件截图
六、打包成exe
老猿在win7上最终打包的可执行程序包已经上传到百度云,大家可以下载下来长期免费使用。具体下载地址为百度网盘。
提取码:yh2d
注意:
百度云上分享的《咖啡狗免费工具软件共享空间》下的不同软件安装时必须解压到不同目录,如果解压到同一目录可能有冲突导致不能正常运行,但解压后遵循如下要求可以将其聚合到同一个目录:
放置到同一目录的不同软件的版本必须相同,版本为压缩文件名中VX.X标注;
聚合拷贝时除拷贝执行文件外,还有resource目录必须拷贝,如果resource目录下有相同文件名可以覆盖;
聚合拷贝exe文件和resource目录及其下文件到其他已解压工具目录后,源目录可以删除。
关于老猿的付费专栏
老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。
跟老猿学Python!
python音视频开发_Python音视频开发:消除抖音短视频Logo的图形化工具实现相关推荐
- Python音视频开发:消除抖音短视频Logo的图形化工具实现
☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解>节介绍了怎么通过Python+Moviepy+OpenCV实现 ...
- python爬取抖音用户评论_python实现模拟器爬取抖音评论数据的示例代码
目标: 由于之前和朋友聊到抖音评论的爬虫,demo做出来之后一直没整理,最近时间充裕后,在这里做个笔记. 提示:大体思路 通过fiddle + app模拟器进行抖音抓包,使用python进行数据整理 ...
- python 写数值模拟器_python实现模拟器爬取抖音评论数据的示例代码
目标: 由于之前和朋友聊到抖音评论的爬虫,demo做出来之后一直没整理,最近时间充裕后,在这里做个笔记. 提示:大体思路 通过fiddle + app模拟器进行抖音抓包,使用python进行数据整理 ...
- python爬取抖音用户数据_python批量爬取下载抖音视频
本文实例为大家分享了python批量爬取下载抖音视频的具体代码,供大家参考,具体内容如下 import os import requests import re import sys import a ...
- Python音视频开发:消除抖音短视频Logo和去电视台标
☞ ░ 前往老猿Python博文目录 ░ 一.引言 对于带Logo(如抖音Logo.电视台标)的视频,有三种方案进行Logo消除: 直接将对应区域用对应图像替换: 直接将对应区域模糊化: 通过变换将要 ...
- SpyNote V5.0图形化工具远程控制Android手机教程(图文教程+演示视频)
*本文原创作者:艾登--皮尔斯,本文属FreeBuf原创奖励计划,未经许可禁止转载 前言 本篇文章主要以图文教程和视频演示详细地教你如何快速学会使用SpyNote 5.0图形化工具来穿透内网远程控制A ...
- Moviepy音视频开发:视频转gif动画或jpg图片exe图形化工具开发案例
☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿之所以学习和研究Moviepy的使用,是因为需要一个将视频转成动画的工具,当时在网上到处搜索查找免费使用工具,结果找了很多自称免费的工具,但转完 ...
- 抖音右上角一个小黄点是什么_抖音官方入驻视频号,释放了一个什么样的信号?...
专注视频号观察第 328 篇这几天,视频号生态新入驻了一个企业号,在圈里引起不少的轰动,因为这个号的名字叫做---抖音.这件事在圈里引发不少的轰动,很多人惊叹:"连抖音都来开视频号了,你还在 ...
- 前端开发使用的 安卓模拟器_抖音有电脑版或者网页版吗?如何在电脑上使用抖音?...
大家好,欢迎来到创推学苑,最近很多小伙伴来问我们是否可以在电脑上使用抖音,因为有一些玩法和数据抓取用电脑操作更方便一些,当然也有习惯用电脑看短视频的朋友. 那么我们如何在pc端使用抖音app呢?首先我 ...
最新文章
- app网站换服务器,app切换服务器
- 1029 C语言文法定义
- ELF文件格式详解-请查收
- 2019 ICPC Asia Nanchang Regional K.Tree 树上启发式合并 + 动态开点线段树
- print2flashwindows7旗舰版下载哪一个_JUJUMAO_MSDN原版 win 7 二合一 旗舰版32位 64位原版ISO镜像...
- 10. VMware Tools 安裝
- LeetCode 258. Add Digits
- 有这几个编程利器网站,再也不愁学习
- 速芯科技完成1亿元人民币融资
- php root权限执行命令,如何使用PHP执行需要root权限的系统命令
- Visual Studio Code 10 月 Python 扩展更新
- python中的__all__
- switch如何更新大气层,和进入hekate界面
- JAVA远程声卡,Delphi带多声道声卡(ASIO)
- python相关性分析及可视化
- 2022-2028全球卧式滚齿机行业调研及趋势分析报告
- 硬件参数 调整 麦克风MIC灵敏度 原理
- 乌班图配置 https ssl证书
- 工科硕士毕业14年,谈谈我的经验教训
- 【强化学习】Q-Learning算法详解以及Python实现【80行代码】
热门文章
- 用DNS进行网络度量和安全分析
- QC-excel的用例导入QC
- 2020年度个人小结
- 小麦教你如何利用电子表格制作交叉报表
- 格式工厂 v4.0.0 最新去广告绿色纯净版
- 如何判断团队是否真正实施Scrum -- Scrum方法二十问
- Pelnaty free neural network重新实现和$\nabla A \nabla u =f$
- 带安全笼的梯子的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 基于C#的列车运行控制与仿真系统设计
- android新技术 1