(十四)老视频修复、视频超分、视频提高分辨率、视频高清化、视频清晰化、黑白视频上色、人脸祛斑、美颜、人体瘦身、视频去噪、批量处理、视频提高分辨率、视频逐帧修复

(十四)老视频修复、视频超分、视频提高分辨率、视频高清化、视频清晰化、黑白视频上色、人脸祛斑、美颜、人体瘦身、视频去噪、批量处理、视频提高分辨率、视频逐帧修复

本文的代码的功能是:可以对视频文件、视频批量增强清晰度,对老视频进行修复、复原操作、对黑白视频进行上色处理、人脸祛斑、美颜、人体瘦身、视频去噪等图像处理功能,使用了人工智能的算法。

本文与前几篇博文关联性较强,请事先阅读前几篇。 对此文感兴趣的可以加微深入探讨:herbert156
可运行的试用版本下载:https://pan.baidu.com/s/1cWZDzZCgXO2sb2Scm38lzQ
提取码: h8a4
如果提示过期,可以向博主索要新的SN文件。

一、主要功能:
以下的Python代码的功能:批量选择视频、批量处理,主要包括:
1、对视频、视频进行高清化、修复、上色并输出变换后的文件;
2、可以批量处理,在选择文件的对话框里可以选择多个文件,进行批量操作;
3、如果电脑有GPU,则会自动选择GPU处理,加快处理速度;
4、信息统计里面可以实时显示处理的各种统计信息;
5、视频处理完毕后自动进行音频的处理与合成。

软件运行界面如下:
在这里插入图片描述
二、主要代码:

话不多说,上代码!

