Easy Web Camera LIBrary
EWCLIB 2.0
"ewclib.h" by I.N. 2010/5/13 |
内容
1.
はじめに
特長,
動作環境,
環境設定,
インストール方法,
アンインストール方法,
使用手順
2.
説明
基本関数について,
フレームバッファについて
3.
サンプルプログラム
最も単純なプログラム,
ESPLIBを併用した例(1),
ESPLIBを併用した例(2),
ESPLIBを併用した例(3),
ESPLIBを併用した例(4)
OpenCVと組み合わせて使用した例,
OpenCV&ESPLIBと組み合わせて使用した例
4.
関数リファレンス
基本関数,
画像の更新確認,
グローバル変数,
フレームバッファ関連,
カメラ設定の取得・変更,
画像変換
5.
おわりに
著作権・使用許諾,
バージョンアップ履歴,
作者のウェブサイト,
開発環境,
謝辞
はじめに
本製品をお買い上げいただき誠にありがとうございます.(無料です)
このライブラリ関数を使えば,誰でも手軽にウェブカメラ(USBカメラ/DirectShow)画像入力プログラムを作成できます.
最近は低価格なウェブカメラがたくさん出回っていますが,それらの画像を処理するプログラムの作成に便利です.
特長
(1) 最低3つの関数を使用するだけで簡単に画像入力ができます.
(2) 複数カメラの同時接続に対応します.
(3) カメラ毎に解像度,フレームレートの設定ができます.
(4) 明るさ,コントラスト,ホワイトバランス等の取得・設定ができます.
(5) 画像の更新確認,サンプル時刻の取得,フレームバッファの変更ができます.
動作環境
OS:Windows XP/Vista/7
必要ソフト:例1 Visual C++ 2008 Professional ※1
例2 Visual C++ 2010 Professional + qedit.h※1※2
例3 Visual C++ 2008 Express Edition ※1
例4 Visual C++ 2005 Professional + Windows SDK※1※3
※1 DirectX SDKはなくてもよい.
※2 Visual C++ 2010にはqedit.hがついてこない.
VC2008についてきたqedit.hをコピーして持ってきたら使えた.
※3 例えば,Windows SDK for Windows Server 2008 and .NET Framework 3.5
(Windows SDKのうち,少なくともヘッダーファイルとx86ライブラリがあればよい)
動作確認した環境:
(a) Logicool Qcam Pro 4000 x2台
+ Logicool Qcam Ultra Vision x1台
(b) Buffalo PC-SDVD/U2G (USBキャプチャーケーブル)
+ Logicool Qcam Pro 4000
+ Logicool Qcam Ultra Vision
(c) OpenCV 2.1と組み合わせて使用
(上記以外の機器・環境については不明です.また上記以外の機器が接続されている環境下も不明です.)
(Visual C++ .NET 2003などの開発環境の場合には,EWCLIBのバージョン1.2を使用してください.)
環境設定
・
Visual C++ のインストール
あらかじめ,Visual C++ をインストールしておいて下さい.
・
Visual C++ 2008では
インストール以外,特にすることはありません.
・
Visual C++ 2010では
Visual C++ 2010にはqedit.hだけがない.
Visual C++ 2008についてきたqedit.hをVisual C++ 2010の方にもコピーしておく.
例えば,C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\qedit.hをC:\Program
Files\Microsoft SDKs\Windows\v7.0A\Include\へコピーする.
上記以外の方法として,適当なWindows SDKをインストールすることでもよいと思われるが未確認.Visual C++ 2005のやり方に近いと思われる.
・
Visual C++ 2005では
Windows SDKに付いているDirectShowのインクルードファイルやライブラリファイルを使用しますので,パスが通っていない環境であれば,パスを通しておいて下さい.すなわち,Visual
C++のディレクトリに関する設定を行っておいて下さい.
設定例:
Visual C++ 2005の「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ ディレクトリ」
ディレクトリを表示するプロジェクト:インクルード ファイル
C:\Program Files\Microsoft SDKs\Windows\v6.0\Include
ディレクトリを表示するプロジェクト:ライブラリ ファイル
C:\Program Files\Microsoft SDKs\Windows\v6.0\Lib
を追加します.
インストール方法
Visual C++ 2008 の場合
以下の2方法を例として挙げておきます.(他の方法でも構いません.)
方法1:
ewclib.h を適当なフォルダに置いておく.Visual C++ で「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,ewclib.h を置いた先のフォルダ名を追加登録する.
方法2:
Visual C++ が C:\Program Files\Microsoft Visual Studio 9.0 フォルダにインストールされている場合を例にとると,C:\Program Files\Microsoft Visual Studio 9.0\VC\include フォルダの中に ewclib.h をコピーする.
Visual C++ 2010 の場合
各プロジェクトのプロパティで,ewclib.hが置いてあるディレクトリを,インクルードファイルのディレクトリに追加する.
アンインストール方法
方法1でインストールした場合
インストールの時と同じ手順で「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,自分が追加したフォルダ名の登録を削除する.
方法2でインストールした場合
C:\Program Files\Microsoft Visual Studio 9.0\VC\include フォルダの中にある ewclib.h を削除する.
使用手順
プログラムの先頭で ewclib.h をインクルードするだけです.
OpenCVを併用する場合は,
cv.hの方を先にインクルードしておいてください.
ソースファイルの拡張子は .cpp にして下さい.
説明
基本関数について

関数リファレンス
基本関数

カメラの初期化のために
EWC_Open()を最初に呼んで下さい.複数のカメラを使用する場合,カメラ毎に
EWC_Open()を実行してください.

画像データを取得するには
EWC_GetImage()を使います.

終了処理のために
EWC_Close()または
EWC_CloseAll()を最後に呼んで下さい.

接続されているカメラの数を得るには
EWC_GetCamera()を使います.

画像データの格納に必要なフレームバッファのサイズを得るには
EWC_GetBufferSize()を使います.

画像の更新確認やサンプル時刻を取得するときは
画像の更新確認関数を使います.

