Easy Web Camera LIBrary
EWCLIB 2.5
"ewclib.h" by I.N. 2018/5/29

  内容

1.はじめに
  特長動作環境環境設定インストール方法アンインストール方法使用手順

2.説明
  基本的なことメディアサブタイプについてフレームバッファについて

3.サンプルプログラム
  最も単純なプログラムESPLIBを併用した例フォーマット情報を取得してからカメラを使用する例
  各種設定の変更を行う例3台までのカメラ画像を表示する例
  300フレーム遅れた映像を表示する例CPU使用率を下げた低速度な画像入力
  OpenCVと組み合わせて使用した例OpenCV&ESPLIBと組み合わせて使用した例

4.関数リファレンス
  基本関数画像の更新確認グローバル変数フレームバッファ関連
  カメラ設定の取得・変更・保存・読込画像変換対応フォーマットの取得

5.おわりに
  著作権・使用許諾バージョンアップ履歴作者のウェブサイト開発環境謝辞


はじめに

本製品をお買い上げいただき誠にありがとうございます.(無料です)
このライブラリ関数を使えば,誰でも手軽にウェブカメラ(USBカメラ/DirectShow)画像入力プログラムを作成できます.
最近は低価格なウェブカメラがたくさん出回っていますが,それらの画像を処理するプログラムの作成に便利です.


特長

(1) 最低3つの関数を使用するだけで簡単に画像入力ができます.
(2) 複数カメラの同時接続に対応します.
(3) カメラ毎に解像度,フレームレートの設定ができます.
(4) 明るさ,コントラスト,ホワイトバランス等の取得・設定ができます.
(5) 画像の更新確認,サンプル時刻の取得,フレームバッファの変更ができます.
(6) カメラのフォーマット取得やフォーマット指定ができます.


動作環境

 OS:Windows XP/Vista/7/8/10※4
 必要ソフト:例1 Visual C++ 2008 Professional ※1
        例2 Visual C++ 2010以降 + qedit.h ※2
        例3 Visual C++ 2008 Express Edition ※3
      ※1 DirectX SDKはなくてもよい.
      ※2 Visual C++ 2010以降にはqedit.hがない.
         「Windows SDK for Windows Server 2008 and .NET Framework 3.5」にqedit.hが入っている.
      ※3 Express EditionではWindows SDKが必要.
         (Windows SDKのうち,少なくともヘッダーファイルとx86ライブラリがあればよい)

※4 補足
Windows 10のversion 1803等でEWC_Open()等のエラーコード7が出ることが確認されています.
設定→プライバシー→カメラ→「アプリがカメラにアクセスできるようにする」がオンであるか確認
してください.

動作確認したカメラ環境:
    (a) Logicool HD Pro Webcam C920 (1920x1080, 30fps可)
    (b) Microsoft LifeCam Studio (1920x1080, 30fps可, Microsoft LifeCamはインストールしない)
    (c) Logicool Qcam Ultra Vision
    (d) Logicool Qcam Pro 4000
    (e) Buffalo BSW13K08H
    (f) Buffalo PC-SDVD/U2G (USBキャプチャーケーブル)
    (g) The Imaging Source DMK22AUC03
    (*) BSW50KM01H(640x480まで), WebCam Pro, WebCam Pro eX, ノートPC内蔵カメラ
    その他: 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++ 2008の場合

 以下の方法を例として挙げておきます.(他の方法でも構いません.)

 ewclib.h を適当なフォルダに置いておく.Visual C++ で「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,ewclib.h を置いた先のフォルダ名を追加登録する.


 Visual C++ 2010以降の場合

 各プロジェクトのプロパティ(VC++ディレクトリ - インクルードディレクトリ)に,ewclib.hが置いてあるディレクトリを追加する.


アンインストール方法

 インストールの時と同じ手順で「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,自分が追加したフォルダ名の登録を削除する.


使用手順

 プログラムの先頭で ewclib.h をインクルードするだけです.
 OpenCVを併用する場合は,cv.hの方を先にインクルードしておいてください.
 ソースファイルの拡張子は .cpp にして下さい.



説明

基本的なこと

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

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

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

使用開始したカメラのデバイス名を取得するにはEWC_GetDeviceName()を使用します.

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

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

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

明るさ,コントラスト等の設定を変更するにはカメラ設定の取得・変更・保存・読込関数を使います.

EWC_Open()によってフレームバッファは自動的に確保されますが,自前で用意したフレームバッファを使用するときはフレームバッファ関連関数を使います.

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

カメラを複数接続して使用できますが,同時入力(同期した画像入力)が保証されるわけではありません.

カメラを複数使用する場合,USBバスの帯域不足のため初期化に失敗することがあります.このとき,解像度を下げたり,別のUSBポートを使用することで問題が解消する場合があります.


メディアサブタイプについて

EWCLIBではデバイス出力ピンのメディアサブタイプ(以下,デバイスフォーマット)と取得画像のメディアサブタイプ(以下,画像フォーマット)を別々に指定できます.

カメラがサポートしているデバイスフォーマットや解像度等の情報を得るにはEWC_GetFormat()を使用します.

