利用cv2和PyQt5实现类似视频格式工厂的小项目

举报
悲恋花丶无心之人 发表于 2021/02/03 02:35:51 2021/02/03
【摘要】 本博客展示利用cv2和PyQt5对视频,gif和帧图像进行相互转换,并制作成GUI,可对选择的视频,gif和帧图片进行选择。 项目地址:https://github.com/nickhuang1996/format-tools 兼容格式:视频mp4/avi/mkv,帧图像jpg 如何运行:运行main.py 目录 一、项目结构 二、图像格式(五位数) ...

本博客展示利用cv2PyQt5视频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


  
  1. from abc import ABCMeta, abstractmethod
  2. from PyQt5.QtWidgets import *
  3. class ButtonBase(metaclass=ABCMeta):
  4. def __init__(self, MainForm):
  5. self.btn = QPushButton(MainForm)
  6. @abstractmethod
  7. def get_btn(self):
  8. pass

            ----ButtonSub.py


  
  1. from scripts.Button.ButtonBase import ButtonBase
  2. """Choose images2gif"""
  3. class Button_images2gif(ButtonBase):
  4. def get_btn(self):
  5. self.btn.setObjectName("btn_chooseDir")
  6. self.btn.setText("images2gif")
  7. return self.btn
  8. """Choose video2images"""
  9. class Button_video2images(ButtonBase):
  10. def get_btn(self):
  11. self.btn.setObjectName("btn_chooseFile")
  12. self.btn.setText("video2images")
  13. return self.btn
  14. """Choose videos2image"""
  15. class Button_videos2image(ButtonBase):
  16. def get_btn(self):
  17. self.btn.setObjectName("btn_chooseMutiFile")
  18. self.btn.setText("videos2image")
  19. return self.btn
  20. """Choose images2video"""
  21. class Button_images2video(ButtonBase):
  22. def get_btn(self):
  23. self.btn.setObjectName("btn_saveFile")
  24. self.btn.setText("images2video")
  25. return self.btn
  26. """Choose videoscreenshot"""
  27. class Button_videoscreenshot(ButtonBase):
  28. def get_btn(self):
  29. self.btn.setObjectName("btn_VideoScreenShot")
  30. self.btn.setText("videoscreenshot")
  31. return self.btn

      ----Form

            ----__init__.py

            ----MainForm.py


  
  1. import sys
  2. import os
  3. from PyQt5.QtWidgets import *
  4. from PyQt5.QtCore import *
  5. class MainForm(QWidget):
  6. def __init__(self, name='MainForm'):
  7. super(MainForm, self).__init__()
  8. self.setWindowTitle(name)
  9. self.resize(300, 200)
  10. """Center"""
  11. screen = QDesktopWidget().screenGeometry()
  12. form = self.geometry()
  13. x_move_step = (screen.width() - form.width()) // 2
  14. y_move_step = (screen.height() - form.height()) // 2
  15. self.move(x_move_step, y_move_step)
  16. if __name__ == "__main__":
  17. app = QApplication(sys.argv)
  18. mainForm = MainForm('test QFileDialog')
  19. mainForm.show()
  20. sys.exit(app.exec_())

            ----SelectForm.py


  
  1. from scripts.Form.MainForm import *
  2. from scripts.Form.VideoScreenShotForm import VideoScreenShotForm
  3. from scripts.transform_tools.video2image import video2image
  4. from scripts.transform_tools.image2video import image2video
  5. from scripts.transform_tools.image2gif import image2gif
  6. from scripts.Button.ButtonSub import *
  7. from scripts.utils.ProcessBar import ProcessBar
  8. from scripts.utils.set_cwd import set_cwd
  9. from scripts.utils.check_jpg_dir import check_jpg_dir
  10. class SelectForm(MainForm):
  11. def __init__(self, name='SelectForm', settings=set_cwd()):
  12. super(SelectForm, self).__init__(name)
  13. """default fps"""
  14. self.fps = 25
  15. """VideoScreenShotForm"""
  16. self.VideoScreenShotForm = None
  17. """ProcessBar"""
  18. self.ProcessBar = ProcessBar()
  19. """path for button"""
  20. self.images_folder = settings['images_folder']
  21. self.gif_folder = settings['gif_folder']
  22. self.video_folder = settings['video_folder']
  23. """btn images2gif"""
  24. self.btn_images2gif = Button_images2gif(self).get_btn()
  25. """btn video2images"""
  26. self.btn_video2images = Button_video2images(self).get_btn()
  27. """btn videos2images"""
  28. self.btn_videos2images = Button_videos2image(self).get_btn()
  29. """btn images2video"""
  30. self.btn_images2video = Button_images2video(self).get_btn()
  31. """btn VideoScreenShot"""
  32. self.btn_videoscreenshot = Button_videoscreenshot(self).get_btn()
  33. """layout"""
  34. layout = QVBoxLayout()
  35. layout.addWidget(self.btn_images2gif)
  36. layout.addWidget(self.btn_video2images)
  37. layout.addWidget(self.btn_videos2images)
  38. layout.addWidget(self.btn_images2video)
  39. layout.addWidget(self.btn_videoscreenshot)
  40. layout.addWidget(self.ProcessBar.get_pbar_text())
  41. layout.addWidget(self.ProcessBar.get_pbar())
  42. self.setLayout(layout)
  43. """signal"""
  44. self.btn_images2gif.clicked.connect(self.slot_btn_images2gif)
  45. self.btn_video2images.clicked.connect(self.slot_btn_video2images)
  46. self.btn_videos2images.clicked.connect(self.slot_btn_videos2images)
  47. self.btn_images2video.clicked.connect(self.slot_btn_images2video)
  48. self.btn_videoscreenshot.clicked.connect(self.slot_btn_videoscreenshot)
  49. """transform images to gif"""
  50. def slot_btn_images2gif(self):
  51. QMessageBox.information(self,
  52. 'Choose the frames directory',
  53. "Choose the frames folder.")
  54. check_flag = True
  55. video_dir_choose = None
  56. while check_flag:
  57. video_dir_choose = QFileDialog.getExistingDirectory(self,
  58. "select the load path",
  59. self.images_folder['images2gif'])
  60. self.images_folder['images2gif'] = video_dir_choose
  61. if video_dir_choose == "":
  62. print("\nCancel Select load directory")
  63. return
  64. """check direction whether exists jpg files"""
  65. check_flag = self.check_load_jpg_dir(video_dir_choose, "gif")
  66. gifname_choose, file_type = QFileDialog.getSaveFileName(self,
  67. "choose video path",
  68. self.gif_folder['images2gif'],
  69. "All Files (*);;"
  70. "gif Files (*.gif);;")
  71. self.gif_folder = os.path.abspath(gifname_choose)
  72. if gifname_choose == "":
  73. print("\nCancel Select video")
  74. return
  75. print("\nThe chosen images is:")
  76. print(gifname_choose)
  77. """input fps"""
  78. ok_pressed = True
  79. while ok_pressed:
  80. fps, ok_pressed = QInputDialog.getText(self,
  81. "Fps Setting",
  82. "Please input fps:",
  83. QLineEdit.Normal,
  84. str(self.fps))
  85. if ok_pressed and fps.strip(): # erase head and tail blank
  86. image2gif(self.ProcessBar,
  87. video_dir_choose,
  88. gifname_choose,
  89. fps)
  90. self.reset_pbar()
  91. QMessageBox.information(self,
  92. 'Synthetic success!',
  93. os.path.basename(gifname_choose) + ' Synthetic success!')
  94. return
  95. elif ok_pressed is False:
  96. return
  97. else:
  98. QMessageBox.critical(self, 'Error', "please input fps and try again!")
  99. """transform video to images"""
  100. def slot_btn_video2images(self):
  101. QMessageBox.information(self,
  102. 'Choose the video',
  103. "Choose the video")
  104. videoname_choose, file_type = QFileDialog.getOpenFileName(self,
  105. "choose video path",
  106. self.video_folder['video2images'],
  107. "All Files (*);;"
  108. "Video Files (*.mp4);;"
  109. "Video Files (*.avi);;"
  110. "Video Files (*.mkv);;")
  111. self.video_folder['video2images'] = os.path.abspath(videoname_choose)
  112. if videoname_choose == "":
  113. print("\nCancel Select video")
  114. return
  115. QMessageBox.information(self,
  116. 'Choose the save path',
  117. "Choose the frames save path")
  118. video_dir_choose = QFileDialog.getExistingDirectory(self,
  119. "select the save path",
  120. self.images_folder['video2images'])
  121. self.images_folder['video2images'] = video_dir_choose
  122. if video_dir_choose == "":
  123. print("\nCancel Select save directory")
  124. return
  125. print("\nThe chosen video is:")
  126. print(videoname_choose)
  127. """Select video and transform to images"""
  128. image_save_folder, video_name, fps, total_finish_frame_number = video2image(self.ProcessBar,
  129. videoname_choose,
  130. video_dir_choose)
  131. """check direction whether exists jpg files"""
  132. video_information = self.check_save_video_dir(image_save_folder,
  133. video_name,
  134. fps,
  135. total_finish_frame_number)
  136. self.reset_pbar()
  137. QMessageBox.information(self, 'Save Results',
  138. "video2images" + " has been finished!\n" +
  139. video_information
  140. )
  141. """transform videos to images"""
  142. def slot_btn_videos2images(self):
  143. QMessageBox.information(self,
  144. 'Choose the videos',
  145. "Choose the videos")
  146. videoname_chooses, file_type = QFileDialog.getOpenFileNames(self,
  147. "choose videos path",
  148. self.video_folder['videos2images'],
  149. "All Files (*);;"
  150. "Video Files (*.mp4);;"
  151. "Video Files (*.avi);;"
  152. "Video Files (*.mkv);;")
  153. self.video_folder['videos2images'] = os.path.abspath(videoname_chooses[0])
  154. if len(videoname_chooses) == 0:
  155. print("\nCancel Select videos")
  156. return
  157. QMessageBox.information(self,
  158. 'Choose the save path',
  159. "Choose the frames save path")
  160. video_dir_choose = QFileDialog.getExistingDirectory(self,
  161. "select the save path",
  162. self.images_folder['videos2images'])
  163. self.images_folder['videos2images'] = video_dir_choose
  164. if video_dir_choose == "":
  165. print("\nCancel Select save directory")
  166. return
  167. print("\nThe chosen videos are:")
  168. """Select videos and transform to images"""
  169. video_informations = ''
  170. for videoname_choose in videoname_chooses:
  171. print(videoname_choose)
  172. image_save_folder, video_name, fps, total_finish_frame_number = video2image(self.ProcessBar,
  173. videoname_choose,
  174. video_dir_choose)
  175. """check direction whether exists jpg files"""
  176. video_information = self.check_save_video_dir(image_save_folder,
  177. video_name,
  178. fps,
  179. total_finish_frame_number)
  180. video_informations += video_information
  181. self.reset_pbar()
  182. QMessageBox.information(self, 'Save Results',
  183. "video2images" + " has been finished!\n" +
  184. video_informations
  185. )
  186. """transform images to video"""
  187. def slot_btn_images2video(self):
  188. QMessageBox.information(self,
  189. 'Choose the frames directory',
  190. "Choose the frames folder.")
  191. check_flag = True
  192. video_dir_choose = None
  193. while check_flag:
  194. video_dir_choose = QFileDialog.getExistingDirectory(self,
  195. "select the load path",
  196. self.images_folder['images2video'])
  197. self.images_folder['images2video'] = video_dir_choose
  198. if video_dir_choose == "":
  199. print("\nCancel Select load directory")
  200. return
  201. """check direction whether exists jpg files"""
  202. check_flag = self.check_load_jpg_dir(video_dir_choose, "video")
  203. videoname_choose, file_type = QFileDialog.getSaveFileName(self,
  204. "choose video path",
  205. self.video_folder['images2video'],
  206. "All Files (*);;"
  207. "Video Files (*.mp4);;"
  208. "Video Files (*.avi);;"
  209. "Video Files (*.mkv);;")
  210. self.video_folder['images2video'] = os.path.abspath(videoname_choose)
  211. if videoname_choose == "":
  212. print("\nCancel Select video")
  213. return
  214. print("\nThe chosen images is:")
  215. print(videoname_choose)
  216. """input fps"""
  217. ok_pressed = True
  218. while ok_pressed:
  219. fps, ok_pressed = QInputDialog.getText(self,
  220. "Fps Setting",
  221. "Please input fps:",
  222. QLineEdit.Normal,
  223. str(self.fps))
  224. if ok_pressed and fps.strip(): # erase head and tail blank
  225. image2video(self.ProcessBar,
  226. videoname_choose,
  227. video_dir_choose,
  228. fps)
  229. self.reset_pbar()
  230. QMessageBox.information(self,
  231. 'Synthetic success!',
  232. os.path.basename(videoname_choose) + ' Synthetic success!')
  233. return
  234. elif ok_pressed is False:
  235. return
  236. else:
  237. QMessageBox.critical(self, 'Error', "please input fps and try again!")
  238. """video screen shot"""
  239. def slot_btn_videoscreenshot(self):
  240. self.VideoScreenShotForm = VideoScreenShotForm()
  241. self.VideoScreenShotForm.show()
  242. print("VideoScreenShotForm Start...\n")
  243. return
  244. def check_load_jpg_dir(self, video_dir_choose, target):
  245. """check direction whether exists jpg files"""
  246. check_flag, frames_number = check_jpg_dir(video_dir_choose)
  247. if check_flag is True and frames_number is 0:
  248. QMessageBox.critical(self, 'Error', "No jpg file was found, please choose the right folder!!")
  249. elif check_flag is True and frames_number is 1:
  250. QMessageBox.critical(self, 'Error', "Only 1 jpg file was found, please choose the right folder!!")
  251. else:
  252. check_flag = False
  253. QMessageBox.information(self, 'Frames Number',
  254. str(frames_number) + " jpg file were found, continue to choose " + target + " path.")
  255. return check_flag
  256. def check_save_video_dir(self, image_save_folder, video_name, fps, total_finish_frame_number):
  257. """check direction whether exists jpg files"""
  258. _, video_number = check_jpg_dir(image_save_folder)
  259. video_information = video_name + ':\n' + \
  260. str(total_finish_frame_number) + ' images have been transformed.\n' + \
  261. "fps :" + str(fps) + '\n' + '\n'
  262. return video_information
  263. def reset_pbar(self):
  264. self.ProcessBar.reset_pbar()

            ----VideoScreenShotForm.py


  
  1. from scripts.Form.MainForm import *
  2. from scripts.utils.set_cwd import set_cwd
  3. from scripts.transform_tools.video_screen_shot import video_screen_shot
  4. from scripts.utils.ProcessBar import ProcessBar
  5. class VideoScreenShotForm(MainForm):
  6. def __init__(self, name='VideoScreenShotForm', settings=set_cwd()):
  7. super(VideoScreenShotForm, self).__init__(name)
  8. """path for button"""
  9. self.video_folder = settings['video_folder']
  10. """ProcessBar"""
  11. self.ProcessBar = ProcessBar()
  12. """grid layout"""
  13. grid = QGridLayout()
  14. self.grid = grid
  15. self.setLayout(self.grid)
  16. """location contents set"""
  17. screen_shot_set =[
  18. 'left-up-x', 'right-bottom-x',
  19. ' ', ' ',
  20. 'left-up-y', 'right-bottom-y',
  21. ' ', ' ',
  22. 'OK', '',
  23. 'process:', '',
  24. 'pbar', ''
  25. ]
  26. LineEdit_index = 0
  27. LineEdit_content = ['left-up-x', 'right-bottom-x', 'left-up-y', 'right-bottom-y']
  28. """locations set"""
  29. positions = [(i, j) for i in range(7) for j in range(2)]
  30. for pos, name in zip(positions, screen_shot_set):
  31. if name == '':
  32. continue
  33. elif name is 'OK':
  34. btn = QPushButton(name)
  35. btn.setObjectName(name)
  36. btn.clicked.connect(self.slot_btn_video_screen_shot)
  37. grid.addWidget(btn, *pos, 1, 2)
  38. btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  39. elif name is 'process:':
  40. pbar_text = self.ProcessBar.get_pbar_text()
  41. pbar_text.setObjectName(name)
  42. grid.addWidget(pbar_text, *pos, 1, 2)
  43. pbar_text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  44. elif name is 'pbar':
  45. pbar_loc = self.ProcessBar.get_pbar()
  46. pbar_loc.setObjectName(name)
  47. grid.addWidget(pbar_loc, *pos, 1, 2)
  48. pbar_loc.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  49. elif name is ' ':
  50. loc = QLineEdit()
  51. loc.setObjectName(LineEdit_content[LineEdit_index])
  52. grid.addWidget(loc, *pos)
  53. LineEdit_index += 1
  54. else:
  55. loc_label = QLabel(name)
  56. loc_label.setObjectName(name)
  57. grid.addWidget(loc_label, *pos)
  58. self.left_up_x = self.findChild(QLineEdit, 'left-up-x')
  59. self.left_up_y = self.findChild(QLineEdit, 'left-up-y')
  60. self.right_bottom_x = self.findChild(QLineEdit, 'right-bottom-x')
  61. self.right_bottom_y = self.findChild(QLineEdit, 'right-bottom-y')
  62. """default 1920x1080"""
  63. self.left_up_x.setText("0")
  64. self.left_up_y.setText("0")
  65. self.right_bottom_x.setText("1920")
  66. self.right_bottom_y.setText("1080")
  67. self.new_frame = [[], [], [], []]
  68. def slot_btn_video_screen_shot(self):
  69. self.new_frame = self.get_new_frame()
  70. QMessageBox.information(self,
  71. 'Choose the video',
  72. "Choose the video")
  73. videoname_choose, file_type = QFileDialog.getOpenFileName(self,
  74. "choose video path",
  75. self.video_folder['videoscreenshotload'],
  76. "All Files (*);;"
  77. "Video Files (*.mp4);;"
  78. "Video Files (*.avi);;"
  79. "Video Files (*.mkv);;")
  80. self.video_folder['videoscreenshotload'] = os.path.abspath(videoname_choose)
  81. if videoname_choose == "":
  82. print("\nCancel Select video")
  83. return
  84. QMessageBox.information(self,
  85. 'Choose the new video name',
  86. "Choose the new video name")
  87. videonewname_choose, file_type = QFileDialog.getSaveFileName(self,
  88. "choose video path",
  89. self.video_folder['videoscreenshotsave'],
  90. "All Files (*);;"
  91. "Video Files (*.mp4);;"
  92. "Video Files (*.avi);;"
  93. "Video Files (*.mkv);;")
  94. self.video_folder['videoscreenshotsave'] = os.path.abspath(videoname_choose)
  95. if videonewname_choose == "":
  96. print("\nCancel Select new video")
  97. return
  98. print("\nThe chosen video is:")
  99. print(videoname_choose)
  100. """Select video and screen shot"""
  101. video_screen_shot(self.ProcessBar,
  102. videoname_choose,
  103. videonewname_choose,
  104. self.new_frame)
  105. self.reset_pbar()
  106. QMessageBox.information(self, 'Save Results',
  107. "video screen shot" + " has been finished!\n"
  108. )
  109. self.close()
  110. return
  111. def get_new_frame(self):
  112. self.new_frame[0] = int(self.left_up_y.text())
  113. self.new_frame[1] = int(self.right_bottom_y.text())
  114. self.new_frame[2] = int(self.left_up_x.text())
  115. self.new_frame[3] = int(self.right_bottom_x.text())
  116. return self.new_frame
  117. def reset_pbar(self):
  118. self.ProcessBar.reset_pbar()

      ----transform_tools

            ----__init__.py

            ----image2gif.py


  
  1. import os
  2. import numpy as np
  3. from PIL import Image, ImageDraw
  4. import imageio
  5. import inspect
  6. def add_text_to_image(image, text, font=None):
  7. rgba_image = image.convert('RGBA')
  8. text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))
  9. image_draw = ImageDraw.Draw(text_overlay)
  10. text_size_x, text_size_y = image_draw.textsize(text, font=font)
  11. print(rgba_image)
  12. """set text location"""
  13. text_xy = (rgba_image.size[0] - text_size_x, rgba_image.size[1] - text_size_y)
  14. """set text color and transparency"""
  15. image_draw.text(text_xy, text, font=font, fill=(255, 0, 0, 800))
  16. image_with_text = Image.alpha_composite(rgba_image, text_overlay)
  17. return image_with_text
  18. def image2gif(ProcessBar, load_path, gif_name, fps):
  19. """set the func name on pbar text"""
  20. ProcessBar.set_Text(inspect.stack()[0][3])
  21. """int fps"""
  22. fps = int(fps)
  23. """image name save format"""
  24. image_format = '{:05d}{:s}.jpg'
  25. """gif basename"""
  26. gif_basename = os.path.basename(gif_name)
  27. images = os.listdir(load_path)
  28. """duration"""
  29. duration = 1/fps
  30. """the index of the image that has been processed"""
  31. image_index = 1
  32. """for store each frame image"""
  33. frames = []
  34. ProcessBar.set_zero()
  35. for image in range(len(images)):
  36. jpgfile = str(load_path + '/' + image_format.format(image_index, ''))
  37. frame = Image.open(jpgfile)
  38. frame = add_text_to_image(frame, gif_basename)
  39. frames.append(np.array(frame))
  40. print(image_index)
  41. image_index += 1
  42. ProcessBar.set_Value(image_index, len(images), ratio=90)
  43. if image_index == len(images):
  44. ProcessBar.set_Text("Please wait ... it may take a few minutes...")
  45. print("Please wait ... it may take a few minutes...")
  46. imageio.mimsave(gif_name, frames, 'GIF', duration=duration) # duration = 1/fps
  47. ProcessBar.set_max()
  48. print(gif_basename, 'Synthetic success!')

            ----image2video.py


  
  1. import cv2
  2. import os
  3. from PIL import Image
  4. import inspect
  5. def image2video(ProcessBar, video_new_path, load_path, fps):
  6. """set the func name on pbar text"""
  7. ProcessBar.set_Text(inspect.stack()[0][3])
  8. fps = int(fps)
  9. fourcc = cv2.VideoWriter_fourcc(*"mp4v")
  10. """images path"""
  11. images = os.listdir(load_path)
  12. im = Image.open(load_path + '/' + images[0])
  13. vw = cv2.VideoWriter(video_new_path, fourcc, fps, im.size)
  14. """image name save format"""
  15. image_format = '{:05d}{:s}.jpg'
  16. """the index of the image that has been processed"""
  17. image_index = 1
  18. ProcessBar.set_zero()
  19. for image in range(len(images)):
  20. jpgfile = str(load_path + '/' + image_format.format(image_index, ''))
  21. try:
  22. frame = cv2.imread(jpgfile)
  23. vw.write(frame)
  24. print("image ", str(image_index), " has been processed.")
  25. image_index += 1
  26. ProcessBar.set_Value(image_index, len(images))
  27. except Exception as exc:
  28. print(jpgfile, exc)
  29. vw.release()
  30. print(video_new_path, 'Synthetic success!')

            ----video2image.py


  
  1. import os
  2. import cv2
  3. import inspect
  4. def video2image(ProcessBar, video_path, save_path):
  5. """set the func name on pbar text"""
  6. ProcessBar.set_Text(inspect.stack()[0][3])
  7. """select the video"""
  8. vc = cv2.VideoCapture(video_path)
  9. """image name save format"""
  10. image_format = '{:05d}{:s}.jpg'
  11. """basename"""
  12. video_name = os.path.basename(video_path)
  13. """image save folder"""
  14. image_save_folder = save_path + '/' + str(video_name.split('.')[0]) + '_' + str(video_name.split('.')[-1])
  15. if not os.path.exists(image_save_folder):
  16. os.mkdir(image_save_folder)
  17. assert os.path.exists(image_save_folder), 'Error: Invalid save path !'
  18. """the index of the image that has been processed"""
  19. image_index = 1
  20. """get the total frame number"""
  21. total_frame_number = vc.get(cv2.CAP_PROP_FRAME_COUNT)
  22. """get fps"""
  23. fps = vc.get(cv2.CAP_PROP_FPS)
  24. """Start to write..."""
  25. print("\nStart to Write...\n")
  26. ProcessBar.set_zero()
  27. while (image_index - 1) < total_frame_number:
  28. ret, frame = vc.read()
  29. if ret:
  30. cv2.imwrite(image_save_folder + '/' + image_format.format(image_index, ''), frame)
  31. cv2.waitKey(1)
  32. print("image ", str(image_index), " has been processed.")
  33. image_index += 1
  34. ProcessBar.set_Value(image_index, total_frame_number)
  35. elif frame is None:
  36. print("Write process is at the end.\n")
  37. ProcessBar.set_zero()
  38. return
  39. else:
  40. print("Cannot process the image ", str(image_index), "! Write to the image failed! \n")
  41. ProcessBar.set_zero()
  42. return
  43. print("Write process has been finished!!\n")
  44. """the total number of the image"""
  45. print(video_name, ':', image_index - 1, ' images have been transformed.')
  46. """release"""
  47. vc.release()
  48. return image_save_folder, video_name, fps, image_index - 1

            ----video_screen_shot.py


  
  1. import os
  2. import cv2
  3. import inspect
  4. def video_screen_shot(ProcessBar, video_path, video_new_path, new_frame):
  5. """set the func name on pbar text"""
  6. ProcessBar.set_Text(inspect.stack()[0][3])
  7. """select the video"""
  8. vc = cv2.VideoCapture(video_path)
  9. """basename"""
  10. video_name = os.path.basename(video_path)
  11. """judge the video is opened"""
  12. if vc.isOpened():
  13. print(video_name, "can be opened")
  14. else:
  15. print("video has been failed to open!")
  16. return
  17. """get fourcc"""
  18. fourcc = cv2.VideoWriter_fourcc(*"mp4v")
  19. """get fps"""
  20. fps = vc.get(cv2.CAP_PROP_FPS)
  21. """video width and height"""
  22. video_size = (int(new_frame[3] - new_frame[2]), int(new_frame[1] - new_frame[0]))
  23. """VideoWriter"""
  24. if os.path.exists(video_new_path):
  25. os.remove(video_new_path)
  26. vw = cv2.VideoWriter(video_new_path, fourcc, fps, video_size)
  27. """the index of the frame that has been processed"""
  28. image_index = 1
  29. """get the total frame number"""
  30. total_frame_number = vc.get(cv2.CAP_PROP_FRAME_COUNT)
  31. """get the total video time"""
  32. total_time = vc.get(cv2.CAP_PROP_POS_MSEC)
  33. """Start to premiere..."""
  34. print("\nStart to premiere...\n")
  35. ProcessBar.set_zero()
  36. while (image_index - 1) < total_frame_number:
  37. ret, frame = vc.read()
  38. frame = frame[new_frame[0]:new_frame[1], new_frame[2]:new_frame[3]]
  39. vw.write(frame)
  40. print(image_index)
  41. image_index += 1
  42. ProcessBar.set_Value(image_index, total_frame_number)
  43. print("Screen Shot process has been finished!!\n")
  44. """the total number of the image"""
  45. print(video_name, ':', image_index - 1, ' images have been transformed.')
  46. """release"""
  47. vc.release()
  48. vw.release()
  49. return video_new_path, video_name, fps, image_index - 1

      ----utils

            ----__init__.py

            ----check_jpg_dir.py


  
  1. import os
  2. def check_jpg_dir(video_dir_choose):
  3. frames = os.listdir(video_dir_choose)
  4. frames_number = 0
  5. for frame in frames:
  6. if frame.endswith('jpg'):
  7. frames_number += 1
  8. if frames_number == 0:
  9. check_flag = True
  10. elif frames_number == 1:
  11. check_flag = True
  12. else:
  13. check_flag = False
  14. print(frames_number, " images has been chosen.")
  15. return check_flag, frames_number

            ----ProcessBar.py


  
  1. from PyQt5.QtWidgets import *
  2. class ProcessBar(object):
  3. def __init__(self):
  4. """ProcessBar"""
  5. self.pbar = QProgressBar()
  6. self.pbar_text = QLabel()
  7. self.pbar_text.setText("Process :")
  8. def get_pbar(self):
  9. return self.pbar
  10. def get_pbar_text(self):
  11. return self.pbar_text
  12. def set_zero(self):
  13. self.pbar.setValue(0)
  14. def set_max(self):
  15. self.pbar.setValue(100)
  16. def set_Value(self, index, length, ratio=100):
  17. self.pbar.setValue((index - 1) / length * ratio)
  18. def set_Text(self, text):
  19. self.pbar_text.setText(str(text) + ":")
  20. def reset_pbar(self):
  21. self.pbar_text.setText("Process :")
  22. self.pbar.setValue(0)

            ----set_cwd.py


  
  1. import os
  2. def set_cwd():
  3. cwd = os.getcwd()
  4. """path for each button"""
  5. images_folder = {}
  6. images_folder['images2gif'] = cwd
  7. images_folder['video2images'] = cwd
  8. images_folder['videos2images'] = cwd
  9. images_folder['images2video'] = cwd
  10. gif_folder = {}
  11. gif_folder['images2gif'] = cwd
  12. video_folder = {}
  13. video_folder['video2images'] = cwd
  14. video_folder['videos2images'] = cwd
  15. video_folder['images2video'] = cwd
  16. video_folder['videoscreenshotload'] = cwd
  17. video_folder['videoscreenshotsave'] = cwd
  18. """The whole settings"""
  19. settings = {}
  20. settings['images_folder'] = images_folder
  21. settings['gif_folder'] = gif_folder
  22. settings['video_folder'] = video_folder
  23. return settings
  24. if __name__ == '__main__':
  25. set_cwd()

      ----__init__.py

----main.py


  
  1. from scripts.Form.SelectForm import *
  2. if __name__ == '__main__':
  3. app = QApplication(sys.argv)
  4. selectform = SelectForm("format tools")
  5. selectform.show()
  6. 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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。