UI的Python代码:

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ai_repire(object):
    def setupUi(self, ai_repire):
        ai_repire.setObjectName("ai_repire")
        ai_repire.setEnabled(True)
        ai_repire.resize(912, 823)
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        ai_repire.setFont(font)
        ai_repire.setMouseTracking(False)
        self.layoutWidget = QtWidgets.QWidget(ai_repire)
        self.layoutWidget.setGeometry(QtCore.QRect(360, 760, 531, 41))
        self.layoutWidget.setObjectName("layoutWidget")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.layoutWidget)
        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.startButton = QtWidgets.QPushButton(self.layoutWidget)
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.startButton.setFont(font)
        self.startButton.setObjectName("startButton")
        self.horizontalLayout_5.addWidget(self.startButton)
        self.stopButton = QtWidgets.QPushButton(self.layoutWidget)
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.stopButton.setFont(font)
        self.stopButton.setObjectName("stopButton")
        self.horizontalLayout_5.addWidget(self.stopButton)
        spacerItem = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_5.addItem(spacerItem)
        self.helpButton = QtWidgets.QPushButton(self.layoutWidget)
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.helpButton.setFont(font)
        self.helpButton.setObjectName("helpButton")
        self.horizontalLayout_5.addWidget(self.helpButton)
        self.quitButton = QtWidgets.QPushButton(self.layoutWidget)
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.quitButton.setFont(font)
        self.quitButton.setObjectName("quitButton")
        self.horizontalLayout_5.addWidget(self.quitButton)
        self.groupBox_2 = QtWidgets.QGroupBox(ai_repire)
        self.groupBox_2.setGeometry(QtCore.QRect(10, 20, 881, 281))
        self.groupBox_2.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
        self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_2.setObjectName("groupBox_2")
        self.my_label1 = QtWidgets.QLabel(self.groupBox_2)
        self.my_label1.setGeometry(QtCore.QRect(12, 30, 427, 240))
        self.my_label1.setObjectName("my_label1")
        self.my_label2 = QtWidgets.QLabel(self.groupBox_2)
        self.my_label2.setGeometry(QtCore.QRect(443, 30, 427, 240))
        self.my_label2.setObjectName("my_label2")
        self.groupBox_4 = QtWidgets.QGroupBox(ai_repire)
        self.groupBox_4.setGeometry(QtCore.QRect(10, 320, 881, 111))
        self.groupBox_4.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_4.setObjectName("groupBox_4")
        self.filesButton = QtWidgets.QPushButton(self.groupBox_4)
        self.filesButton.setGeometry(QtCore.QRect(20, 30, 78, 24))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.filesButton.setFont(font)
        self.filesButton.setObjectName("filesButton")
        self.outButton = QtWidgets.QPushButton(self.groupBox_4)
        self.outButton.setGeometry(QtCore.QRect(20, 70, 78, 24))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.outButton.setFont(font)
        self.outButton.setObjectName("outButton")
        self.txt1 = QtWidgets.QLabel(self.groupBox_4)
        self.txt1.setGeometry(QtCore.QRect(110, 32, 771, 20))
        self.txt1.setObjectName("txt1")
        self.txt2 = QtWidgets.QLabel(self.groupBox_4)
        self.txt2.setGeometry(QtCore.QRect(110, 72, 771, 20))
        self.txt2.setObjectName("txt2")
        self.groupBox_5 = QtWidgets.QGroupBox(ai_repire)
        self.groupBox_5.setGeometry(QtCore.QRect(10, 640, 881, 81))
        self.groupBox_5.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_5.setObjectName("groupBox_5")
        self.txt11 = QtWidgets.QLabel(self.groupBox_5)
        self.txt11.setGeometry(QtCore.QRect(20, 20, 861, 16))
        self.txt11.setObjectName("txt11")
        self.txt12 = QtWidgets.QLabel(self.groupBox_5)
        self.txt12.setGeometry(QtCore.QRect(20, 50, 861, 21))
        self.txt12.setObjectName("txt12")
        self.groupBox_6 = QtWidgets.QGroupBox(ai_repire)
        self.groupBox_6.setGeometry(QtCore.QRect(10, 450, 881, 71))
        self.groupBox_6.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_6.setObjectName("groupBox_6")
        self.checkBox_1 = QtWidgets.QCheckBox(self.groupBox_6)
        self.checkBox_1.setGeometry(QtCore.QRect(40, 30, 101, 16))
        self.checkBox_1.setObjectName("checkBox_1")
        self.buttonGroup1 = QtWidgets.QButtonGroup(ai_repire)
        self.buttonGroup1.setObjectName("buttonGroup1")
        self.buttonGroup1.addButton(self.checkBox_1)
        self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox_6)
        self.checkBox_2.setGeometry(QtCore.QRect(210, 30, 91, 16))
        self.checkBox_2.setObjectName("checkBox_2")
        self.buttonGroup1.addButton(self.checkBox_2)
        self.checkBox_3 = QtWidgets.QCheckBox(self.groupBox_6)
        self.checkBox_3.setGeometry(QtCore.QRect(390, 30, 101, 16))
        self.checkBox_3.setObjectName("checkBox_3")
        self.buttonGroup1.addButton(self.checkBox_3)
        self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox_6)
        self.checkBox_4.setGeometry(QtCore.QRect(550, 30, 101, 16))
        self.checkBox_4.setObjectName("checkBox_4")
        self.buttonGroup1.addButton(self.checkBox_4)
        self.checkBox_6 = QtWidgets.QCheckBox(self.groupBox_6)
        self.checkBox_6.setGeometry(QtCore.QRect(720, 30, 101, 16))
        self.checkBox_6.setObjectName("checkBox_6")
        self.buttonGroup1.addButton(self.checkBox_6)
        self.groupBox_7 = QtWidgets.QGroupBox(ai_repire)
        self.groupBox_7.setGeometry(QtCore.QRect(10, 550, 881, 71))
        self.groupBox_7.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_7.setObjectName("groupBox_7")
        self.outcheckBox_1 = QtWidgets.QCheckBox(self.groupBox_7)
        self.outcheckBox_1.setGeometry(QtCore.QRect(40, 30, 141, 16))
        self.outcheckBox_1.setObjectName("outcheckBox_1")
        self.buttonGroup2 = QtWidgets.QButtonGroup(ai_repire)
        self.buttonGroup2.setObjectName("buttonGroup2")
        self.buttonGroup2.addButton(self.outcheckBox_1)
        self.outcheckBox_2 = QtWidgets.QCheckBox(self.groupBox_7)
        self.outcheckBox_2.setGeometry(QtCore.QRect(210, 30, 141, 16))
        self.outcheckBox_2.setObjectName("outcheckBox_2")
        self.buttonGroup2.addButton(self.outcheckBox_2)
        self.outcheckBox_3 = QtWidgets.QCheckBox(self.groupBox_7)
        self.outcheckBox_3.setGeometry(QtCore.QRect(390, 30, 181, 16))
        self.outcheckBox_3.setObjectName("outcheckBox_3")
        self.buttonGroup2.addButton(self.outcheckBox_3)
        self.comboBox_1 = QtWidgets.QComboBox(self.groupBox_7)
        self.comboBox_1.setGeometry(QtCore.QRect(560, 28, 71, 22))
        self.comboBox_1.setObjectName("comboBox_1")
        self.check_result = QtWidgets.QPushButton(ai_repire)
        self.check_result.setGeometry(QtCore.QRect(130, 765, 121, 31))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(12)
        self.check_result.setFont(font)
        self.check_result.setObjectName("check_result")

        self.retranslateUi(ai_repire)
        QtCore.QMetaObject.connectSlotsByName(ai_repire)

    def retranslateUi(self, ai_repire):
        _translate = QtCore.QCoreApplication.translate
        ai_repire.setWindowTitle(_translate("ai_repire", "AI视频修复工具"))
        self.startButton.setText(_translate("ai_repire", "开始处理"))
        self.stopButton.setText(_translate("ai_repire", "停止处理"))
        self.helpButton.setText(_translate("ai_repire", "帮助"))
        self.quitButton.setText(_translate("ai_repire", "退出"))
        self.groupBox_2.setTitle(_translate("ai_repire", "预览窗口"))
        self.my_label1.setText(_translate("ai_repire", "原图"))
        self.my_label2.setText(_translate("ai_repire", "输出"))
        self.groupBox_4.setTitle(_translate("ai_repire", "文件设置"))
        self.filesButton.setText(_translate("ai_repire", "选择文件"))
        self.outButton.setText(_translate("ai_repire", "输出目录"))
        self.txt1.setText(_translate("ai_repire", "请选择视频文件[Ctrl+A全选、Ctrl/Shift+鼠标可多选]......"))
        self.txt2.setText(_translate("ai_repire", "输出目录"))
        self.groupBox_5.setTitle(_translate("ai_repire", "信息统计"))
        self.txt11.setText(_translate("ai_repire", "【视频信息】"))
        self.txt12.setText(_translate("ai_repire", "【运行信息】"))
        self.groupBox_6.setTitle(_translate("ai_repire", "功能选择"))
        self.checkBox_1.setText(_translate("ai_repire", "照片修复"))
        self.checkBox_2.setText(_translate("ai_repire", "黑白上色"))
        self.checkBox_3.setText(_translate("ai_repire", "人脸祛斑"))
        self.checkBox_4.setText(_translate("ai_repire", "人体美型"))
        self.checkBox_6.setText(_translate("ai_repire", "图像去噪"))
        self.groupBox_7.setTitle(_translate("ai_repire", "输出设置"))
        self.outcheckBox_1.setText(_translate("ai_repire", "原始分辨率"))
        self.outcheckBox_2.setText(_translate("ai_repire", "2倍分辨率"))
        self.outcheckBox_3.setText(_translate("ai_repire", "手动设置(图片宽度):"))
        self.check_result.setText(_translate("ai_repire", "查看输出目录"))