デフォルトのデバイスフォーマットはカメラによって異なりますが,MEDIASUBTYPE_YUY2であることが多いです.カメラの使用開始後にEWC_GetDeviceSubtype()を使うと,選択されたメディアサブタイプ名を知ることができます.

ハードウェアエンコード機能を持つカメラなど,カメラによっては同じ解像度でも複数のデバイスフォーマットをサポートしている場合があります.デバイスフォーマットを指定するには次の(1)〜(3)のいずれかのようにします.
 (1)EWC_Open()より前にewc_device_typeに値を代入する
   例 ewc_device_type=MEDIASUBTYPE_MJPG;
 (2)ewclib.hのインクルードより前にEWC_DEVICE_TYPEを定義する
   例 #define EWC_DEVICE_TYPE MEDIASUBTYPE_MJPG
 (3)EWC_Open()の引数dev_mstypeを使う
   例 EWC_Open(0,640,480,30,-1,ewc_type,MEDIASUBTYPE_MJPG);

デフォルトの画像フォーマットは,OpenCVのヘッダファイル(cv.h)が読み込まれていなければMEDIASUBTYPE_RGB32,読み込まれていればMEDIASUBTYPE_RGB24になります.
 MEDIASUBTYPE_RGB32の場合,画像データの並び(バイト単位)は[B][G][R][0]です.また,MEDIASUBTYPE_RGB24の場合,画像デー タの並び(バイト単位)は[B][G][R]です.
 デフォルト以外の画像フォーマットを使用したい場合,次の(4)〜(6)のいずれかのようにします.
 (4)EWC_Open()より前にewc_typeに値を代入する
   例 ewc_type=MEDIASUBTYPE_RGB24;
 (5)ewclib.hのインクルードより前にEWC_TYPEを定義する
   例 #define EWC_TYPE MEDIASUBTYPE_RGB24
 (6)EWC_Open()の引数mstypeを使う
   例 EWC_Open(0,640,480,30,-1,MEDIASUBTYPE_RGB24);

カメラの使用開始後にEWC_GetSubtype()を使うと,選択された画像フォーマット名を知ることができます.

24ビット画像と32ビット画像の間でデータの変換を行う関数EWC_Cnv24to32(), EWC_Cnv32to24()も用意されています.

フォーマットの種類についてはDirectX SDKのヘルプでAM_MEDIA_TYPE構造体(Media Types, Video Subtypes)を参照してください.なお,カメラやPC環境(中間変換フィルタの提供状況)によって使用可能なフォーマットは異なります.


フレームバッファについて

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

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を併用した例

 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)
{
}



フォーマット情報を取得してからカメラを使用する例

 カメラがサポートするフォーマット(解像度,ビット数,フレームレート,メディアサブタイプ)の一覧を表示します.
 その後,フォーマットの番号とFPS値を入力してください.
 指定されたデバイスフォーマットで画像入力を行います.
 画像フォーマットはRGB32です.
 画像取得中にPropertyボタンを押すと,プロパティのダイアログが表示されます.
 EWCLIBとESPLIBを使用しています.



//対応フォーマットの一覧を表示し,フォーマットとFPSを指定して画像入力
//2014.1.27 (EWCLIB 2.3)
#include <esplib.h>
#include <ewclib.h>

#define MAXFORMAT 100   //取得数の上限

void ESP_Ready(void)
{
        ESP_OpenTextWindow(0,0,0,390,618);
        ESP_OpenButtonBox(256,669,1,1);
        ESP_ResizeButtonBox(143,40);
        ESP_SetButtonBoxTitle(0,"Property");
        ESP_PlaceMain(0,656);
        ESP_SetForeground(ESPMAINWINDOW);
        ESP_START= 1;
}

void ESP_Main(void)
{
        int r;
        ewc_format f[MAXFORMAT];
        int n= MAXFORMAT;       
        r= EWC_GetFormat(0,f,&n);       //フォーマット取得
        ESP_Printf("EWC_GetFormat()=%d n=%d \n",r,n);
        if(r) return;

        //フォーマット一覧の表示
        for(int i=0; i<n; i++){
            ESP_Printf("%d: %dx%d(%d) %I64d %f[fps] %s\n"
            ,i, f[i].width, f[i].height, f[i].bit, f[i].AvgTimePerFrame, f[i].fps, f[i].subtype_t);
        }

        ESP_Printf("Select[0-%d]:",n-1);
        char str[10];
        ESP_Input(str);         //フォーマットを番号で選択
        int s= atoi(str);
        int wx= f[s].width;
        int wy= f[s].height;
        double fps= f[s].fps;
        ewc_device_type= f[s].subtype; //デバイス出力ピンのフォーマット指定
        ESP_Printf("FPS=");
        ESP_Input(str);         //FPSを入力
        fps= atof(str);

        ESP_CreateImage(0,"Camera",406,0,wx,wy,100);    //ウィンドウ作成

        r=EWC_Open(0,wx,wy,fps);        //カメラ使用開始
        ESP_Printf("EWC_Open(0,%d,%d,%f)=%d\n",wx,wy,fps,r);
        ESP_Printf("EWC_GetDeviceName():%s\n",EWC_GetDeviceName(0));
        ESP_Printf("EWC_GetDeviceSubtype():%s\n",EWC_GetDeviceSubtype(0));
        ESP_Printf("EWC_GetSubtype():%s\n",EWC_GetSubtype(0));

        //画像入力&表示
        for(;;){
                if(ESP_STOP) break;
                if(EWC_IsCaptured(0)){
                        EWC_GetImage(0,ESP_VramPtr[0]);
                        ESP_Update_(0);
                        ESP_Locate(0,-1);
                        ESP_Printf("FPS:%f", 1.0/ewc_s[0].ftime);
                }
                if(ESP_GetButtonBox(0)) EWC_PropertyPage(0);
        }

        r= EWC_Close(0);                //カメラ終了
        ESP_Printf("\nEWC_Close(0)=%d\n\n",r);
        ESP_DestroyImage(0);    //ウィンドウ終了
}