明るさなどの設定値を変更するには
カメラ設定の取得・変更関数を使います.
EWC_Open()によってフレームバッファは自動的に確保されますが,自前で用意したフレームバッファを使用するときは
フレームバッファ関連関数を使います.

初期化関数
EWC_Open()の実行には多少時間がかかる場合があります(特に初回).また,この関数がエラー終了する原因として,カメラのドライバがインストールされていない,そのカメラが対応していない解像度やフレームレートを指定した場合,指定した台数だけのカメラが接続されていない場合などが挙げられます.

カメラが複数接続された環境にも対応しますが,同時入力(同期した画像入力)を保証するわけではありません.
デフォルトの画像フォーマットは,OpenCVのヘッダファイル(cv.h)が読み込まれていればMEDIASUBTYPE_RGB24,読み込まれていなければMEDIASUBTYPE_RGB32になります.
MEDIASUBTYPE_RGB24の場合,画像データの並び(バイト単位)は[B][G][R]です.また,MEDIASUBTYPE_RGB32の場合,画像データの並び(バイト単位)は[B][G][R][0]です.
デフォルト以外の画像フォーマットを使用したい場合は,
EWC_Open()で5番目の引数に指定します.
例: EWC_Open(0,320,240,30,0,MEDIASUBTYPE_RGB565);このように
EWC_Open()を使うとカメラ毎に独立した画像フォーマットを設定できます.詳しくは
EWC_Open()を参照してください.
また,デフォルトの画像フォーマットを変更したいときは,
#define EWC_TYPE MEDIASUBTYPE_RGB565
#include <ewclib.h>
のように,ewclib.hのインクルードより前でEWC_TYPEを定義してください.
参考までに,Qcam Pro 4000の場合,画像フォーマットには次のタイプが使用できました.
MEDIASUBTYPE_RGB4
MEDIASUBTYPE_RGB8
MEDIASUBTYPE_RGB565
MEDIASUBTYPE_RGB555
MEDIASUBTYPE_RGB24
MEDIASUBTYPE_RGB32
MEDIASUBTYPE_ARGB32
これ以外にもたくさんありますが,詳細についてはDirectX SDKのヘルプでAM_MEDIA_TYPE構造体(Media Types, Video Subtypes)を参照してください.カメラによって使用可能なフォーマットは異なります.
フレームバッファについて

関数リファレンス
フレームバッファ関連

EWCLIBでは
EWC_Open()の実行時に画像データを格納するためのフレームバッファを内部で自動的に確保します.カメラからの画像データは取得(サンプル)時刻毎にそのフレームバッファへ格納されます.
EWC_GetImage()はそのフレームバッファからユーザが指定したポインタへ画像データをユーザ側のタイミングで転送(コピー)する関数です.

もし「自前でフレームバッファを用意するから,そのフレームバッファに画像データを取得(サンプル)時刻毎に自動で転送(格納)してくれ」という場合には,
EWC_SetBuffer()を使います.そして,新しい画像データが到着したかどうかは,
EWC_IsCaptured()を使うことによって知ることができます.また,画像データが取得(サンプル)された時刻を知るためにも
EWC_IsCaptured()は使えます.

