# 将影片转换成图片 - Day 11

将影片转换成图片 - Day 11

今天要完成的工作是将搜集到的影片或是照片转换成 YOLOV3 可以接受的格式,所以要完成的工作如下:

  1. 建立目录结构
  2. 安装需要的套件
  3. 撰写程序
    1. 读写目录
    2. 影片转图片
    3. 变更尺寸为608

建立目录结构

github 上所下载的影片放在 video 文件夹,而 utils 文件夹放资料预处理的程序,如今天需要用到的将影片转成图片,images 用来放处理後的图片,labels 是用来存放标签文件,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20210911/201295102O6OFGyNp9.png
图 1、 YOLOV3 资料预处理文件夹

安装需要的套件

将影片转换成图片的程序中需要用到 OpenCV 套件,所以需要安装 OpenCV。打开终端机,输入以下指令进行安装。

pip3 install opencv-python
python3

进入 Python 的交互画面,输入以下指令,确认是否可以正常使用 OpenCV,如果无法正常使用,那代表系统中安装多个 Python 版本,而环境变数 PYTHONPATH 没有设定正确,以至於进行汇入 (import) 时,会无法汇入 cv2,可以透过 sys.path 这个 Python 语法检查目前的设定。

import cv2
cv2.__version__
import sys
sys.path

下图是安装与确认画面,第一个方框显示套件下载的网站,第二个是套件所安装的目录,第三个方框是安装套件以及版本名称,第四个方框则是进入 Python 交互模式,第五个方框则是运行 Python 语法。

https://ithelp.ithome.com.tw/upload/images/20210911/201295102ZFIctlM31.png
图 2、OpenCV 安装与汇入画面

撰写程序

撰写这个程序主要需考虑以下三点

  1. 读写目录:指定输入 (video) 与输出目录 (images)
  2. 影片转图片: 使用 openCV 进行转换,因为拍摄时时每秒 30 张,但这样的图片变化太少,所以是每 5 张图片取一张。
  3. 变更尺寸: YOLOV3 可以自行在 cfg 档中设定输入图片的尺寸,预设 416×416 、608×608 或任何大於 32 的 2 次方倍数尺寸,再尺寸的缩放上还需要注意的是长宽比,因为大多数的照片的是矩型,但 YOLOV3 接受的却是正方形,所以必须要针对长宽不足的地方进行处理,我们这边是直接填 0 ,也就是黑色。
import cv2
import glob
import os

# 变更到指定尺寸,长宽边不足者补黑色
def process_image(img, min_side = 608):
    size = img.shape
    h, w = size[0], size[1]
    scale = max(w, h) / float(min_side)
    new_w, new_h = int(w/scale), int(h/scale)
    resize_img = cv2.resize(img, (new_w, new_h),cv2.INTER_AREA) # 变更尺寸
    if new_w % 2 != 0 and new_h % 2 == 0:
        top, bottom, left, right = (min_side-new_h)//2, (min_side-new_h)//2, (min_side-new_w)//2 + 1, (min_side-new_w)//2
    elif new_h % 2 != 0 and new_w % 2 == 0:
        top, bottom, left, right = (min_side-new_h)//2 + 1, (min_side-new_h)//2, (min_side-new_w)//2, (min_side-new_w)//2
    elif new_h % 2 == 0 and new_w % 2 == 0:
        top, bottom, left, right = (min_side-new_h)//2, (min_side-new_h)//2, (min_side-new_w)//2, (min_side-new_w)//2
    else:
        top, bottom, left, right = (min_side-new_h)//2 + 1, (min_side-new_h)//2, (min_side-new_w)//2 + 1, (min_side-new_w)//2
    pad_img = cv2.copyMakeBorder(resize_img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0,0,0]) 
    return pad_img

# 读写目录
inputPath = '../video'
outputPath = '../images'

files = os.path.join(inputPath,'*.mp4')
files_grabbed = []
files_grabbed.extend(sorted(glob.iglob(files)))

for videoId in range(len(files_grabbed)):
	print(files_grabbed[videoId])
	raw = cv2.VideoCapture(files_grabbed[videoId])
	fIndex = 1
	fCount = 0

	while 1:
    # 影片转图片
	    ret,frame = raw.read()
	    fCount += 1
	    if (ret == True) :
	    	if (fCount % 5) == 0:
		    	img_pad = process_image(frame, min_side = 608)
		    	cv2.imwrite('%s/%02d-frame-608x608-%04d.jpg' % (outputPath, videoId,fIndex), img_pad)
		    	fIndex += 1
	    else:
	    	break

下图显示在 VS Code 中的运行结果,显示处理了 video 目录下的三个影片,记得这个顺序很重要,因为会给予编号,第一个档案编号为 00 ,以此类推。

https://ithelp.ithome.com.tw/upload/images/20210911/20129510XpcNN63gLw.png
图 3、在 VS Code 中的运行结果

下图显示 images 文件夹内的图片讯息,00-frame-608x608-0036.jpg 表示的是标号为00 (黄金珍珠虎), frame-608x608 表示图片的尺寸,而 0036 则是第几张图片,从图片资讯中也的确看到这样的讯息,并且上下被填入黑色框。

https://ithelp.ithome.com.tw/upload/images/20210911/20129510krPImj8SJ0.png
图 4、处理完的图片

下图是原始的影片资讯,尺寸为 960x540 且长宽比为 16:9 ,每秒的祯片为 30。

https://ithelp.ithome.com.tw/upload/images/20210911/20129510QYPwcJ43gZ.png
图 5、原始影片资讯

参考资料


<<:  从 IT 技术面细说 Search Console 的 27 组数字 KPI (11) :网页体验

>>:  Day11. 从日常看到Blue Prism的窝心-BP合并两张报表

JavaScript Day18 - 阵列操作(filter、find、findIndex)

filter filter() 会建立一个新的阵列,其内容为原阵列的每一个元素经由回呼函式判断後所回...

第60天~

这个得上一篇:https://ithelp.ithome.com.tw/articles/10263...

Day 22 rspec-rails 介绍!

该文章同步发布於:我的部落格 今天我们会把 RSpec 安装进入 Rails 里面,以及一些基本的...

AI ninja project [day 2] OCR

首先想把自己比较熟悉的领域做分享, 今天主要是分享OCR套件的安装与使用, 而懂得使用这样的招式之後...

观赏鱼辨识系统说明-Day 01

观赏鱼辨识系统说明-Day 01 在接下来的30天会制作一个完整的系统包含前端-手机/网页,後端-N...