FAST Vision Library シリーズ
WIL チュートリアル(FVCL)
☆第2版☆
FAST Vision Library シリーズ
WIL
Ver1.1
(株)ファースト
画
(株)ファーストは、同社が提供していない装置における同社製ソフトウェア・ハードウェアの使用または信 頼性についてはいかなる責任も負いません。(株)ファーストは本書で記載されているソフトウェア・ハード ウェアの内容、商品価値、又は特定の使用目的に対する責任に対して明示又は黙示に関わらずいかなる保証も 行いません。 本書の内容は、予告なしに変更することがあります。内容の変更について、(株)ファーストはいかなる責任 も負いません。本書あるいは関連ソフトウェアにおける誤りから生じる損害について、(株)ファーストはい かなる責任も負いません。 本書の内容の一部または全部を転載することは固くお断りします。
御注意
◎Microsoft, Windows, Visual Studio, Visual C++, Visual C#, Visual Basic は、 米国 Microsoft Corporation の登録商標です。
◎.NET は、米国 Microsoft Corporation の商標です。
◎Windows XP は、米国 Microsoft Corporation の商品名です。
◎Intel, MMX, Pentium は、米国 Intel Corporation の登録商標です。 ◎その他、文中における会社名、商品名は各社の登録商標または商標です。 ◎文中では 商標シンボル((R)、(TM)、(C) 等)の表記は省略致します。
目 次
[1]
1 .開発環境の準備 ··· 1
2 .プロジェクトの作成 ··· 3
3 .ライブラリの初期化 ··· 5
4 .画像表示の準備 ··· 7
5 .画像ファイルの読み込み ··· 11
6 .画像の2値化 ··· 13
7 .カメラからの画像入力 ··· 15
8 .オーバーレイ表示 ··· 19
-1-
本書では、WIL(FVCL)の初期設定~画像の2値化までの流れについて説明します。
1.開発環境の準備
WIL を使用したプログラム開発を始める前に、まず VisualStudio のパス設定を行う必要があります。 尚、本初期設定は WIL をはじめてお使い頂く際に一度行えば結構です。
1.Microsoft Visual Studio 2005 を起動します。
2.「ツール」メニューの「オプション」を選択します。オプションダイアログが表示されます。
3.左側メニューの「プロジェクトおよびソリューション」の VC++ ディレクトリを選択します。
4.右側のドロップダウンリスト「ディレクトリを表示するプロジェクト」で、「インクルードファイル」を選 択し、WIL のインクルードファイルのパスと EVC のインクルードパスを指定します。
デフォルトでは、C:\Program Files\FAST\WIL\Include、C:\Program Files\FAST\WIL\EVC となります。
WIL チュートリアル(FVCL)
-2-
5.ライブラリのパスを通します。右側のドロップダウンリスト「ライブラリファイル」で、「ライブラリファ イル」を選択し、WIL の lib ファイルのパスを指定します。
-3-
2.プロジェクトの作成
開発環境の設定が終わったら、新規プロジェクトを作成します。 1.メニューから「ファイル(F)」->「新規作成(N)」->「プロジェクト(P)」を選択し、「新しいプロジェクト」 ダイアログを表示させます。 2.プロジェクトの種類を Visual C++に設定し、テンプレート(T)を選択します。 テンプレートに MFC アプリケーションを選択し、プロジェクト名、場所を設定して「OK」をクリックして ください。 今回は、プロジェクト名を「Sample1」とします。 アプリケーションの種類は「ダイアログベース」を指定してください。 この後に表示されるウィザードでは、変更点が無いので説明を省略します。-5-
3.ライブラリの初期化
準備が完了したら早速コーディングを始めましょう。 1.ソリューションエクスプローラより Sample1Dlg.cpp を開き、WIL ライブラリの初期化(ライセンスチェッ ク)関数を記述します。 ※WIL のほとんどの機能は、この処理を行わなければ使うことができません。 ※ OnInitDialog()は、MFC でダイアログ生成した際必ず呼び出されます。 2.EVC ライブラリのリソースを連結します。 ※EVC ライブラリを使うには、必ずこの処理が必要です。BOOL CSample1Dlg CSample1Dlg::OnInitDialog() {
//~~~~~~中略~~~~~~~
// TODO: 初期化をここに追加します。
FVCL::InitVisionLibrary(); // WIL 初期化
BOOL CSample1Dlg CSample1Dlg::OnInitDialog() {
//~~~~~~中略~~~~~~~
// TODO: 初期化をここに追加します。
FVCL::InitVisionLibrary(); // WIL 初期化
-7-
4.画像表示の準備
1. リソースビューより、IDD_SAMPLE1_DIALOG をダブルクリックし表示します。
2. ツールボックスより「Picture Control」を選択し、IDD_ SAMPLE1_DIALOG に貼り付けます。
ここが画像表示領域とな ります
-8-
3. 貼り付けた Picture Control のプロパティを表示し、ID を任意の名称に変更します。
本チュートリアルでは ID を「IDC_STATIC_IMAGE_VIEW」 と変更します
-9-
4. コントロールの変数を追加します。貼り付けた Picture Control を右クリックして「変数の追加(B)」を選択し、変数追加ウィザードを表示 します。変数の種類を CStatic に、任意の変数名を記入して完了をクリックします。本チュートリアルで は、変数名を m_dummy とします。
-10-
5.コーディングを行います。 ソリューションエクスプローラより Sample1Dlg.h を開き、コードの上の方に、WIL ヘッダファイルのイン クルード宣言を行います。 6.Sample1Dlg.h の下の方に、画像メモリ管理クラス、画像ビュークラス、オーバーレイクラスの変数を宣言 します。 #pragma once #include "FVCLbasic.h" // 画像処理クラスヘッダ #include "EVCbasic.h" // GUI ライブラリヘッダafx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP()
FVCL::CFvImage m_image; //画像メモリ管理クラス CEvView m_view; //画像ビュークラス
-11-
5.画像ファイルの読み込み
1.ツールボックスより、ダイアログへボタンコントロールを追加し、プロパティより Caption を「bmp ファイ ルの読込」、ID を「IDC_BUTTON_LOAD」とします。 2.「bmp ファイルの読込」ボタンをダブルクリックし、BN_CLICKED イベントハンドラ (OnBnClickedButtonLoadImage) を作成します。-12-
3. OnBnClickedButtonLoadImage()内の処理を追加します。 4. プログラムを保存し、ビルド・実行してみましょう。 「bmp ファイルの読込」をクリックし、任意の Gray 画像を ロードします。 左図のように画像が表示されれば成功です。 画像上で左クリックし、Ctrl キー+マウスホイールで画像の 倍率が変わることを確認しましょう。補足として、画像表示の操作を行うライブラリをいくつか挙げます。
・ 表示倍率の縮小:CEvView::DoReduce() ・ 表示倍率の拡大:CEvView::DoExpand() ・ 表示倍率をビューに合わせる:CEvView::FitImageSize() ・ 処理範囲設定:CEvView::SetCursorType(FVCL::CursorType::PROCAREA) ・ Aスコープ表示:CEvView::SetCursorType(FVCL::CursorType::ASCOPE) void CSample1Dlg::OnBnClickedButtonLoadImage() { FVCL::CFvImageFileBmp pImageFile;//BMP ファイル読み込みクラスのオブジェクト生成 CFileDialog dlg(TRUE,_T("bmp"),NULL,OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, _T("Imagefile(*.bmp)|*.bmp;|All files(*.*)|*.*||"), this); if(IDOK == dlg.DoModal()){
if( ! pImageFile.Load(dlg.GetFileName(), &m_image)) //画像のロード
{ MessageBox(_T("ファイルロード失敗")); } else { m_view.SetImage(&m_image); //画像をビューに設定します m_view.Update(true); //ビューの表示を更新します } } }
-13-
6.画像の2値化
Sample1 でロードした画像を2値化してみましょう。 1.画像の2値化を行うには、2値化した画像を保存するメモリを新たに追加する必要があります。 Sample1Dlg.h 内で、下記のように画像メモリを一枚宣言してください。 2.次に、画像読込ボタンのときと同じ要領で、ダイアログにボタンを追加し、名前を「画像の2値化」、ID を「IDC_BUTTON_BINARIZE」とします。 3.「画像の2値化」ボタンのイベントハンドラを追加し、OnBnClickedButtonBinarize()内の処理を追加します。 FVCL::CFvImage m_image; CEvView m_view; FVCL::CFvOverlay* m_overlay; FVCL::CFvImage m_imagebin; //2値画像用メモリ void CSample1Dlg::OnBnClickedButtonLoadImage() { FVCL::Conversion::CFvBinarize binarize; //2値化クラスのオブジェクト生成 binarize.SetSrcImage(0,&m_image); //入力画像の設定 binarize.SetDstImage(0,&m_imagebin); //出力画像の設定 if(binarize.Validate()) //出力画像を入力画像の型に合わせる { binarize.SetThreshold(100); //2値化閾値の設定 binarize.Execute(); //2値化実行 m_view.SetImage( &m_imagebin ); m_view.Update(true); } else {int error_code = binarize.GetErrorCode(); //エラーコードの取得
if(error_code == FVCL_ErrorCode::HAVE_NOT_IMAGE) {
MessageBox(_T("入力画像または出力画像が設定されていません。")); }
else if(error_code == FVCL_ErrorCode::FAILED_TO_ALLOCATE ) {
MessageBox(_T("メモリが不足しています。")); }
}
-14-
Validate()を行うと、出力画像の大きさが、強制的に入力画像の大きさに合わせられますので、自分で画像メモ リのサイズを合わせる必要がありません。 又、Validate()はエラーコードを取得できますので、GetErrorCode()によってエラーコードを取得しています。 ※Execute()もエラーコード取得できますがこの例では行っていません。エラーを取得できるメソッドは WIL リファ レンスマニュアルに記述がありますのでご覧下さい。 すべての画像処理の実行は Execute()メソッドで行います。 たとえば、2値計測の場合は FVCL::CFvBlob::Execute()、グレイサーチの場合は FVCL::CFvGSearch::Execute()のようになります。 本ライブラリの画像処理は、下記の手順を基本とします。 基本画像操作※ 画像解析※ 備考 入力設定 SetSrcImage SetSrcImage 処理対象画像を設定します。 出力設定 SetDstImage SetResult 出力画像または出力データ配列を受 け取るオブジェクトを設定します。 パラメータ調整 クラス毎に異なります 有効性検査 IsValid IsValid 入出力の有効性を検査します。 有効化 Validate - 出力画像のサイズや画像種別を調整 します。 実行 Execute Execute ※ 基本画像操作・・・階調変換、フィルタ、アフィンなどの画像操作ライブラリを指します ※ 画像解析・・・・・2値計測、サーチ、エッジ取得などの計測ライブラリを指します。 4.プログラムを保存し、ビルド・実行してみましょう。 画像ロード後、「画像の2値化」ボタンを押し、 左図のように画像が表示されれば成功です。-15-
7.カメラからの画像入力
Sample1 では、BMP ファイルのロードを行って画像処理を行っていましたが、カメラからの画像入力を行って 画像処理をできるようにしてみましょう。 本チュートリアルでは、画像入力ボード FVC05 を用いて画像入力を行います。RICE-001(a/b)や FVC06 を使用 する場合も同様の方法で使用することが可能ですが、画像入力ボードごとに機能が異なるため、設定できる関 数等が異なります。各画像入力ボードの機能詳細はリファレンスマニュアルをご参照ください。 1. カメラから画像入力を行うためには、画像入力ボード制御クラス(FVCL::CFvVideoFVC05)のインスタンスを 用意します。FVCL::CFvVideoFVC05 を使用するためには、インクードファイル FVCLvideo.h をインクルー ドする必要があります。下記の 1 行を Sample1Dlg.h に追加してください。 FVCL::CFvVideoFVC05 のインスタンスを生成します。Sample1Dlg.h 内に下記の一行を追加してください。 2. 画像入力ボードをオープンし、カメラ設定ファイルからパラメータを読み込みます。 画像入力ボードのオープンとは、PC 内にある画像入力ボードを探し、引数で指定したボードを他のソフト ウェアから制御できないように占有する処理のことを言います。 画像入力ボードのオープンに成功したら、使用するカメラに合わせたパラメータを画像入力ボードに設定 します。画像入力ボードの設定は複雑であるため、FAST からカメラ設定ファイルが提供されています。カ メラ設定ファイルは WIL インストール先の”\WIL\CameraFiles\”フォルダ配下に入れられています。使用 するカメラ設定ファイルを CFvVideoFVC05 に読み込ませることで、カメラに合わせたパラメータで画像入 力ボードが初期化されます。 画像の2値化ボタンのときと同じ要領で、ダイアログにボタンを追加し、名前を「ビデオオープン」、ID を IDC_BUTTON_VIDEO_OPEN」とします。 「ビデオオープン」ボタンのイベントハンドラを追加し、OnBnClickedButtonVideoOpen()内の処理を追加し ます。 FVCL::CFvImage m_image; CEvView m_view; FVCL::CFvOverlay* m_overlay; FVCL::CFvImage m_imagebin; //2値画像用メモリ FVCL::CFvVideoFVC05 m_video; //画像入力ボード制御 #include “FVCLvideo.h”-16-
void CSample1Dlg::OnBnClickedButtonVideoOpen() { if(true == m_video.Open(-1, 0)) //(1)画像入力ボードのオープン { FVCL::CFvString path; path=_T("C:\\Program Files\\FAST\\WIL\\CameraFiles\\FVC05\\"); path+=_T("FVC05_XC-HR50_HR57.ini"); // XC-HR50, XC-HR57用カメラ設定ファイ ルif( false == m_video.LoadIniFile(path) ) //(2)カメラ設定ファイル読み込み
{
FVCL::CFvString err_msg;
err_msg.Format( _T("LoadIniFile Error : code=%d"), m_video.GetErrorCode() ); MessageBox( err_msg ); } else { // (3)カメラの画像サイズと画像メモリのサイズを合わせる m_video.ChangeImageSize(&m_image); MessageBox( _T("画像入力ボードオープン成功") ); } } else { switch( m_video.GetErrorCode() ) { case FVCL_ErrorCode::ALREADY_OPENED: MessageBox(_T("既にオープンされています")); break; case FVCL_ErrorCode::INVALID_PARAMETER: MessageBox(_T("引数が間違っています")); break; case FVCL_ErrorCode::FAILED_TO_ALLOCATE: MessageBox(_T("メモリの確保が失敗しました。")); break; case FVCL_ErrorCode::FAILED_TO_OPEN: MessageBox(_T("キャプチャボードのオープンに失敗しました。")); break; } } }
-17-
このプログラムでは次のことが行われています。 (1)画像入力ボードのオープン 画像入力ボードを探し、他のインスタンスから制御できないように占有するのがオープンの処理内容で、 Open 関数を用いて行います。Open 関数は画像入力ボードに応じて、関数が異なります。 関数 第 1 引数 第 2 引数 第 3 引数 RICE-001(a/b) FVC05 Open(INT,INT) ボード ID 無視 - FVC06 Open(INT,INT) ボード ID 無視 - Open(INT,INT,INT) ボード ID コンフィグレーション チャネル (2)カメラ設定ファイルの読み込み 使用するカメラのカメラ設定ファイルを指定します。本チュートリアルでは XC-HR50,XC-HR57 用カメラ 設定ファイルを指定しています。 (3)カメラから入力される画像サイズと、画像メモリのサイズを一致させる 画像入力を行う際に、カメラから入力される画像サイズと、画像メモリのサイズが不一致だった場合、 エラーとなってしまうため、ChangeImageSize 関数を用いて、画像メモリサイズをカメラの画像サイズ に合わせます。 3. 画像入力ボタンを作り、ボタンが押された瞬間にカメラから画像入力を行うようにします。ビデオオープ ンボタンのときと同じ要領で、ダイアログにボタンを追加し、名前を「ビデオ入力」、ID を IDC_BUTTON_VIDEO_INPUT」とします。 「ビデオオープン」ボタンのイベントハンドラを追加し、OnBnClickedButtonVideoInput()内の処理を追加 します。 画像入力を開始する関数はいくつか用意されており、用途に応じて使い分けていただく必要があります。 関数名 機能 関連関数 GrabImageSync 1 フレーム取り込み (取込完了まで関数から抜けてきません) AbortCapture(*1) GrabImageASync 1 フレーム取り込み (取込開始命令を画像入力ボードに行った 後、即関数から抜けてきます) GrabWait GrabStatus AbortCapture(*1) ContinuousGrab(*1) 連続取込 MemoryLock(*1) MemoryUnlock(*1) AbortCapture(*1) StopCapture(*1) NotifyCaptureNo(*1) QueryCaptureNo(*1) (*1)RICE-001(a/b)は未対応-18-
本チュートリアルでは、GrabImageSync 関数を用いて画像入力を行い、取り込みが行われた画像を画面に 表示します。 4. プログラムを保存し、実行してみましょう。ビデオオープン後に、ビデオ入力ボタンを押すと画像入力が 行われ、画像が表示されれば成功です。 void CSample1Dlg::OnBnClickedButtonVideoInput() {if( true == m_video.GrabImageSync( &m_image )) //画像入力
{ // 描画 m_view.SetImage(&m_image); m_view.Update(true); } else { FVCL::CFvString err_msg;
err_msg.Format( _T("GrabImageSync Error : code=%d"), m_video.GetErrorCode() ); MessageBox( err_msg );
}
-19-
8.オーバーレイ表示
1.オーバーレイに対して図形や文字を表示することができます。処理範囲や処理結果を画面上に表示させて視 覚的に判りやすくさせることができます ソリューションエクスプローラより Sample1Dlg.h を開き、コードの上の方に、WIL ヘッダファイルのイン クルード宣言を行います。 2.Sample1Dlg.h の下の方に、画像メモリ管理クラス、画像ビュークラス、オーバーレイクラスの変数を宣言 します。 3.Picture Control 上に、画像ビューを作成し、オーバーレイを生成します。 3.。afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() FVCL::CFvImage m_image; //画像メモリ管理クラス CEvView m_view; //画像ビュークラス FVCL::CFvOverlay* m_overlay; // オーバーレイクラス #pragma once #include "FVCLbasic.h" // 画像処理クラスヘッダ
#include "EVCbasic.h" // GUI ライブラリヘッダ
BOOL CSample1Dlg::OnInitDialog() {
//~~~~~~中略~~~~~~~
// TODO: 初期化をここに追加します。
FVCL::InitVisionLibrary(); // WIL 初期化
FVCL::EVCbasic::DLLChainResource( NULL ); // EVC リソースの接続
CRect rect; //四角形データ
m_dummy.GetWindowRect( &rect ); //ピクチャーコントロールの範囲を取得
ScreenToClient( &rect ); //rect をクライアント座標(ダイアログ上の座標)に変換
m_view.Create( IDC_STATIC_IMAGE_VIEW, rect, this ); //画像ビューの生成
m_overlay = m_view.m_display.CreateOverlay(); //オーバーレイの生成
m_view.SetFocusOption(FVCL::FocusOption::LDOWN); //ビュー上での左クリック有効
-20-
CEvView FVCL::CFvDisplay 画像ビュー :指定した画像を表示する機能です。画像のスクロール、ボタンクリック、オーバーレイ 表示機能などを持ちます。 オーバーレイ :線や文字などの図形を、画像に重ねて表示するための透明のレイヤーです。 画像の表示や、図形の表示はオーバーレイ上に書き込みますので、オーバーレイは必ず生成する必要がありま す。ここで、 m_overlay = m_view.m_display.CreateOverlay() とありますが、これは“CEvView クラスが内包する FVCL::CFvDisplay クラス内の CreateOverlay メソッドを呼び出す” というコードになります。
CFvDisplay クラスにスクロールバーやオーバレイ描画機能を付加し、使い易くしたのが CEvView となります。 FVCL::CFvDisplay の操作は、CEvView のメンバ変数「m_display」から操作します。
m_view.SetFocusOption(FVCL::FocusOption::LDOWN)は行わなくても動作上問題ありません。 1.今までと同じ要領で、ダイアログにボタンを追加し、名前を「描画」、ID を IDC_BUTTON_DRAW」とします。 2.描画したい図形を宣言します。今回は FAST マークの周囲に矩形をその中心に十字線を表示させます。 void CDrawLineDlg::OnBnClickedDraw () { FVCL::CFvGdiRectangle* GdiRect; //オーバーレイ表示用直線オブジェクト FVCL::CFvGdiLineSegment* GdiLineSeg_hrz; FVCL::CFvGdiLineSegment* GdiLineSeg_vrt; FVCL::CFvRectangle Rectangle; //矩形 FVCL::CFvLineSegment LineSeg_hrz; //横線 FVCL::CFvLineSegment LineSeg_vrt; //縦線
-21-
// 描画線座標を設定 Rectangle.st.x = 100; Rectangle.st.y = 100; Rectangle.ed.x = 350; Rectangle.ed.y = 350;LineSeg_hrz.st.x = (Rectangle.ed.x + Rectangle.st.x)/2-10; LineSeg_hrz.st.y = (Rectangle.ed.y + Rectangle.st.y)/2; LineSeg_hrz.ed.x = (Rectangle.ed.x + Rectangle.st.x)/2+10; LineSeg_hrz.ed.y = (Rectangle.ed.y + Rectangle.st.y)/2; LineSeg_vrt.st.x = (Rectangle.ed.x + Rectangle.st.x)/2; LineSeg_vrt.st.y = (Rectangle.ed.y + Rectangle.st.y)/2-10; LineSeg_vrt.ed.x = (Rectangle.ed.x + Rectangle.st.x)/2; LineSeg_vrt.ed.y = (Rectangle.ed.y + Rectangle.st.y)/2+10;
//オーバーレイへの図形新規作成 GdiRect = static_cast<FVCL::CFvGdiRectangle*>(m_overlay->DrawFigure(Rectangle)) GdiLineSeg_hrz = static_cast<FVCL::CFvGdiLineSegment*>(m_overlay->DrawFigure(LineSeg_hrz));。 GdiLineSeg_vrt = static_cast<FVCL::CFvGdiLineSegment*>(m_overlay->DrawFigure(LineSeg_vrt));
if( GdiLineSeg_hrz != NULL && GdiLineSeg_vrt != NULL) { FVCL::CFvGdiPen pen; pen.SetCol or(RGB(255,0,0)); //線色の設定 pen.SetWidth(2); //線幅の設定 GdiLineSeg_hrz->SetPen(pen); //ペン設定の反映 GdiLineSeg_vrt->SetPen(pen); pen.SetColor(RGB(0,0,255)); //線色の設定 GdiRect->SetPen(pen); } m_view.ReDraw(); //描画更新 }
-22-
3.描画をクリックして、矩形と十字が表示されれば成功です。WILチュートリアル(FVCL) Vol.2
2008 年 10 月 第 2 版 第 1 刷発行発行所 株式会社ファースト
本 社 〒242-0001 神奈川県大和市下鶴間 2791-5 ユーザ・サポートFAX 046-272-8692
TEL 046-272-8691E-mail : [email protected]
B-001989