void ESP_Finish(void)
{
}



各種設定の変更を行う例

 カメラの各種プロパティの表示と変更が行えます.
 また,EWC_SaveProperty(),EWC_LoadProperty()による設定値の保存,読み込みも試せます.
 ESPLIB(ver.7.9以降推奨)を併用しています.



//EWCLIBサンプル(各種設定, PropertyPage, Save, Load)
//2014.04.21 EWCLIB 2.4
//2018.05.29 EWCLIB 2.5

#include <esplib.h>
#include <ewclib.h>

const 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 320x240",0,0,320,240,100);
    // [Text Window]
    ESP_OpenTextWindow(0,0,278,374,190);
    ESP_OpenTextWindow(1,0,506,374,154);
    // [Input Box]
    ESP_OpenInputBox(390,0,17);
    ESP_ResizeInputBox(198,162);
    // [Button Box]
    ESP_OpenButtonBox(778,0,3,18);
    ESP_ResizeButtonBox(270,508);
    for(int i=0;i<17;i++){
        ESP_SetButtonBoxTitle(3*i+0,"変更");
        ESP_SetButtonBoxTitle(3*i+1,"初期値");
        ESP_SetButtonBoxTitle(3*i+2,"自動/手動");
    }
    ESP_SetButtonBoxTitle(51,"Property");
    ESP_SetButtonBoxTitle(52,"Save");
    ESP_SetButtonBoxTitle(53,"Load");
    // [Main Window]
    ESP_PlaceMain(433,540);
    ESP_SetForeground(ESPMAINWINDOW);
    ESP_SelectTW(0);

    ESP_Printf("カメラ初期化中...\n");
    int r=EWC_Open(0,320,240,30);
    if(r){
        ESP_Printf("Error %d\n",r);
        return;
    }
    ESP_Printf("デバイス名:%s\n",EWC_GetDeviceName(0));

    //バッファの変更
    EWC_SetBuffer(0,ESP_VramPtr[0]);

    ESP_START=1;
}