現在設定されているフレームバッファの先頭アドレスを知るには
EWC_GetBuffer()を使います.
EWC_Open()直後には,
EWC_GetBuffer()で得られるアドレスは内部で確保されたフレームバッファのアドレスになっています.
EWC_SetBuffer()で別のフレームバッファを設定した場合には,
EWC_GetBuffer()はその変更された方のアドレスを返します.
double ewc_s[int num].stimeというグローバル変数は,最も新しい画像データを取得(サンプル)した時刻(単位:秒)が常に格納・更新されています.num はカメラ番号です.この
ewc_s[].stimeの値はバックグラウンドで勝手に変化します.この変数をチェックすることで新しい画像データが到着したかどうかを判断することもできます.
double ewc_s[int num].ftimeというグローバル変数は,前回のフレーム周期(単位:秒)が常に格納されています.num はカメラ番号です.この
ewc_s[].ftimeの値はバックグラウンドで勝手に変化します.この変数の逆数(1.0/ewc_s[].ftime)を計算すればフレームレート(FPS)が得られます.
サンプルプログラム
最も単純なプログラム
最も単純なプログラムの例です.これを実行しても何も起こりません.画像の表示もありません.
Win32 コンソール アプリケーションの例です.
画像サイズは320x240ピクセル,フレームレートは30fpsに設定されます.
#include <ewclib.h>
int buffer[320*240];
void main(void)
{
EWC_Open(0, 320, 240, 30.);
EWC_GetImage(0, buffer);
EWC_Close(0);
}
|
ESPLIBを併用した例(1)
EWCLIBとESPLIBを使ってカメラ画像を表示する例です.
1台目のカメラのみ表示します.
プログラム実行後,Startをクリックしてください.
カメラを初期化した後,画像の表示が開始されます.Stopのクリックで停止します.
ESPLIBのインストール方法や使用方法は割愛させていただきます.
//EWCLIBのサンプル(ESPLIB併用) by I.N.
//画像データを取得して表示するだけ
//2010.5.13
#include <esplib.h>
#include <ewclib.h>
#define WX 640
#define WY 480
void ESP_Ready(void)
{
ESP_CreateImage(0,"Camera",0,0,WX,WY,100);
ESP_OpenTextWindow(0,86,512,439,135);
ESP_Printf("Startをクリックしてください.\n");
}
void ESP_Main(void)
{
ESP_Printf("初期化中...\n");
int r= EWC_Open(0,WX,WY,30.);
if(r){
ESP_Printf("Error %d\n",r);
return;
}
for(;;){
if(ESP_STOP) break;
if(EWC_IsCaptured(0)){
EWC_GetImage(0,ESP_VramPtr[0]);
ESP_Update_(0);
ESP_Printf("*");
}
}
EWC_Close(0);
ESP_Printf("Stopped\n");
}
void ESP_Finish(void)
{
}
|
ESPLIB を併用した例(2)
EWCLIBとESPLIBを使用しています.設定内容の表示と変更が行えます.
//EWCLIBのサンプル(ESPLIB併用) by I.N.
//Visual C++ 2008 Professional
//2010.05.12 for EWCLIB 2.0
#include <esplib.h>
#include <ewclib.h>
#define WX 320
#define WY 240
#define ZOOM 100
int nc; //カメラ数
char *itemtitle[17]={
"BRIGHTNESS","CONTRAST","HUE","SATURATION","SHARPNESS",
"GAMMA","COLORENABLE","WHITEBALANCE","BACKLIGHTCOMPENSATION","GAIN",
"PAN","TILT","ROLL","ZOOM","EXPOSURE","IRIS","FOCUS"
};
//設定の読み出し
void read_value(void)
{
for(int i=0;i<17;i++){
int mode=0;
double v=EWC_GetValue(0,i,&mode);
ESP_SetInputBoxD(i,v);
char s[256];
strcpy_s(s,256,itemtitle[i]);
if(mode) strcat_s(s,256," [auto]");else strcat_s(s,256," ");
ESP_SetInputBoxTitle(i,s);
}
}
void ESP_Ready(void)
{
// [Image Window]
ESP_CreateImage(0,"Camera",0,0,WX,WY,ZOOM);
// [Text Window]
ESP_OpenTextWindow(0,0,265,374,190);
ESP_OpenTextWindow(1,0,482,374,154);
// [Input Box]
ESP_OpenInputBox(382,265,17);
ESP_ResizeInputBox(198,130);
// [Button Box]
ESP_OpenButtonBox(730,265,3,17);
ESP_ResizeButtonBox(240,480);
for(int i=0;i<17;i++){
ESP_SetButtonBoxTitle(3*i+0,"変更");
ESP_SetButtonBoxTitle(3*i+1,"初期値");
ESP_SetButtonBoxTitle(3*i+2,"自動");
}
ESP_SetForeground(ESPMAINWINDOW);
SetWindowPos(esp_mw_hwnd,0,60,680,0,0,SWP_NOSIZE|SWP_NOZORDER);
ESP_StartAllLog();
ESP_SelectTW(0);
ESP_Printf("初期化中...\n");
int r=EWC_Open(0, WX, WY, 30.0);
if(r){
ESP_Printf("Error %d\n",r);
return;
}
nc=EWC_GetCamera();
ESP_Printf("カメラ数=%d\n",nc);
r=EWC_GetBufferSize(0);
ESP_Printf("バッファサイズ:%d bytes\n",r);
//バッファの変更
EWC_SetBuffer(0,ESP_VramPtr[0]);
//設定の読み出し
read_value();
ESP_Printf("Startをクリックしてください.\n");
}
void ESP_Main(void)
{
int en=0;
char s[256];
double t=0.;
EWC_PropertyPage(0);
EWC_Run(0);
read_value();
ESP_Printf("画像更新中...\n");
for(;;){
if(ESP_STOP)break;
ESP_SelectTW(1);
if(EWC_IsCaptured(0,&t)){
ESP_Update_(0);
ESP_Printf("t:%.1f s [%4.1f fps]\n",t,1.0/ewc_s[0].ftime);
}
ESP_UnSelectTW();
for(int b=0;b<51;b++){
//ボタンが押されたとき
if(ESP_GetButtonBox(b)){
double v;
int r;
int item=b/3;
switch(b%3){
case 0:
v=ESP_GetInputBoxD(item);
r=EWC_SetValue(0,item,v);
break;
case 1:
r=EWC_SetDefault(0,item);
break;
case 2:
r=EWC_SetAuto(0,item);
break;
}
//メッセージの表示
en++;
if(r>=4){
ESP_Printf("[%d]",en);
EWC_GetLastMessage(s,256);
ESP_Printf("%s",s);
}else if(r==3){
ESP_Printf("[%d]この機能はサポートされていません\n",en);
}else if(r>0){
ESP_Printf("[%d]エラー\n",en);
}else{
ESP_Printf("[%d]OK\n",en);
}
//設定の読み出し
read_value();
}
}
}
EWC_Stop(0);
ESP_Printf("Stop\n");
}
void ESP_Finish(void)
{
EWC_Close(0);
}
|
ESPLIB を併用した例(3)
カメラ3台まで表示します.
カメラ毎に動作の停止と再開,プロパティページの起動が行えます.
EWCLIBとESPLIBを使用しています.
//EWCLIB 2.0のテスト(カメラ3台まで表示)
//2010.5.13 I.N.
#include <esplib.h>
#include <ewclib.h>
#define N 3
int WX[N]={320,320,320};
int WY[N]={240,240,240};
double FPS[N]={30,30,30};
void ESP_Ready(void)
{
// [Image Window]
ESP_CreateImage(0,"Camera 0", 0, 0,WX[0],WY[0],100);
ESP_CreateImage(1,"Camera 1",336, 0,WX[1],WY[1],100);
ESP_CreateImage(2,"Camera 2", 0,278,WX[2],WY[2],100);
// [Text Window]
ESP_OpenTextWindow(0,541,278,208,237);
// [Button Box]
ESP_OpenButtonBox(336,278,2,3);
ESP_ResizeButtonBox(189,157);
ESP_SetButtonBoxTitle(0,"#0\nRun/Stop");
ESP_SetButtonBoxTitle(1,"Property");
ESP_SetButtonBoxTitle(2,"#1\nRun/Stop");
ESP_SetButtonBoxTitle(3,"Property");
ESP_SetButtonBoxTitle(4,"#2\nRun/Stop");
ESP_SetButtonBoxTitle(5,"Property");
ESP_SetForeground(ESPMAINWINDOW);
ESP_Printf("Click 'Start'.\n");
}
void ESP_Main(void)
{
int tgl[N],r[N];
double fps[N];
ESP_Printf("Starting...\n");
for(int i=0;i<N;i++){
r[i]=EWC_Open(i,WX[i],WY[i],FPS[i]);
ESP_Printf("EWC_Open(%d)=%d\n",i,r[i]);
tgl[i]=1;
fps[i]=0;
}
for(;;){
if(ESP_STOP) break;
int f=0;
for(int i=0;i<N;i++){
if(EWC_IsCaptured(i)){
EWC_GetImage(i,ESP_VramPtr[i]);
ESP_Update_(i);
fps[i]=1./ewc_s[i].ftime;
f++;
}
}
if(f) ESP_Printf("FPS: %5.1f %5.1f %5.1f\n",fps[0],fps[1],fps[2]);
for(int i=0;i<N;i++){
if(ESP_GetButtonBox(i*2)){
if(tgl[i]) EWC_Stop(i); else EWC_Run(i);
tgl[i]=1-tgl[i];
}
if(ESP_GetButtonBox(i*2+1)) EWC_PropertyPage(i);
}
}
int n=EWC_GetCamera();
ESP_Printf("Camera=%d\n",n);
for(int i=N-1;i>=0;i--){
r[i]=EWC_Close(i);
ESP_Printf("EWC_Close(%d)=%d\n",i,r[i]);
}
ESP_Printf("Fin.\n");
}
void ESP_Finish(void)
{
}
|
ESPLIB を併用した例(4)
10秒(300フレーム)遅れたカメラ映像を表示します.
EWCLIBとESPLIBを使用しています.
プログラムは短いですが,メモリは400MBくらい消費します.
//10秒遅延したカメラ映像を実現するプログラム
//(300フレーム(10秒)だと,メモリを400MBくらい消費する!)
//2009.04.30 ver.1.0
//2010.05.12 ver.1.1 EWCLIB2.0対応版
#include <esplib.h>
#include <ewclib.h>
#define FRAMES 300
#define WX 640
#define WY 480
int img[FRAMES][WX*WY];
void ESP_Ready(void)
{
ESP_CreateImage(0,"Delayed frame",0,0,WX,WY,100);
ESP_OpenTextWindow(0,86,512,439,135);
ESP_SetForeground(ESPMAINWINDOW);
ESP_Printf("Startをクリックしてください\n");
}
void ESP_Main(void)
{
int w=0; //これから書き込むフレーム番号[0〜(FRAMES-1)]
int r=0; //これから読み出すフレーム番号[0〜(FRAMES-1)]
int flag=0; //最初のFRAMESフレームがたまったら1になるフラグ
ESP_Printf("カメラ初期化中...\n");
int t= EWC_Open(0,WX,WY,30.);
if(t){
ESP_Printf("Error %d\n",r);
return;
}
for(;;){
// フレームバッファを指定
EWC_SetBuffer(0,img[w]);
// 新しいフレームが来るまで待つ
for(;;){
if(EWC_IsCaptured(0)) break;
if(ESP_STOP) goto fin;
}
// フレーム番号 w の表示
ESP_Locate(0,2);
ESP_Printf("w=%03d\n",w);
w=(w+1)%FRAMES; //wは0〜(FRAMES-1)を繰り返す
if(w==0) flag=1; //wがひとまわり(FRAMES)したら1
//画像がFRAMESフレーム蓄積されたら表示が開始される
if(flag){
r=w; //rには最も古いフレーム番号を指定する
CopyMemory(ESP_VramPtr[0],img[r],WX*WY*4);
ESP_Update_(0);
// フレーム番号 r の表示
ESP_Locate(0,3);
ESP_Printf("r=%03d\n",r);
}
}
fin:
EWC_Close(0);
ESP_Printf("Stopped\n");
}
void ESP_Finish(void)
{
}
|
OpenCVと組み合わせて使用した例
EWCLIBとOpenCVを使って,カメラ画像を入力し処理するプログラム例です.
OpenCVの関数を利用して特徴点(Harris)を抽出します.
アプリケーションの種類は,Win32 コンソール アプリケーションを指定してください.
OpenCVのインストール方法や使用方法は割愛させていただきます.
//EWCLIBとOpenCVを使って,USBカメラ画像を入力し処理するプログラム例
// by I.N.
//動作確認ソフト:
// Windows XP Professional SP3
// Visual C++ 2008 Professional
// EWCLIB 2.0
// OpenCV 2.1.0
//履歴:
// 2009.04.24 ver.1.0 動作確認
// 2010.05.12 ver.1.1 EWCLIB2.0/OpenCV2.1対応版
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#pragma comment(lib, "cv210.lib")
#pragma comment(lib, "cxcore210.lib")
#pragma comment(lib, "highgui210.lib")
#include <ewclib.h> //cv.hより後でインクルードする
#define WX 640
#define WY 480
#define FPS 30
int main(void)
{
char *winc="Camera"; //ウィンドウの名前
char *win1="Image1";
int r=EWC_Open(0,WX,WY,FPS); //カメラ初期化
if(r){
printf("カメラを初期化できません(%d)\n",r);
return 1;
}
cvNamedWindow(win1,CV_WINDOW_AUTOSIZE); //ウィンドウ作成
cvMoveWindow(win1,0,0);
IplImage *imgc=cvCreateImage(cvSize(WX,WY),8,3); //画像作成(カラー用)
IplImage *img1=cvCreateImage(cvSize(WX,WY),8,1); //画像作成(グレー用)
IplImage *img2;
EWC_SetBuffer(0,imgc->imageData); //カメラ画像格納先の変更
//特徴点抽出用
#define CNTMAX 128
CvPoint2D32f ppts[CNTMAX];
IplImage *imge=cvCreateImage(cvSize(WX,WY),32,1);
IplImage *imgt=cvCreateImage(cvSize(WX,WY),32,1);
//処理ループ
while(1){
int key=cvWaitKey(1);
if (key==0x1B) break; //ESCキーで終了
if (EWC_IsCaptured(0)){
cvCvtColor(imgc,img1,CV_BGR2GRAY); //カラーからグレーへ変換
//特徴点(Harris)抽出
int cnt=CNTMAX;
cvGoodFeaturesToTrack(img1,imge,imgt,ppts,&cnt,0.1,15,NULL,3,1,0.01);
cvFindCornerSubPix(img1,ppts,cnt,cvSize(3,3),cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
//描画
img2=cvCloneImage(imgc);
for (int i=0;i<cnt;i++) cvCircle(img2,cvPointFrom32f(ppts[i]),3,CV_RGB(255,0,0),2);
cvShowImage(win1,img2); //処理した画像の表示
cvReleaseImage(&img2);
}
}
//終了処理
EWC_Close(0);
cvReleaseImage(&imgt);
cvReleaseImage(&imge);
cvReleaseImage(&img1);
cvReleaseImage(&imgc);
cvDestroyWindow(win1);
return 0;
}
|
OpenCV&ESPLIBと組み合わせて使用した例
OpenCVとESPLIBとEWCLIBを使って,カメラ画像を入力し処理するプログラム例です.
OpenCVの関数を利用して特徴点(Harris)を抽出します.
アプリケーションの種類は,Win32 アプリケーションを指定してください.
OpenCVやESPLIBのインストール方法や使用方法は割愛させていただきます.
//OpenCV,EWCLIB,ESPLIBを使って,USBカメラ画像を入力し処理するプログラム例
// by I.N.
//動作確認ソフト:
// Windows XP Professional SP3
// Visual C++ 2008 Professional
// OpenCV 2.1.0
// EWCLIB 2.0
// ESPLIB 7.4
//履歴:
// 2009.05.01 ver.1.0 動作確認
// 2010.05.12 ver.1.1 EWCLIB2.0/OpenCV2.1対応版
#include <cv.h>
#include <cxcore.h>
#pragma comment(lib, "cv210.lib")
#pragma comment(lib, "cxcore210.lib")
#include <esplib.h>
#include <ewclib.h> //cv.hより後でインクルードする
#define WX 640
#define WY 480
#define FPS 30
void ESP_Ready(void)
{
ESP_CreateImage(0,"Camera",0,0,WX,WY,100);
ESP_OpenTextWindow(0,672,0,152,469);
ESP_SetForeground(ESPMAINWINDOW);
ESP_Printf("Startをクリック\n");
}
void ESP_Main(void)
{
int t,t0;
int r=EWC_Open(0,WX,WY,FPS); //カメラ初期化
if(r) {ESP_Printf("カメラを初期化できません(%d)\n",r); return;}
IplImage *imgc=cvCreateImage(cvSize(WX,WY),8,3); //画像(カメラ画像用)
IplImage *img1=cvCreateImage(cvSize(WX,WY),8,1); //画像(グレー用)
IplImage *img2=NULL;
EWC_SetBuffer(0,imgc->imageData); //カメラ画像格納先の変更
//特徴点抽出用
#define CNTMAX 100
CvPoint2D32f ppts[CNTMAX];
IplImage *imge=cvCreateImage(cvSize(WX,WY),32,1);
IplImage *imgt=cvCreateImage(cvSize(WX,WY),32,1);
ESP_StartClock();
//処理ループ
while(1){
if(ESP_STOP) break;
if (EWC_IsCaptured(0)){
t0=ESP_GetClock();
cvCvtColor(imgc,img1,CV_BGR2GRAY); //カラーからグレーへ変換
//特徴点(Harris)抽出
int cnt=CNTMAX;
cvGoodFeaturesToTrack(img1,imge,imgt,ppts,&cnt,0.1,5,NULL,3,1,0.01);
cvFindCornerSubPix(img1,ppts,cnt,cvSize(3,3),cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
//描画
img2=cvCloneImage(imgc);
for (int i=0;i<cnt;i++) cvCircle(img2,cvPointFrom32f(ppts[i]),3,CV_RGB(255,0,0),2);
EWC_Cnv24to32(ESP_VramPtr[0],(unsigned char*)img2->imageData,WX*WY);
ESP_Update_(0);
cvReleaseImage(&img2);
//周期の表示
t=ESP_GetClock();
ESP_Printf("t=%dms\n",t-t0);
t0=t;
}
}
//終了処理
EWC_Close(0);
cvReleaseImage(&imgt);
cvReleaseImage(&imge);
cvReleaseImage(&img1);
cvReleaseImage(&imgc);
ESP_Printf("Stopped");
}
void ESP_Finish(void)
{
}
|
関数リファレンス
基本関数
int EWC_Open(int num, int wx, int wy, double fps);
int EWC_Open(int num, int wx, int wy, double fps, int device);
int EWC_Open(int num, int wx, int wy, double fps, int device, GUID mstype);
説明
指定された番号のカメラを初期化します.
カメラ毎に最初に1回呼びます.
EWCLIBにより認識されて使用可能なカメラ台数を知りたいときは,この関数の実行後にEWC_GetCamera()を使います.
カメラからの画像を得るにはEWC_GetImage()を使います.
カメラの使用が終わったらEWC_Close()またはEWC_CloseAll()で終了処理を行ってください.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
wx,wy:画像サイズ(幅および高さ) [単位:ピクセル]
代表的なサイズとしては160x120,320x240,640x480です.
使用するカメラによって利用できる解像度は異なります.
利用できない解像度を指定した場合,エラー終了となります.
fps:フレームレート
代表的なフレームレートは30や15ですが,任意の値を設定できます.
使用するカメラによって利用できるフレームレートは異なります.
指定した通りのフレームレートが得られるとは限りませんので注意してください.
利用できないフレームレートを指定した場合,エラー終了となります.
device:実際に対応するカメラの番号(この引数はオプション)
複数のカメラが接続されている場合で,論理的なカメラ番号numは変更せずに,
実際に対応するカメラの番号を変更する場合に使います.
例えば,2台接続されていて,両者を入れ替えた場合を試したい場合で,
プログラムソースの他の部分の変更を最小限に抑えるには,
EWC_Open(0, 320, 240, 30, 1);
EWC_Open(1, 320, 240, 30, 0);
のように,この引数deviceを追加するだけで実現できます.
mstype:画像フォーマット(この引数はオプション)
デフォルトの画像フォーマットから変更したい場合,この引数を使います.
これによりカメラ毎に異なる画像フォーマットを指定することができます.
戻り値
0:正常終了
0以外:エラー終了
使用例
EWC_Open(0, 320, 240, 15.);
EWC_Open(0, 320, 240, 30, 1);
EWC_Open(2, 320, 240, 30, 2, MEDIASUBTYPE_RGB24);
int EWC_Close(int num);
int EWC_CloseAll(void);
説明
終了処理を行います.カメラの使用を終了させるため最後に1回呼びます.
カメラ毎に行うのがEWC_Close()です.また,EWC_Open()によって使用中のすべてのカメラをまとめて終了させるのがEWC_CloseAll()です.
この関数が実行されるまでは,他のアプリケーションはそのカメラにアクセスすることができません.
(確証はありませんが,複数カメラの場合,EWC_Open()の逆順でEWC_Close()した方が問題が起きない?)
EWC_CloseAll()はEWC_Open()により起動させた順番の逆で終了処理を行います.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
0:正常終了
1:EWC_Open()で初期化されていない
上記以外:エラー終了
使用例
EWC_Close(0);
EWC_CloseAll();
int EWC_GetCamera(void);
説明
EWCLIBによって認識されたカメラの台数を返します.
EWC_Open()の実行後にこの関数を使ってください.そうしないと,カメラの有無に関わらず0を返します.
引数
なし
戻り値
0:EWC_Open()で初期化されていない or カメラが接続されていない
上記以外:カメラ台数
使用例
int n;
n=EWC_GetCamera();
int EWC_GetBufferSize(int num);
説明
画像データを格納するのに必要なフレームバッファのサイズを返します.
バッファサイズは画像のサイズ(解像度)やフォーマットによって変わります.
EWC_Open()の実行後にこの関数を使ってください.そうしないと,カメラの有無に関わらず0を返します.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
フレームメモリの大きさ [単位:バイト]
使用例
int size;
size=EWC_GetBufferSize(0);
int EWC_GetImage(int num, void *buffer);
説明
カメラの画像データを取得します.
EWCLIB内部にあるフレームバッファから buffer へ画像データをコピーします.
EWC_SetBuffer()によって画像データ転送先の変更が行われている場合,この関数を使用する必要はなくなります.
EWC_SetBuffer()を使ってフレームバッファを変更している場合にこの関数を使うと,変更された方のフレームバッファから buffer へ画像データをコピーします.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
buffer:画像データを格納する領域の先頭アドレス(ポインタ)
格納されたデータの構造はフォーマットによって異なります.
MEDIASUBTYPE_RGB32の場合,1ピクセル=int型(4バイト,0xrrggbb)です.
MEDIASUBTYPE_RGB24の場合,1ピクセル=3バイト,[B][G][R]…です.
OpenCVを使用する場合(ewclib.hより先にcv.hがインクルードされたとき),EWCLIBは
MEDIASUBTYPE_RGB24に設定します.それ以外はMEDIASUBTYPE_RGB32がデフォルト値です
他のフォーマットにおけるデータ構造はDirectX SDKヘルプを参照してください.
戻り値
0:正常終了
1:EWC_Open()で初期化されていない or カメラ番号が範囲外
使用例
int buffer[320*240];
EWC_GetImage(0,buffer);
int EWC_Stop(int num);
説明
カメラの動作(キャプチャ)を一時的に停止させます.
カメラに動作ランプが備わっていれば,停止中は消灯します.
停止中に画像データの取得を行うと,停止時の内容が読み出されます.
再開させるにはEWC_Run()を使います.
この関数はEWC_Close()/EWC_CloseAll()の内部でも自動で実行されるので,カメラの使用を終了するためにわざわざこの関数を呼ぶ必要はありません.また,すでに停止している場合,実行しても影響はありません.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
0:正常終了
1:EWC_Open()で初期化されていない or カメラ番号が範囲外
上記以外:エラー終了
使用例
EWC_Stop(0);
int EWC_Run(int num);
説明
カメラの動作(キャプチャ)を再開させます.
カメラに動作ランプが備わっていれば,再点灯します.
すでに動作(再開)している場合,実行しても影響はありません.
停止させるにはEWC_Stop()を使います.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
0:正常終了
1:EWC_Open()で初期化されていない or カメラ番号が範囲外
上記以外:エラー終了
使用例
EWC_Run(0);
画像の更新確認
int EWC_IsCaptured(int num [, double *t] );
説明
新しい画像データがフレームバッファに格納されたかどうかを確認します.
この関数が1度呼ばれた後は,新しい次の画像がフレームバッファへ格納されるまで この関数は0 を返します.
使い方ですが,メインのプログラム中でこの関数を使って新しい画像の到着を確認し,到着したらすぐに画像データをどこか別の場所へ転送するか,何らかの画像処理を行うようにします.次の画像データが格納されるまではフレームバッファには古いデータが存在しています.
引数 t は省略可能です.t にdouble型変数へのポインタを指定すれば,新しい画像データが取得された時刻を知ることができます.新しい画像データが到着していなかった場合,変数 t の内容は変化しません.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
t:取得時刻を格納する変数へのポインタ(この引数はオプション)
戻り値
0:新しい画像データはまだ来ていません or 引数numの値が不正です
1:新しい画像データが格納されました
使用例
while(1){
if(EWC_IsCaptured(0)){
// Image processing...
}
}
使用例
double t;
EWC_IsCaptured(0,&t);
グローバル変数
double ewc_s[int num].stime;
説明
最近取得された画像データの取得(サンプル)時刻が格納されています.
この変数の値はバックグラウンドで常に更新されます.
EWC_IsCaptured()を使用しなくても,この変数の値を監視すれば,新しい画像データが格納されたかどうかを確認することができます.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
取得時刻(単位:秒)
使用例
printf("Sample time= %f [s]\n",ewc_s[0].stime);
double ewc_s[int num].ftime;
説明
前回のフレーム周期が格納されています.
この変数の値はバックグラウンドで常に更新されます.
隣接したサンプル時刻の差から計算していますので,この値の逆数を求めればフレームレート(FPS)となります.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
前回のフレーム周期(単位:秒)
使用例
printf("Frame period= %f [s]\n", ewc_s[0].ftime);
printf("Frame rate= %f [fps]\n", 1.0/ewc_s[0].ftime);
フレームバッファ関連
int EWC_SetBuffer(int num, void *buffer);
説明
フレームバッファを指定のアドレスへ変更します.
指定されたフレームバッファには一定時間毎に画像データが格納(上書き)されます.
buffer には画像データが格納されるため,あらかじめユーザ側で必要なメモリ領域を確保しておいてください.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
0:正常終了
1:エラー(num値が正しくない or カメラが接続されていない など)
使用例
int buf[640*480];
EWC_SetBuffer(0, buf);
int EWC_GetBuffer(int num, void **buffer);
説明
EWCLIB内部で画像格納先として登録されているフレームバッファのアドレスを取得します.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
buffer:フレームバッファのアドレスを格納するための変数へのポインタ
戻り値
0:正常終了
1:エラー(num値が正しくない or カメラが接続されていない など)
使用例
int *p;
EWC_GetBuffer(0, (void **)&p);
カメラ設定の取得・変更
double EWC_GetValue(int num, int prop [, int *mode] );
説明
現在のドライバ設定値を読み出します.
ウェブカメラの種類によってはサポートされていない項目もあります.
また,各項目の設定値はもともと整数値であり,範囲や刻み幅は項目毎にまちまちですが,EWCLIBでは,全項目について0.0〜100.0の割合(%)に変換して値を返します.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
prop:設定項目
下の中から1つを指定します
EWC_BRIGHTNESS (明るさ)
EWC_CONTRAST (コントラスト)
EWC_HUE (色相)
EWC_SATURATION (彩度)
EWC_SHARPNESS (鮮明度)
EWC_GAMMA (ガンマ補正)
EWC_COLORENABLE (カラー/モノクロ)
EWC_WHITEBALANCE (ホワイトバランス)
EWC_BACKLIGHTCOMPENSATION (バックライト補正)
EWC_GAIN (ゲイン)
EWC_PAN (パン/左右の向き)
EWC_TILT (チルト/上下の向き)
EWC_ROLL (ロール/光軸回りの回転)
EWC_ZOOM (ズーム/拡大)
EWC_EXPOSURE (露出)
EWC_IRIS (絞り)
EWC_FOCUS (焦点)
mode:現在のモードを取得したいときには,ここにモードを格納する変数の
先頭アドレス(ポインタ)を渡してください.
(この引数modeはオプションであり,省略できます.)
modeの戻り値:0は手動モード,1は自動モードを意味します.
戻り値
実数(double型):設定項目の値を0〜100[%]の範囲で返します.
-1.0:サポートされていない or 引数が不正 or その他のエラー
使用例
double d;
d=EWC_GetValue(0, EWC_BRIGHTNESS);
int mode;
d=EWC_GetValue(0, EWC_EXPOSURE, &mode);
int EWC_SetValue(int num, int prop, double value);
説明
制御を手動モードにし,設定値を変更します.
ウェブカメラの種類によってはサポートされていない項目もあります.
また,各項目の設定値はもともと整数値であり,範囲や刻み幅は項目毎にまちまちですが,EWCLIBでは,全項目について0.0〜100.0の割合(%)で値を指定します.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
prop:設定項目
(指定できる項目についてはEWC_GetValue()と同じです)
value:設定値(0.0〜100.0の間で指定します.単位:%)
戻り値
0:正常終了
1:カメラ番号が範囲外またはカメラは接続されていない
2:項目が範囲外
3:指定された項目はこのカメラではサポートされていない
4 or 5:その他のエラー(詳しい内容はEWC_GetLastMessage()で取得できます)
使用例
EWC_SetValue(0, EWC_WHITEBALANCE, 50.);
int EWC_SetDefault(int num, int prop);
説明
指定した項目を初期値に戻します.
ウェブカメラの種類によってはサポートされていない項目もあります.
初期値はドライバが提供する値に従います.
項目やカメラの種類によっては初期値を適用すると(暗すぎたり明るすぎたりして)画像内容が見えなくなる場合もあります.その場合はEWC_SetValue()を使用して適切な値を手動で設定してください.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
prop:設定項目
(指定できる項目についてはEWC_GetValue()と同じです)
戻り値
0:正常終了
1:カメラ番号が範囲外またはカメラは接続されていない
2:項目が範囲外
3:指定された項目はこのカメラではサポートされていない
4 or 5:その他のエラー(詳しい内容はEWC_GetLastMessage()で取得できます)
使用例
EWC_SetDefault(0, EWC_WHITEBALANCE);
int EWC_SetAuto(int num, int prop);
説明
制御を自動モードにします.
ウェブカメラの種類によってはサポートされていない項目もあります.
項目によっては自動モードにできない場合もあります.
また,指定しない他の項目も連動して自動モードに設定されることもあります.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
prop:設定項目
(指定できる項目についてはEWC_GetValue()と同じです)
戻り値
0:正常終了
1:カメラ番号が範囲外またはカメラは接続されていない
2:項目が範囲外
3:指定された項目はこのカメラではサポートされていない
4 or 5:その他のエラー(詳しい内容はEWC_GetLastMessage()で取得できます)
使用例
EWC_SetAuto(0, EWC_WHITEBALANCE);
void EWC_GetLastMessage(char *s, int size);
説明
EWCLIBの様々な関数でエラー終了となったとき,エラーの詳しい内容を文字列で得ることができます.
ただし,EWCLIBの内部で最後に実行されたDirectShow関数に限定されるので,得られたメッセージが当たっていない場合もあります.
引数
s:メッセージの文字列を格納する領域の先頭アドレス(ポインタ)
buf:領域sのサイズ(単位:バイト)
使用例
int r;
r=EWC_SetValue(0,EWC_EXPOSURE, 30.0);
if(r){
char s[160];
EWC_GetLastMessage(s,sizeof(s));
printf("%s",s);
}
int EWC_PropertyPage(int num);
説明
カメラのドライバが用意するカメラ設定のためのプロパティページを表示します.
何らかのダイアログが開かれますので,対話形式で設定内容の確認・変更ができます.
ダイアログを閉じるときは「OK」「閉じる」ボタン等をクリックしてください.
引数
num:カメラ番号 (0:1台目, 1:2台目,…,n-1:n番目)
戻り値
0:正常終了
1:EWC_Open()で初期化されていない or カメラ番号が範囲外
上記以外:プロパティのページが表示できなかった
使用例
EWC_PropertyPage(0);
画像変換
void EWC_Cnv32to24(unsigned char *dst, unsigned int *src, int pxl);
説明
32ビット画像を24ビット画像へ変換します.
ESPLIB,OpenCVと組み合わせて使うときに,あれば便利かもしれない関数です.
ESPLIBのカラー画像は32ビット形式[B][G][R][0]…です.
OpenCVのカラー画像は24ビット形式[B][G][R]…です.
<注意>画像の横ピクセル数が4の倍数ではない場合,この関数は使えません.
引数
dst:24ビット画像を格納するメモリ領域の先頭アドレス(ポインタ)
src:32ビット画像の先頭アドレス(ポインタ)
pxl:画像のピクセル数(横幅×縦幅)
使用例
unsigned int img32[320*240];
unsigned char img24[320*240*3];
EWC_Cnv32to24(img24,img32,320*240);
void EWC_Cnv24to32(unsigned int *dst, unsigned char *src, int pxl);
説明
24ビット画像を32ビット画像へ変換します.
ESPLIB,OpenCVと組み合わせて使うときに,あれば便利かもしれない関数です.
ESPLIBのカラー画像は32ビット形式[B][G][R][0]…です.
OpenCVのカラー画像は24ビット形式[B][G][R]…です.
<注意>画像の横ピクセル数が4の倍数ではない場合,この関数は使えません.
引数
dst:32ビット画像を格納するメモリ領域の先頭アドレス(ポインタ)
src:24ビット画像の先頭アドレス(ポインタ)
pxl:画像のピクセル数(横幅×縦幅)
使用例
unsigned int img32[320*240];
unsigned char img24[320*240*3];
EWC_Cnv24to32(img32,img24,320*240);
著作権・使用許諾

EWCLIB のすべての著作権はI.N.にあります.

EWCLIB はフリーソフトウェアであり配布・転載は自由です.

EWCLIB の改造・変更は自由に行っても構いません.

EWCLIB を使用した際の著作権表示は特に必要ありません.

EWCLIB の使用目的・用途は限定しません.

EWCLIB を使用したことによって生じたいかなる損害等も,作者は一切その責任を負わないこととします.
バージョンアップ履歴
ver.1.0 2005/3/29
"ewclib.h"の誕生.
Qcam Pro 4000で動作確認した.
ver.1.1 2005/4/4
Creative WebCam Pro eXのためにdisplaynameのチェックを追加した.
最大認識数を5から8へ変更
ver.1.2 2005/4/5
WideCharToMultiByte()の利用.
細かな点の見直し等.
ver.1.4 2006/12/26
Visual C++ 2005対応になった.
ver.1.5 2007/1/12
EWC_GetValue(), EWC_SetValue(), EWC_SetDefault(), EWC_SetAuto()を追加.
EWC_GetLastMessage(), EWC_PropertyPage()を追加.
EWC_IsCaptured(), EWC_GetBuffer(), EWC_SetBuffer()の追加.
ewc_time[]の追加
EWC_Open()の仕様変更.
サンプルプログラムを追加.
ver.1.6 2008/1/29
IAMVideoProcAmpやIAMCameraControlが未サポートであるUSBカメラへの対応.
ver.1.7 2009/4/30
#pragma warning(disable:4819)を外す
#pragma warning(disable:4996)を外す
Visual C++ 2008対応版.
OpenCV対応.
EWC_Cnv32to24()/EWC_Cnv24to32()追加.
サンプル追加.
ver.1.8 2009/5/13
COM初期化,終了方法の改良(OpenCV対策).
OpenCV&ESPLIBと組み合わせるサンプル追加.
ver.1.9 2010/4/15
dxtrans.hと__IDxtCompositor等へ対処を変更し,qedit.hの修正を不要にした.
EWC_Close():メモリ解放の不徹底を修正(ewc_pSampleGrabberCB[]関係).
EWC_GetLastMessage():Unicode設定とマルチバイト設定の両対応化.
ver.2.0 2010/5/13
EWC_Open()/EWC_Close()仕様変更.カメラ毎に解像度等の設定が可能となった.
EWC_Run()/EWC_Stop()/EWC_CloseAll()追加.
ewc_time[]の廃止とewc_s[].stime/ewc_s[].ftimeの追加.
作者のウェブサイト
EWCLIBの最新情報や他のライブラリがあります.
http://www.geocities.jp/in_subaru/
開発環境
OS:Windows XP Professional (SP3)
言語:Visual Studio 2008 Professional Edition
謝辞
・このEWCLIB(初期バージョン)の作成にはMicrosoft DirectXの資料以外に,下記ページの情報が大いに役立ちました.ありがとうございました.
1.http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/directshow.html
(京都大学 川嶋先生のHiroaki's Private Pageより)
2.http://www.katolab.ee.kagu.sut.ac.jp/programing/capture.htm
(東京理科大学 加藤先生の研究室ホームページより)
End of help.