☞ ░ 前往老猿Python博文目录 ░

一、引言

在《Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解》节介绍了怎么通过Python+Moviepy+OpenCV实现消除视频Logo的四种方法,并提供了详细的实现思路和实现代码,但这种原生态的应用不适合开发人员以外的其他人员使用,提供一个图形界面的工具程序是比较好的解决方案,本文就介绍实现这样一个图形化工具的步骤。

本节的背景知识都在《Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解》介绍了,在此就不重复介绍了。

二、图形界面设计

本程序复用了《PyQt+moviepy音视频剪辑实战1:多个音视频合成顺序播放或同屏播放的视频文件实现详解》、《PyQt+moviepy音视频剪辑实战1:多视频合成顺序播放或同屏播放的视频文件》的公用框架,该框架提供统一的print输出管理、浮动窗口管理以及系统统一框架。

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 = Falseself.replaceRegSelected =Falseif self.srcFName:self.videoOperation = CSubVideoImg(self.srcFName)self.replaceObject = Noneself.logoObjList = Noneself.destFNameManuChanged = Falsedef initValues(self):#部分实例变量初始化self.initWidgetSatus()self.videoOperation = Noneself.srcFName = Noneself.destFName = Noneself.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.imgInfWfor showObj in showObjs:if showObj is None: continueif 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 = videoFNameself.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 = destFNameif  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 = Trueself.logoObjList = (logobjs, frame)self.verifyWidgetStatus()self.frameMask = self.videoOperation.genMultiLogoFrameMask([logobjs[-1]],frame)self.multiFrameMask = self.videoOperation.genMultiLogoFrameMask(logobjs, frame)self.frame = frameelse:self.showInfo("本次操作没有选择对应Logo图像,如果要执行后续操作,请重新选择。")

3.5、查看动作槽方法示例

    def viewLogoImg(self): #查看Logo图像if not self.logoSelected:self.showInfo("当前视频文件尚未选择Logo图像")returnself.showImgInf( f"截取的Logo共计{len(self.logoObjList[0])}个,除了多采样图像修复术外,其他消除方法都只取最后一个。各图像如下:\n ")count = 0logoObjs = 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

使用《PyQt(Python+Qt)学习随笔:windows下使用pyinstaller将PyQt文件打包成exe可执行文件》介绍的方法进行打包。

老猿在win7上最终打包的可执行程序包已经上传到百度云,大家可以下载下来长期免费使用。具体下载地址为百度网盘。

链接:https://pan.baidu.com/s/1UNaA2UqQBoxx-v8rCIPDhA

提取码:yh2d

选择该链接下的:视频Logo消除工具V2.0.rar 即可。

注意:
百度云上分享的《咖啡狗免费工具软件共享空间》下的不同软件安装时必须解压到不同目录,如果解压到同一目录可能有冲突导致不能正常运行,但解压后遵循如下要求可以将其聚合到同一个目录:

  1. 放置到同一目录的不同软件的版本必须相同,版本为压缩文件名中VX.X标注;
  2. 聚合拷贝时除拷贝执行文件外,还有resource目录必须拷贝,如果resource目录下有相同文件名可以覆盖;
  3. 聚合拷贝exe文件和resource目录及其下文件到其他已解压工具目录后,源目录可以删除。

更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《moviepy音视频开发专栏》。这2个专栏内容的导读请参考《Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载》。

关于老猿的付费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。

付费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》。本文对应付费专栏文章为《Python音视频开发:消除抖音短视频Logo的图形化工具实现过程详解》。

关于Moviepy音视频开发的内容,请大家参考《Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载》的导览式介绍。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python!

☞ ░ 前往老猿Python博文目录 ░

