第6回 初めてのOpenCV開発 ― highgui/imgcodecs/videoioモジュール【OpenCV 3.1.0】:OpenCV入門【3.0対応】(2/2 ページ)
OpenCVのhighgui、imgcodecs、videoioという3つのモジュールの概要を解説。GUI機能、画像ファイル/動画ファイルの入出力機能、カメラキャプチャ機能などのAPIと、その基本的な使い方を説明する。
4. videoioモジュール
ここでは、videoioモジュールでよく用いる以下の機能について紹介します(※動画像=動画)。
- 動画像入力
- 動画像出力
- カメラキャプチャ
4.1 動画像入力
videoioモジュールには、動画像入力を行うVideoCaptureクラスが提供されています。VideoCaptureクラスのメソッドと機能の概要は以下の通りです。
関数名 | 機能 |
---|---|
isOpened | 動画ファイルが正しく開けているかをチェックする |
get | 各種プロパティを取得する |
set | 各種プロパティを設定する |
VideoCaptureクラスのメソッドと機能の概要 |
4.1.1 メソッド紹介
ここでは、VideoCaptureクラスのコンストラクターおよびメソッドの機能と引数の説明を行います。
【VideoCaptureクラスのコンストラクター】動画ファイルを開くための準備を行う
VideoCapture::VideoCapture(const string& filename)
引数 | 引数の説明 |
---|---|
filename | 読み込む動画ファイル名 |
【VideoCaptureクラスのOpenedメソッド】動画ファイルが正常に開けているかをチェックする
bool VideoCapture::isOpened()
- 戻り値: 動画ファイルが正常に開けていればtrue、正常に開けていなければfalseを返す
【VideoCaptureクラスのgetメソッド】各種プロパティを取得する
double VideoCapture::get(int propId)
引数 | 引数の説明 |
---|---|
propId | プロパティを識別するための定数(詳細はこちらを参照) |
【VideoCaptureクラスのsetメソッド】各種プロパティを設定する
bool VideoCapture::set(int propId, double value)
引数 | 引数の説明 |
---|---|
propId | プロパティを識別するための定数(詳細はこちらを参照) |
value | 設定するプロパティ値 |
4.1.2 サンプルプログラム(動画像入力)
動画ファイルから取得した画像データをウィンドウ表示するサンプルコードを、以下に示します。
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp> // videoioのヘッダーをインクルード
#include <opencv2/highgui.hpp> // highguiのヘッダーをインクルード
#include <iostream>
int main(int argc, const char* argv[])
{
// (1)動画ファイルを開くための準備を行う
cv::VideoCapture cap("videofile.avi");
// (2)動画ファイルが正しく開けているかをチェックする(正しく開けていなければエラー終了する)
if (!cap.isOpened())
return -1;
// 画像表示用のウィンドウを生成する
cv::namedWindow("image", cv::WINDOW_AUTOSIZE);
// 画像データを格納するための変数を宣言する
cv::Mat frame;
for (;;)
{
// (3)動画ファイルから1フレーム分の画像データを取得して、変数frameに格納する
cap >> frame;
// 画像データ取得に失敗したらループを抜ける
if (frame.empty()) break;
// 取得した画像データをウィンドウ表示する
cv::imshow("image", frame);
if (cv::waitKey(30) >= 0) break;
}
return 0;
}
4.2 動画像出力
videoioモジュールには動画像出力を行うVideoWriterクラスが提供されています。
4.2.1 コンストラクター紹介
ここでは、VideoWriterクラスのコンストラクターで指定できるパラメーターとその内容について説明を行います。
【VideoWriterクラスのコンストラクター】画像データを動画像ファイルに書き出す
VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true)
引数 | 引数の説明 |
---|---|
filename | 書き出すファイル名 |
fourcc | コーデックを指定する4文字のキャラクター。 例えば、cv::VideoWriter::fourcc('P','I','M','1')で「MPEG-1」であることを表す。 その他のリストは「Video Codecs by FOURCC」で参照できる |
fps | 動画像のフレームレート(=1秒あたりのフレーム数) |
frameSize | 動画像のフレームサイズ(前回紹介したcv::Sizeを使って指定する) |
isColor | カラーの動画像ファイルとして書き出すかを指定する |
4.2.2 サンプルプログラム(動画像出力)
画像データを動画ファイルに書き出すサンプルコードを、以下に示します。
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp> // videoioのヘッダーをインクルード
#include <iostream>
int main(int argc, const char* argv[])
{
// 幅320px、高さ240px、3チャンネルのインスタンスを生成する
cv::Mat img(cv::Size(320, 240), CV_8UC3, cv::Scalar(0, 0, 255));
int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D');
double fps = 30.0;
bool isColor = true;
// (1)動画ファイルを書き出す準備を行う
cv::VideoWriter writer("videofile.avi", fourcc, fps, img.size(), isColor);
// (2)動画ファイル書き出しの準備に成功したかチェックする(失敗していればエラー終了する)
if (!writer.isOpened())
return -1;
for (int i = 0; i < 300; i++)
{
// (3)画像データを動画ファイルに書き出す
writer << img;
}
return 0;
}
4.2.3 動画ファイル再生可否状況(参考情報)
ここでは、参考情報としてVideoWriterクラスで生成した動画ファイルの再生可否についてコーデック名ごとにまとめたものを紹介します。○は再生できたこと、△は画像サイズによっては再生できたこと、×は再生できなかったことを表します。
コーデック名 | cv::VideoWriter::fourccの引数 | 拡張子 | Windows 10 Pro(64bit) |
---|---|---|---|
MP4S | ('M', 'P', '4', 'S') | .mp4 | ○ |
MP4V | ('M', 'P', '4', 'V') | .mp4 | ○ |
DIV3 | ('D', 'I', 'V', '3') | .avi | ○ |
DIVX | ('D', 'I', 'V', 'X') | .avi | ○ |
I420 | ('I', '4', '2', '0') | .avi | ○ |
IYUV | ('I', 'Y', 'U', 'V') | .avi | ○ |
MJPG | ('M', 'J', 'P', 'G') | .avi | ○ |
PIM1 | ('P', 'I', 'M', '1') | .avi | ○ |
XVID | ('X', 'V', 'I', 'D') | .avi | ○ |
dv25 | ('d', 'v', '2', '5') | .wmv | △ |
dv50 | ('d', 'v', '5', '0') | .wmv | △ |
dvc | ('d', 'v', 'c', ' ') | .wmv | △ |
dvh1 | ('d', 'v', 'h', '1') | .wmv | △ |
dvhd | ('d', 'v', 'h', 'd') | .wmv | △ |
dvsd | ('d', 'v', 's', 'd') | .wmv | △ |
dvsl | ('d', 'v', 's', 'l') | .wmv | △ |
H263 | ('H', '2', '6', '3') | .wmv | △ |
M4S2 | ('M', '4', 'S', '2') | .wmv | ○ |
MP43 | ('M', 'P', '4', '3') | .wmv | ○ |
MPG1 | ('M', 'P', 'G', '1') | .wmv | ○ |
MSS1 | ('M', 'S', 'S', '1') | .wmv | × |
MSS2 | ('M', 'S', 'S', '2') | .wmv | × |
WMV1 | ('W', 'M', 'V', '1') | .wmv | ○ |
WMV2 | ('W', 'M', 'V', '2') | .wmv | ○ |
WMV3 | ('W', 'M', 'V', '3') | .wmv | × |
WVC1 | ('W', 'V', 'C', '1') | .wmv | × |
mp4v | ('m', 'p', '4', 'v') | .mov | ○ |
動画ファイル再生可否状況(CMakeによる設定で「WITH_FFMPEG」をオンにしてOpenCVをビルド) |
コーデック名 | cv::VideoWriter::fourccの引数 | 拡張子 | Windows 10 Pro(64bit) |
---|---|---|---|
MP4S | ('M', 'P', '4', 'S') | .mp4 | × |
MP4V | ('M', 'P', '4', 'V') | .mp4 | × |
DIV3 | ('D', 'I', 'V', '3') | .avi | × |
DIVX | ('D', 'I', 'V', 'X') | .avi | × |
I420 | ('I', '4', '2', '0') | .avi | × |
IYUV | ('I', 'Y', 'U', 'V') | .avi | × |
MJPG | ('M', 'J', 'P', 'G') | .avi | × |
PIM1 | ('P', 'I', 'M', '1') | .avi | ○ |
XVID | ('X', 'V', 'I', 'D') | .avi | × |
dv25 | ('d', 'v', '2', '5') | .wmv | × |
dv50 | ('d', 'v', '5', '0') | .wmv | × |
dvc | ('d', 'v', 'c', ' ') | .wmv | × |
dvh1 | ('d', 'v', 'h', '1') | .wmv | × |
dvhd | ('d', 'v', 'h', 'd') | .wmv | × |
dvsd | ('d', 'v', 's', 'd') | .wmv | × |
dvsl | ('d', 'v', 's', 'l') | .wmv | × |
H263 | ('H', '2', '6', '3') | .wmv | × |
M4S2 | ('M', '4', 'S', '2') | .wmv | × |
MP43 | ('M', 'P', '4', '3') | .wmv | × |
MPG1 | ('M', 'P', 'G', '1') | .wmv | × |
MSS1 | ('M', 'S', 'S', '1') | .wmv | × |
MSS2 | ('M', 'S', 'S', '2') | .wmv | × |
WMV1 | ('W', 'M', 'V', '1') | .wmv | ○ |
WMV2 | ('W', 'M', 'V', '2') | .wmv | ○ |
WMV3 | ('W', 'M', 'V', '3') | .wmv | ○ |
WVC1 | ('W', 'V', 'C', '1') | .wmv | ○ |
mp4v | ('m', 'p', '4', 'v') | .mov | ○ |
動画ファイル再生可否状況(CMakeによる設定で「WITH_MSMF」をオンにしてOpenCVをビルド) |
コーデック名 | cv::VideoWriter::fourccの引数 | 拡張子 | Windows 10 Pro(64bit) |
---|---|---|---|
MP4S | ('M', 'P', '4', 'S') | .mp4 | ○ |
MP4V | ('M', 'P', '4', 'V') | .mp4 | ○ |
DIV3 | ('D', 'I', 'V', '3') | .avi | ○ |
DIVX | ('D', 'I', 'V', 'X') | .avi | ○ |
I420 | ('I', '4', '2', '0') | .avi | ○ |
IYUV | ('I', 'Y', 'U', 'V') | .avi | ○ |
MJPG | ('M', 'J', 'P', 'G') | .avi | ○ |
PIM1 | ('P', 'I', 'M', '1') | .avi | ○ |
XVID | ('X', 'V', 'I', 'D') | .avi | ○ |
dv25 | ('d', 'v', '2', '5') | .wmv | △ |
dv50 | ('d', 'v', '5', '0') | .wmv | △ |
dvc | ('d', 'v', 'c', ' ') | .wmv | △ |
dvh1 | ('d', 'v', 'h', '1') | .wmv | △ |
dvhd | ('d', 'v', 'h', 'd') | .wmv | △ |
dvsd | ('d', 'v', 's', 'd') | .wmv | △ |
dvsl | ('d', 'v', 's', 'l') | .wmv | △ |
H263 | ('H', '2', '6', '3') | .wmv | △ |
M4S2 | ('M', '4', 'S', '2') | .wmv | ○ |
MP43 | ('M', 'P', '4', '3') | .wmv | ○ |
MPG1 | ('M', 'P', 'G', '1') | .wmv | ○ |
MSS1 | ('M', 'S', 'S', '1') | .wmv | × |
MSS2 | ('M', 'S', 'S', '2') | .wmv | × |
WMV1 | ('W', 'M', 'V', '1') | .wmv | ○ |
WMV2 | ('W', 'M', 'V', '2') | .wmv | ○ |
WMV3 | ('W', 'M', 'V', '3') | .wmv | ○ |
WVC1 | ('W', 'V', 'C', '1') | .wmv | ○ |
mp4v | ('m', 'p', '4', 'v') | .mov | ○ |
動画ファイル再生可否状況(CMakeによる設定で「WITH_FFMPEG」、「WITH_MSMF」をオンにしてOpenCVをビルド) |
OpenCVのVideoWriterクラスにおける動画像ファイル出力処理は、「WITH_FFMPEG」、「WITH_MSMF」がともにONになっている場合、まずFFMPEGで生成を試みて、失敗するとMedia Foundationで生成を試みる仕組みになっています。そのため、今回試した組み合わせの中では、「WITH_FFMPEG」、「WITH_MSMF」がオンになっているケースが最も多くのコーデックを処理できていることが分かります。
4.3 カメラキャプチャ
videoioモジュールには、カメラキャプチャを行うVideoCaptureクラスが提供されています。VideoCaptureクラスのメソッドと機能の概要は以下の通りです。
関数名 | 機能 |
---|---|
isOpened | カメラが正しくオープンできているかをチェックする |
get | カメラキャプチャの各種プロパティを取得する |
set | カメラキャプチャの各種プロパティを設定する |
VideoCaptureクラスのメソッドと機能の概要 |
4.3.1 メソッド紹介
ここでは、VideoCaptureクラスのメソッドの機能と引数の説明を行います。
【VideoCaptureクラスのisOpenedメソッド】カメラが正常にオープンできているかをチェックする
bool VideoCapture::isOpened()
- 戻り値: 正常にオープンできていればtrue、正常にオープンできていなければfalseを返す
【VideoCaptureクラスのgetメソッド】各種プロパティを取得する
double VideoCapture::get(int propId)
引数 | 引数の説明 |
---|---|
propId | プロパティを識別するための定数(詳細はこちらを参照) |
【VideoCaptureクラスのsetメソッド】各種プロパティを設定する
bool VideoCapture::set(int propId, double value)
引数 | 引数の説明 |
---|---|
propId | プロパティを識別するための定数(詳細はこちらを参照) |
value | 設定するプロパティ値 |
4.3.2 サンプルプログラム
カメラキャプチャを行い、取得した画像データをウィンドウ表示するサンプルコードを、以下に示します。
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp> // videoioのヘッダーをインクルード
#include <opencv2/highgui.hpp> // highguiのヘッダーをインクルード
#include <iostream>
int main(int argc, const char* argv[])
{
// (1)DirectShowを使ってカメラキャプチャを行う。
// また、カメラIDが0番のカメラについてキャプチャの準備を行う
int camera_id = 0;
cv::VideoCapture cap(cv::CAP_DSHOW + camera_id);
// (2)カメラIDが0番のカメラが正しくオープンできているかをチェックする(正しくオープンできていなければエラー終了する)
if (!cap.isOpened())
return -1;
// (3)カメラキャプチャのフレームレートを30.0に指定する
cap.set(cv::CAP_PROP_FPS, 30.0);
// 画像表示用のウィンドウを生成する
cv::namedWindow("image", cv::WINDOW_AUTOSIZE);
// 画像データを格納するための変数を宣言する
cv::Mat frame;
for (;;)
{
// (4)カメラから1フレーム分の画像データを取得して、変数frameに格納する
cap >> frame;
// 画像データ取得に失敗したらループを抜ける
if (frame.empty()) break;
// 取得した画像データをウィンドウ表示する
cv::imshow("image", frame);
if (cv::waitKey(30) >= 0) break;
}
return 0;
}
4.3.3 サンプルプログラムの補足
サンプルコードでは、VideoCaptureクラスのインスタンス生成でcv::CAP_DSHOWを指定することで、“DirectShow”を使ったキャプチャを行うようにしています。
このように明示的な指定を行わない場合、Windowsではデフォルトで“Video for Windows”を使ったキャプチャが行われます。しかし、Video for Windowsは、レガシーなAPIかつ利用できる機能も少ないため、Windows環境で利用する場合にはcv::CAP_DSHOW(DirectShowを使ったキャプチャ)か、cv::CAP_MSMF(Media Foundationを使ったキャプチャ)を指定することをお勧めします。
5. おわりに
今回は、highgui/imgcodecs/videoioモジュールを紹介しました。次回は、OpenCVアプリケーション開発におけるデバッグ補助ツールを紹介します。
Copyright© Digital Advantage Corp. All Rights Reserved.