核心代码如下:

#AI视频处理工具_
import numpy as np
from PIL import Image,ImageDraw,ImageFont
import os, sys, time, cv2, threading
import moviepy.editor as mpe
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget,QMessageBox,QLabel, QFileDialog,QApplication
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPixmap, QIcon
import _fuction
from AI_VideoRepire_UI import Ui_ai_repire

DEBUG_FLAG = False
# DEBUG_FLAG = True
os.environ['TORCH_HOME'] = './torch_model'

my_title = "AI视频处理工具"
work_path = os.getcwd(); files = []; bg_files = ['']
input_path = work_path + '\input'; out_dir=work_path + '\output'

run_flag = 0
filesnums = 1 ; stop_flag = False ; t0 = 0; iii = 0
stop_flag_1 = False

pil_img = Image.open("damo/start_img.jpg")
ImageDraw.Draw(pil_img).text((160,150), "AI视频处理工具", (255,255,255),font=ImageFont.truetype("msyh.ttc", 36))
img_start = cv2.resize(cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR), (427, 240))

ImageDraw.Draw(pil_img).text((410,320), "正在加载AI模型,请稍后 ......", (255,255,255),font=ImageFont.truetype("msyh.ttc", 16))
img_s = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)

def showpic():  # 以下代码显示软件初始界面
    global ret, frame
    while run_flag == 0:
        cv2.imshow("AI Repire Transfer System", img_s)
        cv2.waitKey(100)
    cv2.destroyAllWindows()