void ESP_Main(void)
{
    int en=0;
    char s[256];
    double t=0.;

    EWC_Run(0);
    ESP_Printf("Run\n");
    read_value();    //設定の読み出し

    for(;;){
        if(ESP_STOP)break;

        ESP_SelectTW(1);
        if(EWC_IsCaptured(0,&t)){
            ESP_Update_(0);    //画像更新
            ESP_Printf("t:%.3f s  [%4.2f fps]\n",t,1.0/ewc_s[0].ftime);
        }
        ESP_UnSelectTW();

        if(ESP_GetButtonBox(51)) EWC_PropertyPage(0), read_value();
        if(ESP_GetButtonBox(52)){
            ESP_Printf("Save...%s\n",EWC_SaveProperty(0)?"NG":"OK");
        }
        if(ESP_GetButtonBox(53)){
            ESP_Printf("Load...%s\n",EWC_LoadProperty(0)?"NG":"OK");
            read_value();
        }

        for(int b=0;b<51;b++){
            //ボタンが押されたとき
            if(ESP_GetButtonBox(b)){
                int r;
                int item=b/3;
                switch(b%3){
                    case 0:
                        r=EWC_SetValue(0,item,ESP_GetInputBoxD(item));
                        break;
                    case 1:
                        r=EWC_SetDefault(0,item);
                        break;
                    case 2:
                        int mode;
                        EWC_GetValue(0,item,&mode);
                        if(mode) r=EWC_SetManual(0,item);
                        else 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);
}



3台までのカメラ画像を表示する例

 カメラ3台まで表示します.
 カメラ毎に動作の停止と再開,プロパティページの起動が行えます.
 EWCLIBとESPLIBを使用しています.



//カメラ3台まで表示
//2014.1.17 (EWCLIB 2.2)

#include <esplib.h>
#include <ewclib.h>

#define N 3
#define WX 320
#define WY 240

void ESP_Ready(void)
{
        // [Image Window]
        ESP_CreateImage(0,"Camera 0",  0,0,WX,WY,100);
        ESP_CreateImage(1,"Camera 1",336,0,WX,WY,100);
        ESP_CreateImage(2,"Camera 2",672,0,WX,WY,100);
        // [Text Window]
        ESP_OpenTextWindow(0,523,294,208,237);
        // [Button Box]
        ESP_OpenButtonBox(301,291,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");
        // [Main Window]
        ESP_PlaceMain(14,289);
        ESP_SetForeground(ESPMAINWINDOW);

        ESP_Printf("Click 'Start'.\n");
}

void ESP_Main(void)
{
        int tgl[N], r[N];
        double fps[N];

        ESP_Printf("Starting...\n");
        r[0]=EWC_Open(0,320,240,30);
        r[1]=EWC_Open(1);
        r[2]=EWC_Open(2);

        for(int i=0; i<N; 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);
                }
        }

        ESP_Printf("EWC_GetCamera()=%d\n", EWC_GetCamera());

        EWC_CloseAll();
        ESP_Printf("fin.\n");
}

void ESP_Finish(void)
{
}



300フレーム遅れた映像を表示する例

 300フレーム(10秒)遅れたカメラ映像を表示します.
 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)
{
}



CPU使用率を下げた低速度な画像入力

 EWC_OneShot()を利用した,低速度(周期:約1秒)な画像入力の例です.
 画像入力時以外はキャプチャがポーズ状態になるためCPU使用率が下がります.
 ESPLIBを併用しています.

 プログラム起動後,「Interval 1s」ボタンをクリックすると約1秒周期の画像取得となります.



//EWC_OneShot()のサンプル
//2014.4.17 (EWCLIB 2.4)
#include <esplib.h>
#include <ewclib.h>

#define INTERVAL 1000    //取得間隔(ms)

void ESP_Ready(void)
{
    ESP_CreateImage(0,"Camera",0,0,640,480,100);
    ESP_OpenTextWindow(0,656,0,323,235);
    ESP_OpenButtonBox(669,278,1,5);
    ESP_SetButtonBoxTitle(0,"Property");
    ESP_SetButtonBoxTitle(1,"Pause");
    ESP_SetButtonBoxTitle(2,"Run");
    ESP_SetButtonBoxTitle(3,"Stop");
    ESP_SetButtonBoxTitle(4,"Interval 1s");
    ESP_PlaceMain(662,476);
    ESP_SetForeground(ESPMAINWINDOW);
    ESP_START=1;
}

void ESP_Main(void)
{
    int r;
    r= EWC_Open(0);
    ESP_Printf("EWC_Open(0)=%d\n",r);
    if(r) return;

    int updf=0;  //画像更新フラグ
    int osf=0;   //OneShot連続フラグ
    DWORD t;     //時刻(ms)用

    for(;;){     //画像入力&表示
        if(ESP_STOP) break;
        Sleep(1);    //処理が何もないときはこれでCPU使用率を下げる

        if(ESP_GetButtonBox(0)) EWC_PropertyPage(0);
        if(ESP_GetButtonBox(1)) EWC_Pause(0), osf=0;
        if(ESP_GetButtonBox(2)) EWC_Run(0), osf=0;
        if(ESP_GetButtonBox(3)) EWC_Stop(0), osf=0;
        if(ESP_GetButtonBox(4)) EWC_OneShot(0), updf=1, osf=1, t=GetTickCount();

        if(osf && GetTickCount()-t >= INTERVAL) ESP_SetButtonBox(4);  //4:Intervalボタン

        if(!osf && EWC_IsCaptured(0)) updf=1;    //画像が来た
        
        if(updf){    //画像更新
            EWC_GetImage(0,ESP_VramPtr[0]);
            ESP_Update();
            ESP_Printf("*");
            updf=0;
        }
    }

    r= EWC_Close(0);
    ESP_Printf("\nEWC_Close(0)=%d\n",r);
}

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)
{
}




関数リファレンス

基本関数

<1.デバイス番号指定>
int EWC_Open(int num, int wx=0, int wy=0, double fps=0, int device=-1, GUID mstype=ewc_type, GUID dev_mstype=ewc_device_type);
<2.デバイス名指定>
int EWC_Open(int num, int wx, int wy, double fps, char *devicename, GUID mstype=ewc_type, GUID dev_mstype=ewc_device_type);
<3.デバイス名指定(wx/wy/fps省略)>
int EWC_Open(int num, char *devicename, GUID mstype=ewc_type, GUID dev_mstype=ewc_device_type);
説明
 カメラの使用を開始します.カメラ毎に最初に呼びます.
 EWCLIBにより認識されて使用可能なカメラ台数を知りたいときは,この関数の実行後にEWC_GetCamera()を使います.
 カメラからの画像を得るにはEWC_GetImage()を使います.
 カメラの使用が終わったらEWC_Close()またはEWC_CloseAll()で終了処理を行ってください.
