利用cv2和PyQt5实现类似视频格式工厂的小项目
本博客展示利用cv2和PyQt5对视频,gif和帧图像进行相互转换,并制作成GUI,可对选择的视频,gif和帧图片进行选择。
项目地址:https://github.com/nickhuang1996/format-tools
兼容格式:视频mp4/avi/mkv,帧图像jpg
如何运行:运行main.py
目录
一、项目结构
二、文件格式
1.帧图像:5位数的jpg文件
2.视频文件:mp4
三、代码(按照项目从上往下的顺序)
----scripts
----Button
----__init__.py
----ButtonBase.py
-
from abc import ABCMeta, abstractmethod
-
from PyQt5.QtWidgets import *
-
-
-
class ButtonBase(metaclass=ABCMeta):
-
def __init__(self, MainForm):
-
self.btn = QPushButton(MainForm)
-
@abstractmethod
-
def get_btn(self):
-
pass
-
-
-
----ButtonSub.py
-
from scripts.Button.ButtonBase import ButtonBase
-
-
"""Choose images2gif"""
-
class Button_images2gif(ButtonBase):
-
-
def get_btn(self):
-
self.btn.setObjectName("btn_chooseDir")
-
self.btn.setText("images2gif")
-
return self.btn
-
-
-
"""Choose video2images"""
-
class Button_video2images(ButtonBase):
-
-
def get_btn(self):
-
self.btn.setObjectName("btn_chooseFile")
-
self.btn.setText("video2images")
-
return self.btn
-
-
-
"""Choose videos2image"""
-
class Button_videos2image(ButtonBase):
-
-
def get_btn(self):
-
self.btn.setObjectName("btn_chooseMutiFile")
-
self.btn.setText("videos2image")
-
return self.btn
-
-
-
"""Choose images2video"""
-
class Button_images2video(ButtonBase):
-
-
def get_btn(self):
-
self.btn.setObjectName("btn_saveFile")
-
self.btn.setText("images2video")
-
return self.btn
-
-
"""Choose videoscreenshot"""
-
class Button_videoscreenshot(ButtonBase):
-
-
def get_btn(self):
-
self.btn.setObjectName("btn_VideoScreenShot")
-
self.btn.setText("videoscreenshot")
-
return self.btn
----Form
----__init__.py
----MainForm.py
-
import sys
-
import os
-
from PyQt5.QtWidgets import *
-
from PyQt5.QtCore import *
-
-
class MainForm(QWidget):
-
def __init__(self, name='MainForm'):
-
super(MainForm, self).__init__()
-
self.setWindowTitle(name)
-
self.resize(300, 200)
-
"""Center"""
-
screen = QDesktopWidget().screenGeometry()
-
form = self.geometry()
-
x_move_step = (screen.width() - form.width()) // 2
-
y_move_step = (screen.height() - form.height()) // 2
-
self.move(x_move_step, y_move_step)
-
-
-
if __name__ == "__main__":
-
app = QApplication(sys.argv)
-
mainForm = MainForm('test QFileDialog')
-
mainForm.show()
-
sys.exit(app.exec_())
----SelectForm.py
-
from scripts.Form.MainForm import *
-
from scripts.Form.VideoScreenShotForm import VideoScreenShotForm
-
from scripts.transform_tools.video2image import video2image
-
from scripts.transform_tools.image2video import image2video
-
from scripts.transform_tools.image2gif import image2gif
-
from scripts.Button.ButtonSub import *
-
from scripts.utils.ProcessBar import ProcessBar
-
from scripts.utils.set_cwd import set_cwd
-
from scripts.utils.check_jpg_dir import check_jpg_dir
-
-
-
class SelectForm(MainForm):
-
def __init__(self, name='SelectForm', settings=set_cwd()):
-
super(SelectForm, self).__init__(name)
-
"""default fps"""
-
self.fps = 25
-
"""VideoScreenShotForm"""
-
self.VideoScreenShotForm = None
-
-
"""ProcessBar"""
-
self.ProcessBar = ProcessBar()
-
"""path for button"""
-
self.images_folder = settings['images_folder']
-
self.gif_folder = settings['gif_folder']
-
self.video_folder = settings['video_folder']
-
-
"""btn images2gif"""
-
self.btn_images2gif = Button_images2gif(self).get_btn()
-
-
"""btn video2images"""
-
self.btn_video2images = Button_video2images(self).get_btn()
-
-
"""btn videos2images"""
-
self.btn_videos2images = Button_videos2image(self).get_btn()
-
-
"""btn images2video"""
-
self.btn_images2video = Button_images2video(self).get_btn()
-
-
"""btn VideoScreenShot"""
-
self.btn_videoscreenshot = Button_videoscreenshot(self).get_btn()
-
"""layout"""
-
layout = QVBoxLayout()
-
layout.addWidget(self.btn_images2gif)
-
layout.addWidget(self.btn_video2images)
-
layout.addWidget(self.btn_videos2images)
-
layout.addWidget(self.btn_images2video)
-
layout.addWidget(self.btn_videoscreenshot)
-
layout.addWidget(self.ProcessBar.get_pbar_text())
-
layout.addWidget(self.ProcessBar.get_pbar())
-
self.setLayout(layout)
-
-
"""signal"""
-
self.btn_images2gif.clicked.connect(self.slot_btn_images2gif)
-
self.btn_video2images.clicked.connect(self.slot_btn_video2images)
-
self.btn_videos2images.clicked.connect(self.slot_btn_videos2images)
-
self.btn_images2video.clicked.connect(self.slot_btn_images2video)
-
self.btn_videoscreenshot.clicked.connect(self.slot_btn_videoscreenshot)
-
-
"""transform images to gif"""
-
def slot_btn_images2gif(self):
-
QMessageBox.information(self,
-
'Choose the frames directory',
-
"Choose the frames folder.")
-
check_flag = True
-
video_dir_choose = None
-
while check_flag:
-
video_dir_choose = QFileDialog.getExistingDirectory(self,
-
"select the load path",
-
self.images_folder['images2gif'])
-
self.images_folder['images2gif'] = video_dir_choose
-
-
if video_dir_choose == "":
-
print("\nCancel Select load directory")
-
return
-
"""check direction whether exists jpg files"""
-
check_flag = self.check_load_jpg_dir(video_dir_choose, "gif")
-
-
gifname_choose, file_type = QFileDialog.getSaveFileName(self,
-
"choose video path",
-
self.gif_folder['images2gif'],
-
"All Files (*);;"
-
"gif Files (*.gif);;")
-
self.gif_folder = os.path.abspath(gifname_choose)
-
-
if gifname_choose == "":
-
print("\nCancel Select video")
-
return
-
-
print("\nThe chosen images is:")
-
print(gifname_choose)
-
-
"""input fps"""
-
ok_pressed = True
-
while ok_pressed:
-
fps, ok_pressed = QInputDialog.getText(self,
-
"Fps Setting",
-
"Please input fps:",
-
QLineEdit.Normal,
-
str(self.fps))
-
if ok_pressed and fps.strip(): # erase head and tail blank
-
-
image2gif(self.ProcessBar,
-
video_dir_choose,
-
gifname_choose,
-
fps)
-
-
self.reset_pbar()
-
QMessageBox.information(self,
-
'Synthetic success!',
-
os.path.basename(gifname_choose) + ' Synthetic success!')
-
-
return
-
-
elif ok_pressed is False:
-
return
-
else:
-
QMessageBox.critical(self, 'Error', "please input fps and try again!")
-
-
"""transform video to images"""
-
def slot_btn_video2images(self):
-
QMessageBox.information(self,
-
'Choose the video',
-
"Choose the video")
-
videoname_choose, file_type = QFileDialog.getOpenFileName(self,
-
"choose video path",
-
self.video_folder['video2images'],
-
"All Files (*);;"
-
"Video Files (*.mp4);;"
-
"Video Files (*.avi);;"
-
"Video Files (*.mkv);;")
-
self.video_folder['video2images'] = os.path.abspath(videoname_choose)
-
if videoname_choose == "":
-
print("\nCancel Select video")
-
return
-
QMessageBox.information(self,
-
'Choose the save path',
-
"Choose the frames save path")
-
video_dir_choose = QFileDialog.getExistingDirectory(self,
-
"select the save path",
-
self.images_folder['video2images'])
-
self.images_folder['video2images'] = video_dir_choose
-
if video_dir_choose == "":
-
print("\nCancel Select save directory")
-
return
-
-
print("\nThe chosen video is:")
-
print(videoname_choose)
-
"""Select video and transform to images"""
-
image_save_folder, video_name, fps, total_finish_frame_number = video2image(self.ProcessBar,
-
videoname_choose,
-
video_dir_choose)
-
"""check direction whether exists jpg files"""
-
video_information = self.check_save_video_dir(image_save_folder,
-
video_name,
-
fps,
-
total_finish_frame_number)
-
-
self.reset_pbar()
-
QMessageBox.information(self, 'Save Results',
-
"video2images" + " has been finished!\n" +
-
video_information
-
)
-
-
"""transform videos to images"""
-
def slot_btn_videos2images(self):
-
QMessageBox.information(self,
-
'Choose the videos',
-
"Choose the videos")
-
videoname_chooses, file_type = QFileDialog.getOpenFileNames(self,
-
"choose videos path",
-
self.video_folder['videos2images'],
-
"All Files (*);;"
-
"Video Files (*.mp4);;"
-
"Video Files (*.avi);;"
-
"Video Files (*.mkv);;")
-
self.video_folder['videos2images'] = os.path.abspath(videoname_chooses[0])
-
if len(videoname_chooses) == 0:
-
print("\nCancel Select videos")
-
return
-
QMessageBox.information(self,
-
'Choose the save path',
-
"Choose the frames save path")
-
video_dir_choose = QFileDialog.getExistingDirectory(self,
-
"select the save path",
-
self.images_folder['videos2images'])
-
self.images_folder['videos2images'] = video_dir_choose
-
if video_dir_choose == "":
-
print("\nCancel Select save directory")
-
return
-
print("\nThe chosen videos are:")
-
-
"""Select videos and transform to images"""
-
video_informations = ''
-
for videoname_choose in videoname_chooses:
-
print(videoname_choose)
-
-
image_save_folder, video_name, fps, total_finish_frame_number = video2image(self.ProcessBar,
-
videoname_choose,
-
video_dir_choose)
-
"""check direction whether exists jpg files"""
-
video_information = self.check_save_video_dir(image_save_folder,
-
video_name,
-
fps,
-
total_finish_frame_number)
-
video_informations += video_information
-
-
self.reset_pbar()
-
QMessageBox.information(self, 'Save Results',
-
"video2images" + " has been finished!\n" +
-
video_informations
-
)
-
-
"""transform images to video"""
-
def slot_btn_images2video(self):
-
QMessageBox.information(self,
-
'Choose the frames directory',
-
"Choose the frames folder.")
-
check_flag = True
-
video_dir_choose = None
-
while check_flag:
-
video_dir_choose = QFileDialog.getExistingDirectory(self,
-
"select the load path",
-
self.images_folder['images2video'])
-
self.images_folder['images2video'] = video_dir_choose
-
if video_dir_choose == "":
-
print("\nCancel Select load directory")
-
return
-
"""check direction whether exists jpg files"""
-
check_flag = self.check_load_jpg_dir(video_dir_choose, "video")
-
-
videoname_choose, file_type = QFileDialog.getSaveFileName(self,
-
"choose video path",
-
self.video_folder['images2video'],
-
"All Files (*);;"
-
"Video Files (*.mp4);;"
-
"Video Files (*.avi);;"
-
"Video Files (*.mkv);;")
-
self.video_folder['images2video'] = os.path.abspath(videoname_choose)
-
if videoname_choose == "":
-
print("\nCancel Select video")
-
return
-
-
print("\nThe chosen images is:")
-
print(videoname_choose)
-
-
"""input fps"""
-
ok_pressed = True
-
while ok_pressed:
-
fps, ok_pressed = QInputDialog.getText(self,
-
"Fps Setting",
-
"Please input fps:",
-
QLineEdit.Normal,
-
str(self.fps))
-
if ok_pressed and fps.strip(): # erase head and tail blank
-
-
image2video(self.ProcessBar,
-
videoname_choose,
-
video_dir_choose,
-
fps)
-
-
self.reset_pbar()
-
QMessageBox.information(self,
-
'Synthetic success!',
-
os.path.basename(videoname_choose) + ' Synthetic success!')
-
return
-
-
elif ok_pressed is False:
-
return
-
else:
-
QMessageBox.critical(self, 'Error', "please input fps and try again!")
-
-
"""video screen shot"""
-
def slot_btn_videoscreenshot(self):
-
self.VideoScreenShotForm = VideoScreenShotForm()
-
self.VideoScreenShotForm.show()
-
print("VideoScreenShotForm Start...\n")
-
return
-
-
-
-
-
def check_load_jpg_dir(self, video_dir_choose, target):
-
"""check direction whether exists jpg files"""
-
check_flag, frames_number = check_jpg_dir(video_dir_choose)
-
if check_flag is True and frames_number is 0:
-
QMessageBox.critical(self, 'Error', "No jpg file was found, please choose the right folder!!")
-
elif check_flag is True and frames_number is 1:
-
QMessageBox.critical(self, 'Error', "Only 1 jpg file was found, please choose the right folder!!")
-
else:
-
check_flag = False
-
QMessageBox.information(self, 'Frames Number',
-
str(frames_number) + " jpg file were found, continue to choose " + target + " path.")
-
return check_flag
-
-
def check_save_video_dir(self, image_save_folder, video_name, fps, total_finish_frame_number):
-
"""check direction whether exists jpg files"""
-
_, video_number = check_jpg_dir(image_save_folder)
-
video_information = video_name + ':\n' + \
-
str(total_finish_frame_number) + ' images have been transformed.\n' + \
-
"fps :" + str(fps) + '\n' + '\n'
-
return video_information
-
-
def reset_pbar(self):
-
self.ProcessBar.reset_pbar()
----VideoScreenShotForm.py
-
from scripts.Form.MainForm import *
-
from scripts.utils.set_cwd import set_cwd
-
from scripts.transform_tools.video_screen_shot import video_screen_shot
-
from scripts.utils.ProcessBar import ProcessBar
-
-
-
class VideoScreenShotForm(MainForm):
-
def __init__(self, name='VideoScreenShotForm', settings=set_cwd()):
-
super(VideoScreenShotForm, self).__init__(name)
-
-
"""path for button"""
-
self.video_folder = settings['video_folder']
-
"""ProcessBar"""
-
self.ProcessBar = ProcessBar()
-
"""grid layout"""
-
grid = QGridLayout()
-
self.grid = grid
-
self.setLayout(self.grid)
-
-
"""location contents set"""
-
screen_shot_set =[
-
'left-up-x', 'right-bottom-x',
-
' ', ' ',
-
'left-up-y', 'right-bottom-y',
-
' ', ' ',
-
'OK', '',
-
'process:', '',
-
'pbar', ''
-
]
-
-
LineEdit_index = 0
-
LineEdit_content = ['left-up-x', 'right-bottom-x', 'left-up-y', 'right-bottom-y']
-
"""locations set"""
-
positions = [(i, j) for i in range(7) for j in range(2)]
-
for pos, name in zip(positions, screen_shot_set):
-
if name == '':
-
continue
-
elif name is 'OK':
-
btn = QPushButton(name)
-
btn.setObjectName(name)
-
btn.clicked.connect(self.slot_btn_video_screen_shot)
-
grid.addWidget(btn, *pos, 1, 2)
-
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
-
elif name is 'process:':
-
pbar_text = self.ProcessBar.get_pbar_text()
-
pbar_text.setObjectName(name)
-
grid.addWidget(pbar_text, *pos, 1, 2)
-
pbar_text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
-
elif name is 'pbar':
-
pbar_loc = self.ProcessBar.get_pbar()
-
pbar_loc.setObjectName(name)
-
grid.addWidget(pbar_loc, *pos, 1, 2)
-
pbar_loc.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
-
elif name is ' ':
-
loc = QLineEdit()
-
loc.setObjectName(LineEdit_content[LineEdit_index])
-
grid.addWidget(loc, *pos)
-
LineEdit_index += 1
-
else:
-
loc_label = QLabel(name)
-
loc_label.setObjectName(name)
-
grid.addWidget(loc_label, *pos)
-
-
self.left_up_x = self.findChild(QLineEdit, 'left-up-x')
-
self.left_up_y = self.findChild(QLineEdit, 'left-up-y')
-
self.right_bottom_x = self.findChild(QLineEdit, 'right-bottom-x')
-
self.right_bottom_y = self.findChild(QLineEdit, 'right-bottom-y')
-
"""default 1920x1080"""
-
self.left_up_x.setText("0")
-
self.left_up_y.setText("0")
-
self.right_bottom_x.setText("1920")
-
self.right_bottom_y.setText("1080")
-
-
self.new_frame = [[], [], [], []]
-
-
def slot_btn_video_screen_shot(self):
-
self.new_frame = self.get_new_frame()
-
QMessageBox.information(self,
-
'Choose the video',
-
"Choose the video")
-
videoname_choose, file_type = QFileDialog.getOpenFileName(self,
-
"choose video path",
-
self.video_folder['videoscreenshotload'],
-
"All Files (*);;"
-
"Video Files (*.mp4);;"
-
"Video Files (*.avi);;"
-
"Video Files (*.mkv);;")
-
self.video_folder['videoscreenshotload'] = os.path.abspath(videoname_choose)
-
if videoname_choose == "":
-
print("\nCancel Select video")
-
return
-
QMessageBox.information(self,
-
'Choose the new video name',
-
"Choose the new video name")
-
videonewname_choose, file_type = QFileDialog.getSaveFileName(self,
-
"choose video path",
-
self.video_folder['videoscreenshotsave'],
-
"All Files (*);;"
-
"Video Files (*.mp4);;"
-
"Video Files (*.avi);;"
-
"Video Files (*.mkv);;")
-
self.video_folder['videoscreenshotsave'] = os.path.abspath(videoname_choose)
-
if videonewname_choose == "":
-
print("\nCancel Select new video")
-
return
-
-
print("\nThe chosen video is:")
-
print(videoname_choose)
-
"""Select video and screen shot"""
-
video_screen_shot(self.ProcessBar,
-
videoname_choose,
-
videonewname_choose,
-
self.new_frame)
-
self.reset_pbar()
-
QMessageBox.information(self, 'Save Results',
-
"video screen shot" + " has been finished!\n"
-
)
-
self.close()
-
return
-
-
def get_new_frame(self):
-
self.new_frame[0] = int(self.left_up_y.text())
-
self.new_frame[1] = int(self.right_bottom_y.text())
-
self.new_frame[2] = int(self.left_up_x.text())
-
self.new_frame[3] = int(self.right_bottom_x.text())
-
return self.new_frame
-
-
def reset_pbar(self):
-
self.ProcessBar.reset_pbar()
----transform_tools
----__init__.py
----image2gif.py
-
import os
-
import numpy as np
-
from PIL import Image, ImageDraw
-
import imageio
-
import inspect
-
-
-
def add_text_to_image(image, text, font=None):
-
rgba_image = image.convert('RGBA')
-
text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))
-
image_draw = ImageDraw.Draw(text_overlay)
-
-
text_size_x, text_size_y = image_draw.textsize(text, font=font)
-
-
print(rgba_image)
-
"""set text location"""
-
text_xy = (rgba_image.size[0] - text_size_x, rgba_image.size[1] - text_size_y)
-
"""set text color and transparency"""
-
image_draw.text(text_xy, text, font=font, fill=(255, 0, 0, 800))
-
-
image_with_text = Image.alpha_composite(rgba_image, text_overlay)
-
-
return image_with_text
-
-
-
def image2gif(ProcessBar, load_path, gif_name, fps):
-
"""set the func name on pbar text"""
-
ProcessBar.set_Text(inspect.stack()[0][3])
-
"""int fps"""
-
fps = int(fps)
-
"""image name save format"""
-
image_format = '{:05d}{:s}.jpg'
-
"""gif basename"""
-
gif_basename = os.path.basename(gif_name)
-
images = os.listdir(load_path)
-
"""duration"""
-
duration = 1/fps
-
"""the index of the image that has been processed"""
-
image_index = 1
-
"""for store each frame image"""
-
frames = []
-
ProcessBar.set_zero()
-
for image in range(len(images)):
-
jpgfile = str(load_path + '/' + image_format.format(image_index, ''))
-
frame = Image.open(jpgfile)
-
frame = add_text_to_image(frame, gif_basename)
-
frames.append(np.array(frame))
-
print(image_index)
-
image_index += 1
-
ProcessBar.set_Value(image_index, len(images), ratio=90)
-
if image_index == len(images):
-
ProcessBar.set_Text("Please wait ... it may take a few minutes...")
-
print("Please wait ... it may take a few minutes...")
-
-
imageio.mimsave(gif_name, frames, 'GIF', duration=duration) # duration = 1/fps
-
ProcessBar.set_max()
-
print(gif_basename, 'Synthetic success!')
----image2video.py
-
import cv2
-
import os
-
from PIL import Image
-
import inspect
-
-
-
def image2video(ProcessBar, video_new_path, load_path, fps):
-
"""set the func name on pbar text"""
-
ProcessBar.set_Text(inspect.stack()[0][3])
-
fps = int(fps)
-
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
-
"""images path"""
-
images = os.listdir(load_path)
-
im = Image.open(load_path + '/' + images[0])
-
vw = cv2.VideoWriter(video_new_path, fourcc, fps, im.size)
-
"""image name save format"""
-
image_format = '{:05d}{:s}.jpg'
-
"""the index of the image that has been processed"""
-
image_index = 1
-
-
ProcessBar.set_zero()
-
for image in range(len(images)):
-
jpgfile = str(load_path + '/' + image_format.format(image_index, ''))
-
try:
-
frame = cv2.imread(jpgfile)
-
vw.write(frame)
-
print("image ", str(image_index), " has been processed.")
-
image_index += 1
-
ProcessBar.set_Value(image_index, len(images))
-
-
except Exception as exc:
-
print(jpgfile, exc)
-
vw.release()
-
print(video_new_path, 'Synthetic success!')
----video2image.py
-
import os
-
import cv2
-
import inspect
-
-
-
def video2image(ProcessBar, video_path, save_path):
-
"""set the func name on pbar text"""
-
ProcessBar.set_Text(inspect.stack()[0][3])
-
"""select the video"""
-
vc = cv2.VideoCapture(video_path)
-
"""image name save format"""
-
image_format = '{:05d}{:s}.jpg'
-
"""basename"""
-
video_name = os.path.basename(video_path)
-
"""image save folder"""
-
image_save_folder = save_path + '/' + str(video_name.split('.')[0]) + '_' + str(video_name.split('.')[-1])
-
if not os.path.exists(image_save_folder):
-
os.mkdir(image_save_folder)
-
assert os.path.exists(image_save_folder), 'Error: Invalid save path !'
-
"""the index of the image that has been processed"""
-
image_index = 1
-
"""get the total frame number"""
-
total_frame_number = vc.get(cv2.CAP_PROP_FRAME_COUNT)
-
"""get fps"""
-
fps = vc.get(cv2.CAP_PROP_FPS)
-
"""Start to write..."""
-
print("\nStart to Write...\n")
-
ProcessBar.set_zero()
-
while (image_index - 1) < total_frame_number:
-
ret, frame = vc.read()
-
if ret:
-
cv2.imwrite(image_save_folder + '/' + image_format.format(image_index, ''), frame)
-
cv2.waitKey(1)
-
print("image ", str(image_index), " has been processed.")
-
image_index += 1
-
ProcessBar.set_Value(image_index, total_frame_number)
-
elif frame is None:
-
print("Write process is at the end.\n")
-
ProcessBar.set_zero()
-
return
-
else:
-
print("Cannot process the image ", str(image_index), "! Write to the image failed! \n")
-
ProcessBar.set_zero()
-
return
-
print("Write process has been finished!!\n")
-
"""the total number of the image"""
-
print(video_name, ':', image_index - 1, ' images have been transformed.')
-
"""release"""
-
vc.release()
-
return image_save_folder, video_name, fps, image_index - 1
----video_screen_shot.py
-
import os
-
import cv2
-
import inspect
-
-
-
def video_screen_shot(ProcessBar, video_path, video_new_path, new_frame):
-
"""set the func name on pbar text"""
-
ProcessBar.set_Text(inspect.stack()[0][3])
-
"""select the video"""
-
vc = cv2.VideoCapture(video_path)
-
"""basename"""
-
video_name = os.path.basename(video_path)
-
"""judge the video is opened"""
-
if vc.isOpened():
-
print(video_name, "can be opened")
-
else:
-
print("video has been failed to open!")
-
return
-
-
"""get fourcc"""
-
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
-
"""get fps"""
-
fps = vc.get(cv2.CAP_PROP_FPS)
-
"""video width and height"""
-
video_size = (int(new_frame[3] - new_frame[2]), int(new_frame[1] - new_frame[0]))
-
"""VideoWriter"""
-
if os.path.exists(video_new_path):
-
os.remove(video_new_path)
-
vw = cv2.VideoWriter(video_new_path, fourcc, fps, video_size)
-
"""the index of the frame that has been processed"""
-
image_index = 1
-
"""get the total frame number"""
-
total_frame_number = vc.get(cv2.CAP_PROP_FRAME_COUNT)
-
"""get the total video time"""
-
total_time = vc.get(cv2.CAP_PROP_POS_MSEC)
-
"""Start to premiere..."""
-
print("\nStart to premiere...\n")
-
ProcessBar.set_zero()
-
while (image_index - 1) < total_frame_number:
-
ret, frame = vc.read()
-
frame = frame[new_frame[0]:new_frame[1], new_frame[2]:new_frame[3]]
-
vw.write(frame)
-
print(image_index)
-
image_index += 1
-
ProcessBar.set_Value(image_index, total_frame_number)
-
print("Screen Shot process has been finished!!\n")
-
"""the total number of the image"""
-
print(video_name, ':', image_index - 1, ' images have been transformed.')
-
"""release"""
-
vc.release()
-
vw.release()
-
return video_new_path, video_name, fps, image_index - 1
----utils
----__init__.py
----check_jpg_dir.py
-
import os
-
-
-
def check_jpg_dir(video_dir_choose):
-
frames = os.listdir(video_dir_choose)
-
frames_number = 0
-
for frame in frames:
-
if frame.endswith('jpg'):
-
frames_number += 1
-
if frames_number == 0:
-
check_flag = True
-
elif frames_number == 1:
-
check_flag = True
-
else:
-
check_flag = False
-
print(frames_number, " images has been chosen.")
-
return check_flag, frames_number
----ProcessBar.py
-
from PyQt5.QtWidgets import *
-
-
-
class ProcessBar(object):
-
def __init__(self):
-
"""ProcessBar"""
-
self.pbar = QProgressBar()
-
self.pbar_text = QLabel()
-
self.pbar_text.setText("Process :")
-
-
def get_pbar(self):
-
return self.pbar
-
-
def get_pbar_text(self):
-
return self.pbar_text
-
-
def set_zero(self):
-
self.pbar.setValue(0)
-
-
def set_max(self):
-
self.pbar.setValue(100)
-
-
def set_Value(self, index, length, ratio=100):
-
self.pbar.setValue((index - 1) / length * ratio)
-
-
def set_Text(self, text):
-
self.pbar_text.setText(str(text) + ":")
-
-
def reset_pbar(self):
-
self.pbar_text.setText("Process :")
-
self.pbar.setValue(0)
----set_cwd.py
-
import os
-
-
def set_cwd():
-
cwd = os.getcwd()
-
-
"""path for each button"""
-
images_folder = {}
-
images_folder['images2gif'] = cwd
-
images_folder['video2images'] = cwd
-
images_folder['videos2images'] = cwd
-
images_folder['images2video'] = cwd
-
-
gif_folder = {}
-
gif_folder['images2gif'] = cwd
-
-
video_folder = {}
-
video_folder['video2images'] = cwd
-
video_folder['videos2images'] = cwd
-
video_folder['images2video'] = cwd
-
video_folder['videoscreenshotload'] = cwd
-
video_folder['videoscreenshotsave'] = cwd
-
"""The whole settings"""
-
settings = {}
-
settings['images_folder'] = images_folder
-
settings['gif_folder'] = gif_folder
-
settings['video_folder'] = video_folder
-
-
return settings
-
-
-
if __name__ == '__main__':
-
set_cwd()
----__init__.py
----main.py
-
from scripts.Form.SelectForm import *
-
-
if __name__ == '__main__':
-
app = QApplication(sys.argv)
-
selectform = SelectForm("format tools")
-
selectform.show()
-
sys.exit(app.exec_())
*四、界面演示
运行main.py,然后点击各个按钮
1.帧图像转gif——images2gif
(1)选择已经编好序号的图片文件夹(五位数编号)
(2)例如选择的帧一共是349张,选择存放的gif路径
(3)输入帧率fps,博主这里默认设置是25
(4)稍等片刻,gif生成完成
2.视频转帧图像——video2images
(1)选择视频
(2)选择视频帧存放的路径,即文件夹,选择完成后会自动在该文件夹下新建一个同名的文件夹,存储帧图像形式是五位数
(3)等待完成
(4)显示结果
3.帧图像转视频——images2video
(1)选择帧图像文件夹
(2)继续选择存放的视频文件,命名新的文件名
(3)输入帧率fps,默认为25
(4)等待完成
(5)视频生成完成(mp4,avi,mkv)
4.视频画面区域裁剪——videoscreenshot
(1)对所选的视频进行画面统一裁剪,默认(1920×1080),具体的裁剪区域可根据需要进行修改
(2)改成只有右半边
(3)选择要裁剪的视频
(3)保存新的视频
(4)等待完成
(5)生成新视频
5.多个视频转帧图像——videos2images
这个就是在选择视频的时候ctrl或者shift选择多个视频,和单个视频转帧图像相同,每个视频生成对应名称的文件夹存放帧图片,不多赘述。
总之,先做到这里,大家可以在此基础上拿走自己想要的函数进行修改,如果有能力的也可以分享自己在这个项目中添加的新功能~
文章来源: nickhuang1996.blog.csdn.net,作者:悲恋花丶无心之人,版权归原作者所有,如需转载,请联系作者。
原文链接:nickhuang1996.blog.csdn.net/article/details/90905842
- 点赞
- 收藏
- 关注作者
评论(0)