t = threading.Thread(target=showpic)
t.start()

from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

class MainWin(QWidget, Ui_ai_repire):
    def __init__(self):
        super(MainWin, self).__init__()
        self.setupUi(self)
        global hwnd, run_flag
        self.createLayout()
        self.setWindowIcon(QIcon("damo/anime.ico"))
        self.setWindowFlags(Qt.WindowMinimizeButtonHint)
        self.show()
        run_flag = 1
        self.flash_item = True
        self.Style_flag = '1'

    def CV2toPIL(self, img):  # cv2转PIL
        return Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA))
    def PILtoCV2(self, img):  # PIL转cv2
        return cv2.cvtColor(np.array(img), cv2.COLOR_RGBA2BGRA)
    def two_pic_combine_PIL(self, back_img, fore_img): #2个图片合并
        back_img = self.CV2toPIL(back_img); fore_img = self.CV2toPIL(fore_img); r,g,b,alpha = fore_img.split()
        return cv2.cvtColor(self.PILtoCV2(Image.composite(fore_img, back_img, alpha)), cv2.COLOR_BGRA2BGR)
    def water_print(self, img):  # 打文字水印
        # cv2.putText(图像,需要添加字符串,需要绘制的坐标,字体类型,字号,字体颜色,字体粗细)
        w = img.shape[1]  # 宽度
        h = img.shape[0]  # 高度
        bk_img = np.zeros((160, 1280, 3), np.uint8)  # Creat a Image
        bk_img = cv2.putText(bk_img, 'wx:herbert156', (80, 130), cv2.LINE_AA, 5, (180, 180, 180), 12)
        bk_img = cv2.resize(bk_img, (w, int(w * 16 / 128)))
        mask = 255 * np.ones(bk_img.shape, bk_img.dtype)
        width, height, channels = img.shape
        center = (height // 2, width // 2)  # 融合的位置,可以自己设置
        res = cv2.seamlessClone(bk_img, img, mask, center, cv2.MONOCHROME_TRANSFER)
        return res

    def ShowCarton(self, result, img_path, style):  # 处理完成的帧
        # out_name = out_dir + '/' + os.path.splitext(os.path.split(img_path)[1])[0] + '_'+style+'.'
        # if not _fuction.if_legal or _fuction.softname != "AI_VideoRepire":
        #     result = self.water_print(result)
        # outfile = cv2.resize(result, (img_w, img_h))
        # return result
        pass

    def get_out_ratio(self,size_x,size_y):
        # if self.checkBox_1.isChecked(): multiple = 2    # 图片处理返回的图片分辨率是原图的2倍
        # else: multiple = 1  # 图片上色返回的图片分辨率是原图的1倍
        multiple = 1
        # size_x = result.shape[1]  # 宽度
        # size_y = result.shape[0]  # 高度
        if self.outcheckBox_1.isChecked(): # 原始分辨率
            img_w = int(size_x/multiple)
            img_h = int(size_y/multiple)
        elif self.outcheckBox_2.isChecked(): # 2倍分辨率
            img_w = int(size_x*2/multiple)
            img_h = int(size_y*2/multiple)
        elif self.outcheckBox_3.isChecked(): # 手动设置
            set_w = int(self.comboBox_1.currentText())
            img_w = set_w
            img_h = int(size_y * (set_w / size_x))
        else:
            img_w = int(size_x*2/multiple)
            img_h = int(size_y*2/multiple)
        return img_w, img_h

    def video_change(self, videofile):     #videofile:文件名
        global bg_files, iii, stop_flag, t0
        try: cap = cv2.VideoCapture(videofile)  # 读取视频文件
        except: self.show_error('读取视频文件:'+videofile+'时,出现错误(类型:视频文件无法解码)!'); return
        fps = cap.get(cv2.CAP_PROP_FPS)  # 帧率
        total_fr = cap.get(cv2.CAP_PROP_FRAME_COUNT)  # 总帧数
        size_x = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 视频流的帧宽度
        size_y = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 视频流的帧高度
        if fps==0 or total_fr==0 or size_x==0 or size_y==0:
            self.show_error('读取视频文件:' + videofile + '时,出现错误(类型:视频文件格式错误)!'); return
        try: len_m,len_s = divmod(total_fr/fps, 60)
        except: self.show_error('读取视频文件:' + videofile + '时,出现错误(类型:视频文件内容为空)!'); return

        videoinfo = '【文件信息】 视频总数:%d|正在处理(%d/%d):'%(filesnums,iii,filesnums) + os.path.split(videofile)[1]+\
                    '|帧分辨率:%dx%d|视频长度:%d分%d秒|FPS:%.2f帧/秒'%(size_x,size_y,len_m,len_s,fps)
        self.txt11.setText(videoinfo)
        # tempfile = os.path.split(bg_files[0])[0]+'\\out.mp4'
        tempfile = 'out.mp4'

        size_x1, size_y1 = self.get_out_ratio(size_x,size_y)
        # print(size_x,size_y,size_x1, size_y1)

        out = cv2.VideoWriter(tempfile, cv2.VideoWriter_fourcc(*'mp4v'), fps, (size_x1, size_y1))
        t1 = time.time(); next_fr = 0

        while (True):
            t2 = time.time()
            if stop_flag:
                cap.release();  out.release(); os.remove(tempfile)
                self.txt11.setText('【文件信息】 文件总数:%d个 | 处理完成:%d个' % (filesnums, iii))
                self.txt12.setText('【运行信息】 用户终止了正在进行的转换进程......')
                return
            next_fr += 1
            ret, frame = cap.read()
            if ret:
                if not DEBUG_FLAG: img2 = self.RunAI(frame)
                else: img2 = frame
                if img2 == []:
                    cap.release(); out.release(); os.remove(tempfile)
                    self.txt11.setText('【文件信息】 文件总数:%d个 | 处理完成:%d个' % (filesnums, iii))
                    return
                outfile = cv2.resize(img2, (size_x1, size_y1))
                out.write(outfile)  # 帧转成视频
            else: break

            if size_x / size_y > 1.778: fx = 427 / size_x; fy = fx  # 计算16:9的比例,以便缩放不变形
            else: fx = 240 / size_y; fy = fx
            self.my_label1.setPixmap(self.CvMatToQImage(cv2.resize(frame, (0, 0), fx=fx, fy=fy)))
            if size_x1 / size_y1 > 1.778: fx = 427 / size_x1; fy = fx  # 计算16:9的比例,以便缩放不变形
            else: fx = 240 / size_y1; fy = fx
            self.my_label2.setPixmap(self.CvMatToQImage(cv2.resize(outfile,  (0, 0), fx=fx, fy=fy)))

            # cv2.waitKey(1)
            t3 = time.time(); m1, s1 = divmod(t3-t0, 60); m2, s2 = divmod(t3-t1, 60)
            runinfo = '【运行信息】 总进度:%d%% | 总耗时:%d分%d秒 | 当前耗时:%d分%d秒 | 帧耗时:%.2f秒 | 速度:%.1fFPS'\
                      %(100*next_fr/total_fr, m1, s1, m2, s2,(t3-t2),1/(t3-t2))
            self.set_text_info(runinfo)
            cv2.waitKey(1)

        cap.release(); out.release()
        self.txt12.setText('【运行信息】 正在分离、合成音轨(大概需要:%.1f分钟,不要关闭软件),请稍后......'%(len_m/2))
        cv2.waitKey(1)
        try:
            audio = mpe.AudioFileClip(videofile)  # 分离声轨
            clip = mpe.VideoFileClip(tempfile)
            videoclip = clip.set_audio(audio)  # 写入声轨
            videoclip.write_videofile(out_dir+'/'+os.path.splitext(os.path.split(videofile)[1])[0]+ '_'+self.Style_flag+'.mp4',
                                      audio_codec = 'aac')
        except Exception as errmsg: print(repr(errmsg)); print('分离声音发生错误...')
        try: os.remove(tempfile)
        except Exception as errmsg: print(repr(errmsg)); print('删除临时文件发生错误...')
        t3 = time.time()
        self.txt12.setText('【运行信息】 处理完毕!总消耗时间:%d分%d秒'%(m1, s1))
        self.txt11.setText('【文件信息】 文件总数:%d个 | 处理完成:%d个'%(filesnums,iii))

    def CvMatToQImage(self, ptr):  # Converts an opencv MAT format into a QImage
        ptr = cv2.cvtColor(ptr, cv2.COLOR_BGRA2RGBA)  # 颜色格式转换
        QtImg = QtGui.QImage(ptr.data, ptr.shape[1], ptr.shape[0], QtGui.QImage.Format_RGBA8888)
        return QtGui.QPixmap.fromImage(QtImg)

    def show_error(self, str):
        r_button = QMessageBox.question(self, my_title,'\n\n'+str+'\n\n', QMessageBox.Ok)
    # def show_error(self, str):
    #     infoBox = QMessageBox()
    #     infoBox.setIcon(QMessageBox.Information)
    #     infoBox.setText(str)
    #     infoBox.setStandardButtons(QMessageBox.Ok)
    #     infoBox.button(QMessageBox.Ok).animateClick(30000)  # 10秒自动关闭
    #     infoBox.exec_()

    def set_False_Btn(self):
        self.filesButton.setEnabled(False);       self.outButton.setEnabled(False)
        self.startButton.setEnabled(False);       self.stopButton.setEnabled(True)
        self.quitButton.setEnabled(False)
    def set_True_Btn(self):
        self.filesButton.setEnabled(True);       self.outButton.setEnabled(True)
        self.startButton.setEnabled(True);       self.stopButton.setEnabled(False)
        self.quitButton.setEnabled(True)

    def startrun(self):
        global iii,stop_flag,stop_flag_1, t0
        iii = 0; stop_flag = False
        stop_flag_1 = False
        t0 = time.time()
        if files == []: self.show_error('请选择需要处理的图像文件!'); return
        if not os.path.exists(out_dir): self.show_error('输出目录不存在,请重新选择!'); return
        self.set_False_Btn()
        self.set_text_info('【运行信息】 正在初始化AI模型......')

        def run_thread():
            global iii, stop_flag, stop_flag_1, t0
            self.flash_item = True
            # 处理前调入相关模型数据
            if self.checkBox_1.isChecked():  # 照片处理
                self.Style_flag = '1'
                self.image_portrait = pipeline(Tasks.image_portrait_enhancement,
                                               model='damo/cv_gpen_image-portrait-enhancement')
            if self.checkBox_2.isChecked():  # 黑白上色
                self.Style_flag = '2'
                self.image_colorization = pipeline(Tasks.image_colorization, model='damo/cv_unet_image-colorization')
            if self.checkBox_3.isChecked():  # 人像美肤
                self.Style_flag = '3'
                self.skin_retouching = pipeline(Tasks.skin_retouching, model='damo/cv_unet_skin-retouching')
            if self.checkBox_4.isChecked():  # 人体美型
                self.Style_flag = '4'
                self.image_body_reshaping = pipeline(Tasks.image_body_reshaping,
                                                     model='damo/cv_flow-based-body-reshaping_damo')
            # if self.checkBox_5.isChecked():  # 人像抠图
            #     self.portrait_matting = pipeline(Tasks.portrait_matting, model='damo/cv_unet_image-matting')
            if self.checkBox_6.isChecked():  # 图像去噪
                self.Style_flag = '6'
                self.image_denoise_pipeline = pipeline(Tasks.image_denoising, model='damo/cv_nafnet_image-denoise_sidd')

            for file in files:
                iii += 1
                if stop_flag: break
                self.video_change(file)
            stop_flag_1 = True

        t = threading.Thread(target=run_thread)
        t.start()

        self.my_timer = QTimer(self)
        self.my_timer.start(500)
        self.my_timer.timeout.connect(self.set_run_over)

    def set_text_info(self, str):
        self.txt12.setText(str)
        self.flash_item_str = str

    def set_run_over(self):
        if stop_flag_1:
            self.my_timer.stop()
            self.set_True_Btn()
            return

        if self.txt12.text() == '【运行信息】': self.txt12.setText(self.flash_item_str)
        else: self.txt12.setText('【运行信息】')

        # if self.flash_item:
        #     print(self.flash_item_str)
        #     self.txt12.setText(self.flash_item_str)
        #     self.flash_item_str = self.flash_item_str + '.'
        #     self.flash_item = not self.flash_item
        # else:
        #     if self.txt12.text == '【运行信息】 ':  self.txt12.setText(self.flash_item_str)
        #     self.txt12.setText('【运行信息】 ')
        #     self.flash_item = not self.flash_item

    def stoprun(self):
        global stop_flag
        r_button = QMessageBox.question(self, my_title,
                                        "\n\n    确定要停止视频处理吗?\n\n", QMessageBox.Yes | QMessageBox.No)
        if r_button == QMessageBox.Yes: stop_flag = True

    def helpWin(self):
        str="\n\n\n1、【选择文件】选择需要处理的图像文件(可多选);\n2、【输出目录】处理后的文件目录,文件名:源文件_*.mp4;\n"+\
        "3、如没有Nvidia系列GPU,AI算法自动选择CPU处理;\n4、文件的长边不能大于3840像素;\n\n\n"+\
        "      本软件著作权归属:xxx         网址:xxx.com\n\n"
        QMessageBox.question(self, my_title, str, QMessageBox.Ok)
    def quitWin(self):
        r_button = QMessageBox.question(self, my_title,
                                        "\n\n退出将终止处理过程...... \n\n确认退出吗?\n\n", QMessageBox.Yes | QMessageBox.No)
        if r_button == QMessageBox.Yes: sys.exit()

    def checkresult(self):
        os.startfile(out_dir)

    def filesButton_fuc(self):
        global files,filesnums,input_path
        files, ok1 = QFileDialog.getOpenFileNames(self,'请选择视频文件[全选:Ctrl+A、多选:Ctrl/Shift+鼠标]',
                                                       input_path,"*.mp4;*.avi;*.mkv;;*.*")
        filesnums = len(files)
        if files!=[]:
            txt='目录:'+os.path.split(files[0])[0]+'|已选文件:'+str(filesnums)+'个|文件名:'
            for file in files: txt=txt+ os.path.split(file)[1]+'; '
            self.txt1.setText(txt)
            input_path = os.path.dirname(files[0])
        else:
            self.txt1.setText('请选择视频文件[全选:Ctrl+A、多选:Ctrl/Shift+鼠标]......')

    def outButton_fuc(self):
        global out_dir
        out_dir = QFileDialog.getExistingDirectory(self,'选择转换后的输出文件夹', work_path)
        if out_dir == '': self.txt2.setText('请选择视频变换后的文件保存目录......')
        else: self.txt2.setText(out_dir)

    def box_choose1(self):  # 照片高清处理
        pass
        # if self.checkBox_1.isChecked(): self.checkBox_2.setChecked(False)
        # else: self.checkBox_2.setChecked(True)
    def box_choose2(self):  # 黑白照片上色
        pass
        # if self.checkBox_2.isChecked(): self.checkBox_1.setChecked(False)
        # else: self.checkBox_1.setChecked(True)
    def box_choose3(self):  # 原始分辨率
        self.comboBox_1.setEnabled(False)
        # self.outcheckBox_2.setChecked(False)
        # self.outcheckBox_3.setChecked(False)
    def box_choose4(self):  # 2倍分辨率
        self.comboBox_1.setEnabled(False)
        # self.outcheckBox_1.setChecked(False)
        # self.outcheckBox_3.setChecked(False)
    def box_choose5(self):  # 手动设置
        self.comboBox_1.setEnabled(True)
        # self.outcheckBox_1.setChecked(False)
        # self.outcheckBox_2.setChecked(False)
    def click_comboBox1(self, text):    # 手动分辨率
        pass
    def createLayout(self):
        self.my_label1.setPixmap(self.CvMatToQImage(img_start))
        self.my_label2.setPixmap(self.CvMatToQImage(img_start))

        self.my_label1.setAlignment(Qt.AlignCenter); self.my_label2.setAlignment(Qt.AlignCenter)
        self.my_label1.setFixedSize(427, 240); self.my_label2.setFixedSize(427, 240)
        self.my_label1.setAlignment(Qt.AlignCenter); self.my_label2.setAlignment(Qt.AlignCenter)
        self.my_label1.setToolTip("本区域,显示的是原始视频缩略图...")
        self.my_label2.setToolTip("本区域,显示的是处理后的缩略图...")

        self.checkBox_1.setChecked(True)
        self.outcheckBox_1.setChecked(True)

        self.checkBox_1.stateChanged.connect(self.box_choose1)
        self.checkBox_2.stateChanged.connect(self.box_choose2)
        self.outcheckBox_1.stateChanged.connect(self.box_choose3)
        self.outcheckBox_2.stateChanged.connect(self.box_choose4)
        self.outcheckBox_3.stateChanged.connect(self.box_choose5)

        self.comboBox_1.addItems(['3840','2560','1920','1280','640'])
        self.comboBox_1.setEnabled(False)
        self.comboBox_1.activated[str].connect(self.click_comboBox1)

        self.filesButton.setToolTip("选择即将被处理的的视频文件,可单选、多选...")
        self.outButton.setToolTip("选择输出文件目录,处理后的文件将存在此目录...")

        self.txt2.setText(out_dir)

        self.filesButton.clicked.connect(self.filesButton_fuc)
        self.outButton.clicked.connect(self.outButton_fuc)

        self.stopButton.setEnabled(False)
        self.startButton.clicked.connect(self.startrun)
        self.stopButton.clicked.connect(self.stoprun)
        self.helpButton.clicked.connect(self.helpWin)
        self.quitButton.clicked.connect(self.quitWin)
        self.check_result.clicked.connect(self.checkresult)

#if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QtWidgets.QApplication(sys.argv)
MainWin = MainWin()
sys.exit(app.exec_())

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于视频清晰化,常见的方法是使用基于深度学习的超分辨率算法,其中比较流行的算法包括 SRCNN、ESPCN、FSRCNN、SRGAN 等。这些算法都需要使用 TensorFlow、PyTorch 等深度学习框架进行实现。 下面是一个使用 PyTorch 实现的视频清晰化代码示例: ```python import torch import torch.nn as nn import torch.nn.functional as F class SRCNN(nn.Module): def __init__(self): super(SRCNN, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=9, padding=4) self.conv2 = nn.Conv2d(64, 32, kernel_size=1, padding=0) self.conv3 = nn.Conv2d(32, 3, kernel_size=5, padding=2) def forward(self, x): x = F.relu(self.conv1(x)) x = F.relu(self.conv2(x)) x = self.conv3(x) return x model = SRCNN() model.load_state_dict(torch.load('srcnn.pth')) model.eval() video_path = 'video.mp4' cap = cv2.VideoCapture(video_path) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter('output.mp4', fourcc, 30.0, (1920, 1080)) while(cap.isOpened()): ret, frame = cap.read() if ret == True: frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = cv2.resize(frame, (960, 540)) frame = torch.from_numpy(frame).permute(2, 0, 1).float().unsqueeze(0) / 255.0 with torch.no_grad(): output = model(frame) output = output.squeeze().permute(1, 2, 0).mul(255.0).cpu().numpy().astype('uint8') output = cv2.cvtColor(output, cv2.COLOR_RGB2BGR) output = cv2.resize(output, (1920, 1080)) out.write(output) else: break cap.release() out.release() cv2.destroyAllWindows() ``` 这个示例代码使用了一个经典的超分辨率算法 SRCNN,首先加载预训练好的模型,然后读取视频文件并对每一帧进行处理,最后将处理后的帧写入输出视频文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值