引数
 num:論理カメラ番号(0〜9)
   EWCLIBの他の関数でカメラを指定するために必要なカメラ番号を設定します.
   この論理カメラ番号は,必ずしも0から順に詰めて使う必要はありません.
   実際に使用される物理デバイス(カメラ)は,numに関わらず,見つかったものから順に割り当てられます.
   物理デバイスを指定したい場合は,引数deviceや引数devicenameを使用してください.
 wx,wy:画像サイズ(幅および高さ) [単位:ピクセル](この引数はオプション)
   カメラによって利用できる解像度は異なります.
   利用できない解像度を指定した場合,エラー終了となります.
   代表的なサイズとしては160x120,320x240,640x480があります.
   利用できる解像度に関する情報を知りたい場合はEWC_GetFormat()を使います.
   省略時あるいは0を指定した場合,1つ前のEWC_Open()で設定された値が適用されます.
   ただし,初めてEWC_Open()が呼ばれる場合のデフォルト値は640x480です.
   また,ここに指定されたものは,以降のEWC_Open()のデフォルト値となります.
 fps:フレームレート(この引数はオプション)
   使用するカメラによって利用できるフレームレートは異なります.
   指定した通りのフレームレートが得られるとは限りませんので注意してください.
   利用できないフレームレートを指定した場合,エラー終了となります.
   代表的なフレームレートは30や29.97や15ですが,任意の値を設定できます.
   省略時あるいは0を指定した場合,1つ前のEWC_Open()で設定された値が適用されます.
   ただし,初めてEWC_Open()が呼ばれる場合のデフォルト値は30です.
   また,ここに指定されたものは,以降のEWC_Open()のデフォルト値となります.
 device:実際に対応するカメラの物理番号(この引数はオプション)
   複数のカメラが接続されている場合で,論理カメラ番号numに対応する実際のカメラを指定する場合に使います.
   物理番号は見つかったものから順に0,1,2...と割り振られています.
   省略時あるいは-1が指定された場合,未使用のもので若い番号から使用されていきます.
   なお,EWC_GetDeviceName()を使うと使用開始されたカメラのデバイス名が取得できます.
 devicename:実際に対応するカメラのデバイス名(この引数はオプション)
   論理カメラ番号numに対応する,実際のカメラを指定する場合に使います.
   デバイス名は,Windowsデバイスマネージャーのイメージングデバイスに表示されています.
   ここに指定した文字列を含むカメラが見つかった場合,使用されます.(照合にはstrstr()が使われる)
   同じデバイス名が複数あれば,見つかった順で,未使用のものから使われます.
   なお,EWC_GetDeviceName()を使うと使用開始されたカメラのデバイス名が取得できます.
 mstype:画像フォーマット(この引数はオプション)
   デフォルトの画像フォーマットから変更したい場合,この引数を使います.
   カメラ毎に異なる画像フォーマットを指定することができます.
   ここに指定されたものは,以降のEWC_Open()のデフォルト値となります.
   この引数を使わない,グローバル変数ewc_typeを使う方法もあります.
 dev_mstype:デバイスフォーマット(この引数はオプション)
   デフォルトのデバイスフォーマットから変更したい場合,この引数を使います.
   デフォルトのデバイスフォーマットは,カメラがサポートするフォーマットの中で最初に登録されているものであり,
   カメラによって異なります.
   利用できるデバイスフォーマットに関する情報を知りたい場合はEWC_GetFormat()を使います.
   この引数を使わない,グローバル変数ewc_device_typeを使う方法もあります.
戻り値
 0:正常終了
 0以外:エラー終了
使用例
 EWC_Open(0); //画像サイズ,FPS等はデフォルト値(640,480,30)を使用
 EWC_Open(0, 320, 240, 30); //画像サイズ,FPSを指定
 EWC_Open(0, 320, 240, 30, 1); //対応カメラは2番目を指定(2台以上の接続が前提)
 EWC_Open(0, 0, 0, 0, -1, MEDIASUBTYPE_RGB24); //画像フォーマットのみ指定,あとはデフォルト
 EWC_Open(0, "HD Pro Webcam C920"); //デバイス名のみ指定
 EWC_Open(0, 320, 240, 30, "USB2.0 Camera"); //画像サイズ,FPS,デバイス名を指定
 <複数カメラの2台目以降が同じ設定なら,引数は省略できます>
 EWC_Open(0, 320, 240, 30, 0, MEDISUBTYPE_RGB24);
 EWC_Open(1);
 EWC_Open(2);


int EWC_Close(int num);
int EWC_CloseAll(void);
説明

 終了処理を行います.カメラの使用を終了させるため最後に1回呼びます.
 カメラ毎に行うのがEWC_Close()です.また,EWC_Open()で開始された使用中のカメラをまとめて終了させるのがEWC_CloseAll()です.
 この関数が実行されるまでは,他のアプリケーションはそのカメラにアクセスできません.
 EWC_CloseAll()はEWC_Open()により開始された順番の逆順で終了処理を行います.
引数
 num:論理カメラ番号(0〜9)
戻り値
 0:正常終了
 1:EWC_Open()で初期化されていない
 上記以外:エラー終了
使用例
 EWC_Close(0);
 EWC_CloseAll();


char *EWC_GetDeviceName(int num);
説明

 カメラのデバイス名(デバイスマネージャー - イメージングデバイスに表示される名前)を取得します.
 EWC_Open()で使用開始されているカメラに対して,この関数は使えます.
引数
 num:論理カメラ番号(0〜9)
戻り値
 デバイス名の文字列へのポインタ
 NULL:EWC_Open()で初期化されていない
使用例
 printf("%s\n", EWC_GetDeviceName(0));


