質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1340閲覧

OpenCVによる補正後の動画の保存

km16

総合スコア12

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/22 13:33

前提・実現したいこと

PythonのOpenCVのカメラキャリブレーションについてです。
公式サイトのチュートリアルにあるコードを参考にあらかじめ撮影した動画ファイルのカメラゆがみ補正を行おうとしてます。
補正後の動画サイズを自動で所得し動画の保存をしたいです。

発生している問題・エラーメッセージ

save = cv.VideoWriter('cariburation.MOV',fourcc,frame_rate,(w,h))
のコードを書く場所が分からない。

該当のソースコード

Python

1import numpy as np 2import cv2 as cv 3import glob 4from time import sleep 5from datetime import datetime 6 7 8# termination criteria 9criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001) 10 11# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) 12square_size = 21.0 13objp = np.zeros((6*9,3), np.float32) 14objp[:,:2] = np.mgrid[0:6,0:9].T.reshape(-1,2) 15objp *= square_size 16 17# Arrays to store object points and image points from all the images. 18objpoints = [] # 3d point in real world space 19imgpoints = [] # 2d points in image plane. 20images = glob.glob('./img/*.JPG') 21for fname in images: 22 img = cv.imread(fname) 23 gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 24 # Find the chess board corners 25 ret, corners = cv.findChessboardCorners(gray, (6,9), None) 26 # If found, add object points, image points (after refining them) 27 if ret == True: 28 objpoints.append(objp) 29 corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria) 30 imgpoints.append(corners) 31 # Draw and display the corners 32 cv.drawChessboardCorners(img, (6,9), corners2, ret) 33 cv.imshow('img', img) 34 cv.waitKey(500) 35cv.destroyAllWindows() 36 37et, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) 38 39 40 41cap = cv.VideoCapture(IMG_7800.MOV) 42 43w = int(cap.get(cv.CAP_PROP_FRAME_WIDTH)) 44h = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)) 45 46frame_rate = int(cap.get(cv.CAP_PROP_FPS)) 47fourcc = cv.VideoWriter_fourcc('m','p','4','v') 48save = cv.VideoWriter('cariburation.MOV',fourcc,frame_rate,(w,h)) 49 50while cap.isOpened(): 51 ok, frame=cap.read() 52 h, w = img.shape[:2] 53 newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h)) 54 55 # undistort 56 dst = cv.undistort(frame, mtx, dist, None, newcameramtx) 57 # crop the image 58 x, y, w, h = roi 59 dst = dst[y:y+h, x:x+w] 60 save.write(dst) 61 cv.imshow('cariburation', dst) 62 k = cv.waitKey(1) 63 if k == 27 : break # esc pressed

試したこと

save = cv.VideoWriter('cariburation.MOV',fourcc,frame_rate,(w,h))
のw,hに手動で補正後のサイズを入力したら再生できました。これを自動で入力されるようにしたいです。

補足情報(FW/ツールのバージョンなど)

ubuntu20.04を使用
参考にしたサイト
https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/11/22 22:04 編集

「既にあるキャリブレーション結果(もしくはプログラムの前半でキャリブレーションをした結果)」を元に、キャリブレーション前の動画を修正して改めて保存したい、という質問と理解しました。 > save = cv.VideoWriter('cariburation.MOV',fourcc,frame_rate,(w,h)) > のw,hに手動で補正後のサイズを入力したら再生できました。これを自動で入力されるようにしたいです。 もう少しここを詳しく説明ください。「 cv.VideoWriterのサイズと、保存したい画像のサイズが不一致で出力できない」が問題でしょうか? もしそうであれば、 dst = dst[y:y+h, x:x+w] のあとに、 dst = cv2.resize(dst,(w,h)) とすればうまくいくかもしれません。
fana

2021/11/23 02:23

> dst = cv2.resize(dst,(w,h)) 「結果動画を眺めて楽しむだけ」とかいう用途ならばまぁそれで良いでしょうけど… そうでない(補正結果の映像を何か別の処理に用いる)ならば,せっかくの補正結果をてきとーにリサイズってのはまずいのでは.
km16

2021/11/23 06:48

やりたい事、起きている問題はfourteenlengthさんの言っている通りです。 この後やりたい事としては透視変換で真上から見たように変換した後、一緒に撮影した定規を元にピクセルをmmに変換する予定です。
guest

回答1

0

ベストアンサー

newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))

これを while のループの中で何度も行う必要性はないでしょう.
すなわち,この処理は

et, mtx, dist, rvecs, tvecs = cv.calibrateCamera( ... )

save = cv.VideoWriter( ... )

の間(VideoWriterの作成よりも手前)に持っていくことができるハズです.

で,コードを見るに,どうやら補正結果画像のうち roi の範囲だけを動画に出力したいのだと見えますから,
VideoWriterの作成時に指定するサイズとしては,この roi のサイズを用いればよいでしょう.

投稿2021/11/23 02:18

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/11/23 09:46

> この後やりたい事としては透視変換で真上から見たように変換した後… ([質問への追記・修正、ベストアンサー選択の依頼]より) roi範囲だけを切り取って出力した結果動画を用いる際には,Optical Center の値がその分だけ変化していることに注意が必要でしょうね. で,それはそれとして, 一旦「歪み補正した動画」を中間結果として介在させることには何か利点があるのでしょうか? (元の動画から「透視変換で真上から見た」絵を作るのと比較して)
km16

2021/11/23 15:53

補正しないと歪みによってズレると思ってましたが言われてみれば確かにいらないかも?
fana

2021/11/24 00:58

> 透視変換で真上から見たように変換 の過程で歪みは取り除かれますよね. (元の映像に対応したカメラ内部パラメータを用いた変換式を用いるわけですから)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問