【OpenCV】 Webカメラ
【OpenCV】 Webカメラ導入
TheImagingSource社のカメラを含むWebカメラはUVCデバイスとして使用でき、OpenCVのVideoCaptureでカメラを開き、プロパティ設定をすることができます。ただ、OpenCVのクラスやメソッドは汎用的に作られているのでプログラムに実装してもカメラに反映されないことがあります。
このプログラムはTheImagingSource社のカメラをOpenCVのVideoCaptureで開き、OpenCVのメソッドでプロパティ値を設定し、OpenCVで画像処理(上下反転処理)を検証しています。OpenCVのAPIを使ったときにカメラのプロパティがどこまで反映されるの確認するために使用してください。
なお、このサンプルプログラムはTheImagingSource社製のモジュールを使用せず、OpenCVのオープンソースのライブラリのみを用いたC++のコーディングのみとなります。
検証のための準備(Windowsの場合)
1.TISカメラ使用する場合には下記から該当するドライバをダウンロード・インストールしておいてください。
モバイルサイトではご利用いただけません。
2.Windows10 64bit版をVisual Studio 2022使用する場合には下記のサンプルプログラムをダウンロード
モバイルサイトではご利用いただけません。
なお、上記のプログラムはOpenCVのインストールや環境変数の設定が必要です。
サンプルプログラムは参考程度にし、下記の手順で自身でソリューションファイルを作成してください。
手順1:OpenCVのダウンロード
OpenCVの公式ページよりOpenCVのインストーラをダウンロードします。
サンプルプログラムは現時点で最新版のバージョン4.5.5をダウンロードします。
https://opencv.org/releases/
手順2:OpenCVのダウンロード(Windows)
ダウンロードしたインストーラをダブルクリックします。
インストールディレクトリを入力するウィンドウが立ち上がるので、インストールするディレクトリを指定します。
Cドライブ直下「C:\」にインストールをします。下記の通り、環境変数Pathに「C:\opencv\build\x64\vc15\bin」を追加します。
手順3:Visual Studio2022の設定(Windows)の参照設定を確認
Visual Studio 2022を開き、[ファイル]>[新規作成]>[プロジェクト]>[Visual C++]>[空のプロジェクト]より新規プロジェクトを作成します。
[プロジェクト]>[プロパティ]を開く。以下、プロパティ内での設定です。
[VC++ ディレクトリ]>[インクルード ディレクトリ]>[編集]より「C:\opencv\build\include」を追加します。
[VC++ ディレクトリ]>[インクルード ディレクトリ]>[編集]より「C:\opencv\build\x64\vc15\lib」を追加します。
[リンカー]>[入力]>[追加の依存ファイル]>[編集]より「C:\opencv\build\x64\vc15\lib」にある「opencv_world455d.lib」を追加します。
手順4:サンプルプログラム作成
[プロジェクト名を右クリック]>[追加]>[新しい項目]>[C++ファイル]より新規ソースファイルを作成し、プログラム解説にあるソース.cppのコードを記述します。
手順5:実行
下記の通りローカルWindows デバッガーをクリックするとコンパイルをし、プログラムを実行します。
実行結果
プログラム全体
OpenCVモジュールをインポートします。
#include<opencv2\opencv.hpp>
int main(void) {
cv::VideoCapture cap(1);//デバイスのオープン
cap.set(cv::CAP_PROP_FRAME_WIDTH,1920);//フレームの幅
std::cout << "フレームの幅 : " << cap.get(cv::CAP_PROP_FRAME_WIDTH) << std::endl;
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);//フレームの高さ
std::cout << "フレームの高さ : " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
//圧縮フォーマット(BGR3、YUYV、MJPG、H264などが選択可能)
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y', 'U', 'Y', 'V'));
std::cout << "圧縮フォーマット : " << cap.get(cv::CAP_PROP_FOURCC) << std::endl;
//フレームレート
cap.set(cv::CAP_PROP_FPS, 30);
std::cout << "フレームレート : " << cap.get(cv::CAP_PROP_FPS) << std::endl;
cap.set(cv::CAP_PROP_AUTO_EXPOSURE, 0); //カメラによる自動露光のON/OFF
std::cout << "カメラによる自動露光のON/OFF : " << cap.get(cv::CAP_PROP_AUTO_EXPOSURE) << std::endl;
cap.set(cv::CAP_PROP_AUTO_WB, 0); //カメラによるホワイトバランス制御のON/OFF
std::cout << "カメラによるホワイトバランス制御のON/OFF : " << cap.get(cv::CAP_PROP_AUTO_WB) << std::endl;
cap.set(cv::CAP_PROP_AUTOFOCUS, 1); //カメラによるフォーカス制御のON/OFF
std::cout << "カメラによるフォーカス制御のON/OFF : " << cap.get(cv::CAP_PROP_AUTOFOCUS) << std::endl;
cap.set(cv::CAP_PROP_BRIGHTNESS, 240); //明るさ
std::cout << "明るさ: " << cap.get(cv::CAP_PROP_BRIGHTNESS) << std::endl;
cap.set(cv::CAP_PROP_CONTRAST, -1); //コントラスト
std::cout << "コントラスト : " << cap.get(cv::CAP_PROP_CONTRAST) << std::endl;
cap.set(cv::CAP_PROP_SATURATION,64 ); //彩度
std::cout << "彩度 : " << cap.get(cv::CAP_PROP_SATURATION) << std::endl;
cap.set(cv::CAP_PROP_HUE,0 ); //色相
std::cout << "色相 : " << cap.get(cv::CAP_PROP_HUE) << std::endl;
cap.set(cv::CAP_PROP_GAIN,46); //ゲイン
std::cout << "ゲイン : " << cap.get(cv::CAP_PROP_GAIN) << std::endl;
cap.set(cv::CAP_PROP_EXPOSURE,-6); //露光時間
std::cout << "露光時間 : " << cap.get(cv::CAP_PROP_EXPOSURE) << std::endl;
cap.set(cv::CAP_PROP_GAMMA, 100); //ガンマ
std::cout << "ガンマ : " << cap.get(cv::CAP_PROP_GAMMA) << std::endl;
cap.set(cv::CAP_PROP_FOCUS,0); //フォーカス
std::cout << "フォーカス : " << cap.get(cv::CAP_PROP_FOCUS) << std::endl;
cap.set(cv::CAP_PROP_PAN, 0); //パン(水平移動)
std::cout << "パン(水平移動) : " << cap.get(cv::CAP_PROP_PAN) << std::endl;
cap.set(cv::CAP_PROP_TILT, 0); //チルト
std::cout << "チルト : " << cap.get(cv::CAP_PROP_TILT) << std::endl;
cap.set(cv::CAP_PROP_ROLL, 0); //ロール
std::cout << "ロール : " << cap.get(cv::CAP_PROP_ROLL) << std::endl;
cap.set(cv::CAP_PROP_IRIS, 0); //絞り
std::cout << "絞り : " << cap.get(cv::CAP_PROP_IRIS) << std::endl;
if (!cap.isOpened())//カメラデバイスが正常にオープンしたか確認.
{
//読み込みに失敗したときの処理
return -1;
}
cv::Mat frame,v_frame; //取得したフレーム
while (cap.read(frame))//無限ループ
{
cv::flip(frame, v_frame, 0); // 水平軸で反転(垂直反転)
//取得したフレーム画像に対して,クレースケール変換や2値化などの処理を書き込む.
cv::imshow("win", v_frame);//画像を表示.
const int key = cv::waitKey(1);
if (key == 'q')//qボタンが押されたとき
{
break;//whileループから抜ける.
}
else if (key == 's')//sが押されたとき
{
//フレーム画像を保存する.
cv::imwrite("image.png", v_frame);
}
}
cv::destroyAllWindows();
return 0;
}
プログラム解説
まず、OpenCVモジュールをインポートします。その後、メイン関数内でビデオファイルやカメラからキャプチャを行うためのクラスVideoCaptureを使います。「cv::VideoCapture cap(”デバイスの番号”)」と宣言するだけで簡単にデバイスをオープンできます。引数にあるデバイスの番号はPCに接続されたカメラデバイスの順番を指定します。ここではPCに2台のカメラが接続されていますので引数を"1"としていますが、PCに1台だけしか接続されていない場合には「0」を指定します。
#include<opencv2\opencv.hpp>
int main(void) {
cv::VideoCapture cap(1);//デバイスのオープン
プロパティ値の設定について
カメラのプロパティはset()で設定し、get()でカメラに設定した値を取得することができます。このサンプルでは【フレームのサイズ】から【絞り】まで様々なプロパティ値を設定していますが、すべてのプロパティ値がカメラに反映されるわけではないので注意してください。たとえカメラに機能があったとしてもOpenCVは汎用的なライブラリが故に、OpenCVで制御できないことは往々にしてあります。Webカメラ含めTISカメラのプロパティ値をOpencvで反映できるのは下記の【フレームのサイズ】、【圧縮フォーマット】、【フレームレート】、【ゲイン】、【露光時間】程度とお考えください。カメラにある機能をすべて制御する必要がある場合には専用のSDKを使用するようにしましょう。
その他の設定プロパティは下記をご覧ください。
https://docs.opencv.org/4.x/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d
cap.set(cv::CAP_PROP_FRAME_WIDTH,1920);//フレームの幅
std::cout << "フレームの幅 : " << cap.get(cv::CAP_PROP_FRAME_WIDTH) << std::endl;
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);//フレームの高さ
std::cout << "フレームの高さ : " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
//圧縮フォーマット(BGR3、YUYV、MJPG、H264などが選択可能)
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y', 'U', 'Y', 'V'));
std::cout << "圧縮フォーマット : " << cap.get(cv::CAP_PROP_FOURCC) << std::endl;
//フレームレート
cap.set(cv::CAP_PROP_FPS, 30);
std::cout << "フレームレート : " << cap.get(cv::CAP_PROP_FPS) << std::endl;
cap.set(cv::CAP_PROP_GAIN,0); //ゲイン
std::cout << "ゲイン : " << cap.get(cv::CAP_PROP_GAIN) << std::endl;
cap.set(cv::CAP_PROP_EXPOSURE,-10); //露光時間
std::cout << "露光時間 : " << cap.get(cv::CAP_PROP_EXPOSURE) << std::endl;
露光時間について
露光時間はcap.set(cv::CAP_PROP_EXPOSURE,-6);で指定することができます。
TISのUSBカメラ(DFK33UX174)の場合、setの第1引数にCAP_PROP_EXPOSUREを、下記の表の通り第2引数には0 ~ -16の範囲の数値を指定することができます。setの第2引数の数値をnとした場合、2のn乗
2n
が露光時間となります。これよりもステップ数を細かく区切ることができないため、この表の中から最も設定値として近しい値を選ぶことになります。
CAP_PROP_EXPOSURE | 露光時間 |
---|---|
0 | 1秒 |
-1 | 500ms |
-2 | 250msms |
-3 | 125ms |
-4 | 62.5ms |
-5 | 31.3ms |
-6 | 15.6ms |
-7 | 7.8ms |
-8 | 3.9ms |
-9 | 2ms |
-10 | 976.6µs |
-11 | 488.3µs |
-12 | 244.1µs |
-13 | 122.1µs |
-14 | 61.5µs |
-15 | 3v0.7µs |
-16 | 15.3µs |
ゲイン
ゲインはcap.set(cv::CAP_PROP_GAMMA, 100);で指定することができます。
TISのUSBカメラ(DFK33UX174)の場合、setの第1引数にCAP_PROP_GAMMAを、カメラで0~500の範囲の数値を指定することができます。カメラのスペックに依存しますが、DFK33UX174の場合、0~480(0dB~48.0dB)までの範囲で設定可能です。
その他のプロパティの設定範囲はAmCapなどのWEBカメラの動作を確認するためのフリーソフトウェアにて設定範囲を参考程度に確認してください。
例:
画像取得について
サンプルではMat変数を宣言した後にwhile文のループ中に下記の手順で画像を取得し、表示・保存を行っています。
なお、Matとは多次元配列を格納するためのクラスで,主に画像や行列を扱う時に利用するものです。ここでは取得した画像に対して画像処理を行うために明示的に定義しています。
① cap.readによってMat変数にカメラの画像を格納する。
② flipによって画像を上下反転させる画像処理を行う(カメラによってデフォルトで上下反転していることがあります)。
③ imshow関数により画面表示する。
④ キーボードでqキーを押したときにプログラム終了する。
⑤ キーボードでsキーを押したときにimage.pngの名称で画像を保存する。
cv::Mat frame,v_frame; //画像を格納するオブジェクトを宣言する
while (cap.read(frame))//無限ループ
{
cv::flip(frame, v_frame, 0); // 水平軸で反転(垂直反転)
//取得したフレーム画像に対して,クレースケール変換や2値化などの処理を書き込む.
cv::imshow("win", v_frame);//画像を表示.
const int key = cv::waitKey(1);
if (key == 'q')//qボタンが押されたとき
{
break;//whileループから抜ける.
}
else if (key == 's')//sが押されたとき
{
//フレーム画像を保存する.
cv::imwrite("image.png", v_frame);
}
}
cv::destroyAllWindows();
return 0;