char *EWC_GetDeviceSubtype(int num);
説明

 使用開始されたカメラのデバイスフォーマット名を取得します.
 例えば,MEDIASUBTYPE_YUY2であれば"YUY2"という文字列が得られます.
 EWC_Open()で使用開始されているカメラに対して,この関数は使えます.
引数
 num:論理カメラ番号(0〜9)
戻り値
 デバイスフォーマット名の文字列へのポインタ
 NULL:EWC_Open()で初期化されていない
使用例
 printf("%s\n", EWC_GetDeviceSubtype(0));


char *EWC_GetSubtype(int num);
説明

 使用開始されたカメラの画像フォーマット名を取得します.
 例えば,MEDIASUBTYPE_RGB32であれば"RGB32"という文字列が得られます.
 EWC_Open()で使用開始されているカメラに対して,この関数は使えます.
引数
 num:論理カメラ番号(0〜9)
戻り値
 デバイスフォーマット名の文字列へのポインタ
 NULL:EWC_Open()で初期化されていない
使用例
 printf("%s\n", EWC_GetSubtype(0));


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〜9)
戻り値
 フレームメモリの大きさ [単位:バイト]
使用例
 int size;
 size=EWC_GetBufferSize(0);


int EWC_GetImage(int num, void *buffer);
説明

 カメラの画像データを取得します.
 EWCLIB内部にあるフレームバッファから buffer へ画像データをコピーします.
 EWC_SetBuffer()によって画像データ転送先の変更が行われている場合,この関数を使用する必要はなくなります.
 EWC_SetBuffer()を使ってフレームバッファを変更している場合にこの関数を使うと,変更された方のフレームバッファから buffer へ画像データをコピーします.
引数
 num:論理カメラ番号(0〜9)
 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〜9)
戻り値
 0:正常終了
 1:EWC_Open()で初期化されていない or カメラ番号が範囲外
 上記以外:エラー終了
使用例
 EWC_Stop(0);


int EWC_Run(int num);
説明
 カメラの動作(キャプチャ)を再開させます.
 カメラに動作ランプが備わっていれば,再点灯します.
 すでに動作(再開)している場合,実行しても影響はありません.
 停止させるにはEWC_Stop()を使います.
 ポーズ(一時停止)させるにはEWC_Pause()を使います.
引数
 num:論理カメラ番号(0〜9)
戻り値
 0:正常終了
 1:EWC_Open()で初期化されていない or カメラ番号が範囲外
 上記以外:エラー終了
使用例
 EWC_Run(0);


int EWC_Pause(int num);
説明
 カメラの動作(キャプチャ)をポーズ(一時停止)させます.
 カメラの動作ランプは点灯のままですが,新しい画像は到着しなくなります.
 EWC_Stop()による停止と比較すると,EWC_Pause()の方が再開が早い特徴があります.
 再開させるにはEWC_Run()を使います.
引数
 num:論理カメラ番号(0〜9)
戻り値
 0:正常終了
 1:EWC_Open()で初期化されていない or カメラ番号が範囲外
 上記以外:エラー終了
使用例
 EWC_Pause(0);


int EWC_OneShot(int num);
説明
 カメラのキャプチャ動作を開始させ,画像を1フレーム取得した後,ポーズ状態にします.
 CPU使用率を下げることを目的とした低速度(低フレームレート)の画像入力のために使用します.
 具体的な使用例はサンプルプログラム(CPU使用率を下げた低速度な画像入力)を参照してください.
 この関数の内部では,EWC_Run(),画像2枚の入力,EWC_Pause()を順に実行しています.
 2枚取得している理由は,再開直後の1枚は画像内容が乱れているので飛ばし,2枚目を採用しているためです.
引数
 num:論理カメラ番号(0〜9)
戻り値
 0:正常終了
 1:EWC_Open()で初期化されていない or カメラ番号が範囲外
使用例
 EWC_OneShot(0);


画像の更新確認

int EWC_IsCaptured(int num [, double *t] );
説明

 新しい画像データがフレームバッファに格納されたかどうかを確認します.
 この関数が1度呼ばれた後は,新しい次の画像がフレームバッファへ格納されるまで この関数は0 を返します.
 使い方ですが,メインのプログラム中でこの関数を使って新しい画像の到着を確認し,到着したらすぐに画像データをどこか別の場所へ転送するか,何らかの画像処理を行うようにします.次の画像データが格納されるまではフレームバッファには古いデータが存在しています.
 引数 t は省略可能です.t にdouble型変数へのポインタを指定すれば,新しい画像データが取得された時刻を知ることができます.新しい画像データが到着していなかった場合,変数 t の内容は変化しません.
引数
 num:論理カメラ番号(0〜9)
 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〜9)
戻り値
 取得時刻(単位:秒)
使用例
 printf("Sample time= %f [s]\n",ewc_s[0].stime);


double ewc_s[int num].ftime;
説明

 前回のフレーム周期が格納されています.
 この変数の値はバックグラウンドで常に更新されます.
 隣接したサンプル時刻の差から計算していますので,この値の逆数を求めればフレームレート(FPS)となります.
引数
 num:論理カメラ番号(0〜9)
戻り値
 前回のフレーム周期(単位:秒)
使用例
 printf("Frame period= %f [s]\n", ewc_s[0].ftime);
 printf("Frame rate= %f [fps]\n", 1.0/ewc_s[0].ftime);


