iT邦幫忙

2021 iThome 鐵人賽

DAY 11
1
AI & Data

觀賞魚辨識的YOLO全餐系列 第 11

# 將影片轉換成圖片 - 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、原始影片資訊

參考資料


上一篇
介紹影像辨識的處理流程 - Day 10
下一篇
標籤圖片的方法與實作 - Day 12
系列文
觀賞魚辨識的YOLO全餐33

1 則留言

0
胭脂虎
iT邦新手 2 級 ‧ 2021-09-29 15:26:30

謝謝老師,YOLOv3 圖片轉影片的應用原理說的很清楚!

謝謝。

我要留言

立即登入留言