Python音视频开发:消除抖音短视频Logo的图形化工具实现相关推荐

  1. python音视频开发_Python音视频开发:消除抖音短视频Logo的图形化工具实现

    一.引言 在<Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解>节介绍了怎么通过Python+Moviepy+OpenCV实现消除视频Logo的四种方法,并提供了详细的 ...

  2. 短视频开发的基石:短视频源码

    短视频行业的兴起,短视频源码立下了汗马功劳,可以说是短视频开发的基石啦.短视频源码不止为短视频构建了各种方便,简洁,强大的功能,还为短视频系统的安全,稳定,流畅做了太多的工作. 短视频首页: 在短视频 ...

  3. Python音视频开发:消除抖音短视频Logo和去电视台标

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 对于带Logo(如抖音Logo.电视台标)的视频,有三种方案进行Logo消除: 直接将对应区域用对应图像替换: 直接将对应区域模糊化: 通过变换将要 ...

  4. 抖音账号矩阵系统/抖音seo霸屏系统源码/关键词短视频账号矩阵源码/独立私有部署/可定制开发

    前言:抖音账号矩阵系统/抖音seo霸屏系统源码/关键词短视频账号矩阵源码/独立私有部署/可定制开发 场景:抖音账号矩阵系统/抖音seo霸屏系统/抖音矩阵seo系统源码/独立部署,技术团队如何围绕抖音矩 ...

  5. Python 【哔哩哔哩】短视频的自动上传与发布实例演示,,同时支持抖音、快手、小红书、微视、西瓜视频、微信视频号等平台的视频自动化同步发布

    导读: 本系列依次介绍目前主流的短视频平台(抖音.快手.B站.微视.小红书.好看视频.西瓜视频.视频号.搜狐视频等)的短视频自动发布,希望帮助大家更方便.高效的来进行自媒体的创作与管理. [本文介绍的 ...

  6. 如何开发仿抖音短视频APP源码?

    如何开发仿抖音短视频APP源码? 流程列表 开发一个短视频最主要的流程分为 3 个,下面我将分步教你实现这 3 个流程下的各个功能点,功能点 API 可按需调用: 视频拍摄 a.启动拍摄 b.给拍摄添 ...

  7. 一人一天,如何开发一个抖音级的短视频?

    7 月,抖音全球日活跃用户 1.5 亿,月活跃用户突破 5 亿,其活跃程度及用户粘性概括为「抖音五分钟,人间两小时」.毫无疑问抖音是 2018 年最火应用之一.抖音的火爆,不仅意味着垂直短视频可以获得 ...

  8. 企业如何通过抖音矩阵号实现抖音搜索丨短视频SEO系统开发部署

    1.什么是抖音矩阵号运营?如何通过抖音SEO实现关键词侵占及排名优化?企业如何通过抖音SEO运营收货百亿流量? 抖音搜索你可以把它理解成更细分.更垂直的短视频搜索引擎.就像豆丁网一样,它就是垂直定位于 ...

  9. 叫板抖音,运营商入局短视频

    视频彩铃,会是下一个短视频生态的入口吗? 作者 | 曾响铃 本文经授权转自科技向令说(ID: xiangling0815) 掌握这些项目,秒杀90%的AI工程师! https://edu.csdn.n ...

最新文章

  1. 固定div的位置——不随窗口大小改变为改变位置
  2. linux实战应用案例: 777 权限表示什么,各数字又是什么含义?
  3. 2017菜鸡C与C++工程师总结,撸码撸码,垃圾专科生撸码人生
  4. python在线投票系统讲解_在线投票系统功能分析
  5. 删除linux内核多余架构,删除多余Linux内核方法
  6. 计算机目标导学方法,计算机教学计划
  7. 纽氏达特旗下智能机器人_专业工业机器人增程方案提供商纽氏达
  8. linux如何关掉正在启动的服务器,Linux服务管理(如何关闭或禁用不需要的服务)?...
  9. VScode自动跳转到某一行代码
  10. IOS 计时器 NSTimer
  11. hdu 4318 Power transmission 临接表 广搜 多校联合赛(二) 第九题
  12. IDEA 导出java文档
  13. DELPHI 字符转16进制、16进制转字符
  14. 模拟退火算法(simulated annealing algorithm)求极值
  15. Python-S9-Day123——爬虫两示例
  16. java 实现超级玛丽小游戏
  17. 1234,四个不同的数字组成多少种不同的数
  18. namenode启动报错:There appears to be a gap in the edit log. We expected txid 1, but got txid 16
  19. vnr光学识别怎么打开_小区安装家用防盗报警系统方案
  20. Git之版本回退和分支合并

热门文章

  1. 设计模式学习笔记--中介者模式(详细笔记)
  2. 团队管理16--团建要素剖析
  3. Summary of the January
  4. Python turtle库的常用函数
  5. windows下安装redis5
  6. *51nod1757 大灾变
  7. dumpbin的使用方法_dumpbin命令不能使用解决方法
  8. 【软件工程】 第0次个人作业
  9. 【每日一练】你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
  10. 【高频电子线路课程设计】调幅发射机