int ewc_s[int num].count;
説明

 取得したフレーム数の累計が格納されています.
 新たな画像が到着する毎に1ずつ増加します.
引数
 num:論理カメラ番号(0〜9)
戻り値
 フレーム数
使用例
 printf("Frames= %d\n", ewc_s[0].count);


GUID ewc_type;
説明

 EWC_Open()で使用されるデフォルトの画像フォーマットが記憶されています.
 値を変更することもできます.
戻り値
 EWC_Open()で使用されるデフォルトの画像フォーマット


GUID ewc_device_type;
説明

 EWC_Open()で使用されるデフォルトのデバイスフォーマットが記憶されています.
 値を変更することもできます.
戻り値
 EWC_Open()で使用されるデフォルトのデバイスフォーマット


フレームバッファ関連

int EWC_SetBuffer(int num, void *buffer);
説明

 フレームバッファを指定のアドレスへ変更します.
 指定されたフレームバッファには一定時間毎に画像データが格納(上書き)されます.
 buffer には画像データが格納されるため,あらかじめユーザ側で必要なメモリ領域を確保しておいてください.
引数
 num:論理カメラ番号(0〜9)
戻り値
 0:正常終了
 1:エラー(num値が正しくない or カメラが接続されていない など)
使用例
 int buf[640*480];
 EWC_SetBuffer(0, buf);


int EWC_GetBuffer(int num, void **buffer);
説明

 EWCLIB内部で画像格納先として登録されているフレームバッファのアドレスを取得します.
引数
 num:論理カメラ番号(0〜9)
 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〜9)
 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〜9)
 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〜9)
 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〜9)
 prop:設定項目
    (指定できる項目についてはEWC_GetValue()と同じです)
戻り値
 0:正常終了
 1:カメラ番号が範囲外またはカメラは接続されていない
 2:項目が範囲外
 3:指定された項目はこのカメラではサポートされていない
 4 or 5:その他のエラー(詳しい内容はEWC_GetLastMessage()で取得できます)
使用例
 EWC_SetAuto(0, EWC_WHITEBALANCE);


int EWC_SetManual(int num, int prop);
説明

 制御を手動モードにします.
 ウェブカメラの種類によってはサポートされていない項目もあります.
 項目によってはモード変更できない場合もあります.
引数
 num:論理カメラ番号(0〜9)
 prop:設定項目
    (指定できる項目についてはEWC_GetValue()と同じです)
戻り値
 0:正常終了
 1:カメラ番号が範囲外またはカメラは接続されていない
 2:項目が範囲外
 3:指定された項目はこのカメラではサポートされていない
 4 or 5:その他のエラー(詳しい内容はEWC_GetLastMessage()で取得できます)
使用例
 EWC_SetManual(0, EWC_WHITEBALANCE);


int EWC_SaveProperty(int num, char *filename=NULL);
説明

 すべてのカメラ設定をテキスト形式のファイルへ保存します.
 保存形式の例を下に示します.
BRIGHTNESS            = 45.777777777777779
CONTRAST              = 40.
HUE                   = -1.
SATURATION            = 66.5
SHARPNESS             = 54.
GAMMA                 = -1.
COLORENABLE           = -1.
WHITEBALANCE          = 22.199999999999999, AUTO
BACKLIGHTCOMPENSATION = 0.
GAIN                  = -1.
PAN                   = 50.
TILT                  = 50.
ROLL                  = -1.
ZOOM                  = 0.
EXPOSURE              = 61.53846153846154, AUTO
IRIS                  = -1.
FOCUS                 = 50.
 サポートされていない項目は -1と表記されます.
 また,自動モードに設定されている項目はAUTOの表記が付加されます.
 カメラ設定をファイルから読み込むには,EWC_LoadProperty()を使います.
引数
 num:論理カメラ番号(0〜9)
 filename:作成するファイル名 (省略時は [デイバス名].txt が使われます)
戻り値
 0:正常終了
 1:カメラ番号が範囲外またはカメラは接続されていない
 2:書き込み用ファイルがオープンできなかった
使用例
 EWC_SaveProperty(0, "web_camera.txt");
 EWC_SaveProperty(1);


int EWC_LoadProperty(int num, char *filename=NULL);
説明

 カメラ設定値をテキスト形式のファイルから読み込んで設定します.
 テキストファイルの形式についてはEWC_SaveProperty()を参照してください.
 カメラ設定を保存するには,EWC_SaveProperty()を使います.
引数
 num:論理カメラ番号(0〜9)
 filename:設定を読み込むファイル名 (省略時は [デイバス名].txt が使われます)
戻り値
 0:正常終了
 1:カメラ番号が範囲外またはカメラは接続されていない
 2:読み込み用ファイルがオープンできなかった
使用例
 EWC_LoadProperty(0, "web_camera.txt");
 EWC_LoadProperty(1);


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〜9)
戻り値
 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);


対応フォーマットの取得

