PythonとOpenCV の読み書き はじめました pt.003affine変換
PythonとOpenCV の読み書きシリーズ
第3回
part 002はこちら part 004はこちら
目標/目的 又はそれらしきもの
- 大項目 手ブレ補正 やってみる?
- 中項目 今回やること → affine変換を使って、動画の空間的な制御
- 小項目 実験するよー
(ココで「空間的」とは、画面上のXY座標を指します)
環境
part 001を参照
かんたんな説明
今回は、結果を動画ファイルで出力したいので、ファイル形式の定義と、アウトプットファイルを生成、ファイルポインタを持ってます。
fourcc = cv2.VideoWriter_fourcc(*’XVID’)
out = cv2.VideoWriter(tgtdir+ os.sep +’output.avi’, fourcc, 30.0, (600,200))
動画ファイルオープンして、capにファイルポインタ保持 cap = cv2.VideoCapture(FILE_ORG)で、
フレーム画像読み込み cap.read()
フレーム画像サイズ変更 cv2.resize(画像配列,タプル型)
アフィン変換行列式 今回はコード中にコメント記述。デフォルト画面の左上(0,0)が回転中心となるが、参考URLから、画面中心を回転中心に出来る。
アフィン変換適用 output_img = cv2.warpAffine(crnt, np.float32(T), ORG_SIZE, flags=cv2.INTER_LINEAR)
crnt(フレーム画像)に対してT(アフィン変換行列)適用して、output_imgに格納
Tは [[cos, -sin, tx], [sin, cos, ty]] の配列です。↓
画像出力1 今回画像を横並びに表示したい。
xが0から300までは crntのリサイズしたもの
xが300から600までは output_imgのリサイズしたもの
ここで、pythonの配列は、(x,y)で並んでいるのに対して、opencvの配列は(y,x)で並んでいるのが曲者
アウトプット
- x方向への移動: https://youtu.be/t1px75aDaP0
- y方向への移動: https://youtu.be/qyZ_5sWcqus
まとめと雑感
動画のフレーム画像ごとにaffine変換を充てて、フレームを空間的に操作した
操作したフレーム画像を、動画としてファイルに出力した
次回の予定
画像ブレの分析
プログラム
import math
import cv2
import numpy as np
import os
fourcc = cv2.VideoWriter_fourcc(*’XVID’)
SKIPFRAMES = 0
RESIZE_RAT=2
ORG_SIZE=[]
if __name__ == ‘__main__’:
tgtdir=’C:\\Users\\Admin\\Downloads’
tgtfile=’VID_20171223_151319.mp4′
FILE_ORG = tgtdir + os.sep + tgtfile
#アウトプットファイル生成
out = cv2.VideoWriter(tgtdir+ os.sep +’output.avi’, fourcc, 30.0, (600,200))
showimage = np.zeros((200,600,3), dtype=np.uint8)
#フレーム読み込み関係の配列準備
cur = np.ndarray([])
cur_gray = np.ndarray([])
prev = np.ndarray([])
prev_gray = np.ndarray([])
has_next = None
cap = cv2.VideoCapture(FILE_ORG)
ORG_SIZE = (int(cap.get(3)),int(cap.get(4)))
#必要であればフレーム読み飛ばし
cap.set(1,SKIPFRAMES)
# 最初のフレーム読み込み
has_next, prev = cap.read()
while(True):
if has_next == False:
break
has_next, crnt = cap.read()
#T = [[a, b, c],
# [d, e, f]]
# a=cos(回転ラジアン)
# b=-sin(回転ラジアン)
# d=cos(回転ラジアン)
# e=sin(回転ラジアン)
# c=x移動
# e=y移動
transform_x = cap.get(1)
transform_y = 0
transform_r = 0
#今回はアフィン変換(T)には、回転中心の変更を含まない
#回転中心を考慮したいときの参考↓
#参考http://imagingsolution.blog107.fc2.com/blog-entry-111.html
T = [[math.cos(transform_r),-math.sin(transform_r),transform_x],
[math.sin(transform_r),math.cos(transform_r),transform_y]]
output_img = cv2.warpAffine(crnt, np.float32(T), ORG_SIZE, flags=cv2.INTER_LINEAR)
#映像出力
showimage[0:200,0:300] = cv2.resize(crnt,(300,200))
if output_img is not None:
showimage[0:200,300:600] = cv2.resize(output_img,(300,200))
out.write(showimage)
#検証用画像出力
if output_img is not None:
cv2.imshow(“frame0”, cv2.resize(showimage,(600,200)))
if cv2.waitKey(1) & 0xFF == ord(‘q’):
break
#cv2.waitKey(0)
prev = crnt
out.release()
pass