int EWC_GetFormat(int devn, ewc_format *fmt, int *nmax);
int EWC_GetFormat(char *devicename, ewc_format *fmt, int *nmax);
説明

 カメラがサポートする解像度等の情報を取得します.
 EWC_Open(),EWC_GetDeviceName()等の他の関数とは独立しており,単独でいつでも実行できます.
 カメラの指定は,物理デバイス番号またはデイバス名で行います.
 得られた情報は構造体fmtに格納されますので,fmtの配列を事前に用意しておきます.
 また,その配列の要素数も必要です.nmaxには事前に値を入れておきます.
 構造体ewc_formatの説明は次のとおりです.
 struct ewc_format{
  int width; 画像の横幅
  int height; 画像の高さ
  int bit; 画像のビット数
  REFERENCE_TIME AvgTimePerFrame; フレーム周期(100μ秒単位)
  double fps; フレームレート(frame/s) ※単に10000000を上のAvgTimePerFrameで割った値
  GUID subtype; メディアサブタイプ
  char subtype_t[80]; subtypeに対応する文字列(例えば,MEDIASUBTYPE_RGB32なら"RGB32")
 };
 メディアサブタイプ情報は,カメラがネイティブでサポートする形式を示したものです.ewc_device_type等の使用によりここで得られたメディアサブタイプの中から指定されたデバイスフォーマットを選択して画像入力を行うこともできます.デバイスフォーマットや画像フォーマットについては「メディアサブタイプについて」を参照してください.
引数
 devn:物理デバイス番号(0〜9)
  カメラを番号で指定します.他の関数で出てくる論理カメラ番号とは異なりますのでご注意ください.
  物理デイバス番号は見つかった順(デバイスマネージャー - イメージングデバイスに現れる順)に0,1,2…と割り当てられています.
 devicename:デバイス名
  物理デイバス番号ではなく,デイバス名でカメラを探索して指定するときは,この引数を使います.
  デバイスマネージャ - イメージングデバイスに表示される名前です.
  ここに指定された文字列を含むものがあれば対象とします.
 fmt:構造体配列へのポインタ
  構造体ewc_formatを配列にしたものの先頭アドレス(ポインタ)を渡してください.
 nmax:フォーマット取得数の上限(用意された構造体配列fmtの要素数)
  上記配列の要素数を事前にこの変数に入れておき,そのポインタを渡してください.
  得られるフォーマット数が多い場合,このnmaxにより最大取得数が制限されます.
  関数実行後,nmaxには実際に格納されたフォーマット数が格納されています.
戻り値
 0:正常終了
 1:番号devnが範囲外
 上記以外:その他のエラー
使用例
 ewc_format fmt[10];
 int n=10;
 EWC_GetFormat(0, fmt, &n);
 for(int i=0; i<n; i++)
  printf("%d x %d\n", fmt[i].width, fmt[i].height);


int EWC_GUIDtoTEXT(GUID guid, char *s, int size);
説明

 メディアサブタイプで使われるGUID値に対応する文字列を取得します.
 例えば,MEDIASUBTYPE_RGB32であれば"RGB32"という文字列が得られます.
 他の関数とは独立しており,単独でいつでも実行できます.
引数
 guid:メディアサブタイプのGUID値が入った変数
 s:文字列の格納先
 size:メモリ領域sのバイトサイズ
戻り値
 0:正常終了
 1:EWCLIBで未実装のguid値だった.このときsには16進数表記した文字列が格納されます.
使用例
 char s[30];
 EWC_GUIDtoTEXT(MEDIASUBTYPE_RGB32, s, sizeof(s));




著作権・使用許諾

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の追加.

ver.2.1 2012/2/28
  EWC_Close()でメモリ解放する際,メモリリークが生じていたのを修正.

ver.2.2 2014/1/20
  EWC_Open()を一部仕様変更(デフォルト値追加,デバイス名指定,等)
  @device:pnpだけでなく@device:swも認識対象とした
  最大カメラ認識数を8台から10台へ変更
  EWC_GetDeviceName(),EWC_GetFormat()の追加

ver.2.3 2014/1/27
  デバイス出力ピンのフォーマット指定の機能を追加
  フォーマット一覧を取得するサンプルの変更
  EWC_Open()引数追加
  ewc_type,ewc_device_type(EWC_DEVICE_TYPE)追加
  EWC_GetDeviceSubtype(),EWC_GetSubtype(),EWC_GUIDtoTEXT()追加
  struct ewc_formatへsubtype_tを追加

ver.2.4 2014/4/22
  ewc_s[].count, EWC_Pause(), EWC_OneShot()の追加
  EWC_SaveProperty(), EWC_LoadProperty(), EWC_SetManual()の追加
  サンプルプログラム「各種設定の変更を行う例」の内容改訂
  サンプルプログラム「CPU使用率を下げた低速度な画像入力」の追加

ver.2.5 2018/5/29
  Visual C++ 2017対応


作者のウェブサイト
 EWCLIBの最新情報や作者の他のソフト,ライブラリがあります.
 http://www.geocities.jp/in_subaru/


作者への連絡先
 EWCLIBに関する質問やバグ情報などは下記URL(ブログ&ゲストブック)にて対応いたします.
 http://blogs.yahoo.co.jp/in_subaru/


開発環境

OS:Windows 10 Pro version 1803
言語:Visual Studio 2015/2017 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.