wil チュートリアル (visual c++ 2005 mfc ベース …...4.貼り付けたpicture control...

18
WIL チュートリアル (Visual C++ 2005 MFC ベースアプリケーション) この「WIL チュートリアル(Visual C++ 2005)」では、 Visual C++ 2005 (以下 Visual C++を使用して、WIL アプリケーションを作成するための手順を説明します。 ここでは例題として、「画像読込み」「ソーベルフィルタ」「画像の表示」を行う MFC ダイ アログベースアプリケーションを作成します。 0Visual C++ 2005 の設定 WIL を使用したプログラムを始める前に、Visual C++のディレクトリ設定を行う必要が あります。下記手順に従って設定を行ってください。 尚、本初期設定は WIL をはじめてお使い頂く際に一度行えば結構です。一度、設定を行う と保存されますので次回からは再度、設定していただく必要はありません。 1. Microsoft Visual Studio 2005 を起動します。 2. 「ツール」メニューの「オプション」を選択します。オプションダイアログが表示されま す。

Upload: others

Post on 13-Mar-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

WILチュートリアル (Visual C++ 2005 MFCベースアプリケーション)

この「WILチュートリアル(Visual C++ 2005)」では、Visual C++ 2005(以下 Visual C++)を使用して、WILアプリケーションを作成するための手順を説明します。 ここでは例題として、「画像読込み」「ソーベルフィルタ」「画像の表示」を行うMFC ダイアログベースアプリケーションを作成します。 0. Visual C++ 2005の設定 WILを使用したプログラムを始める前に、Visual C++のディレクトリ設定を行う必要があります。下記手順に従って設定を行ってください。 尚、本初期設定はWILをはじめてお使い頂く際に一度行えば結構です。一度、設定を行うと保存されますので次回からは再度、設定していただく必要はありません。 1. Microsoft Visual Studio 2005 を起動します。 2. 「ツール」メニューの「オプション」を選択します。オプションダイアログが表示されます。

3. 左側メニューの「プロジェクトおよびソリューション」の VC++ ディレクトリを選択します。

4. 右側のドロップダウンリスト「ディレクトリを表示するプロジェクト」で、「インクルードファイル」を選択し、WILのインクルードファイルのパスと EVCのインクルードパスを指定します。標準のディレクトリ構成でインストールした場合には、C:¥Program Files¥FAST¥WIL¥Include、C:¥Program Files¥FAST¥WIL¥EVC になります。

5. ライブラリのパスを通します。右側のドロップダウンリスト「ライブラリファイル」で、「ライブラリファイル」を選択し、WILの libファイルのパスを指定します。 標準のディレクトリ構成でインストールした場合には、C:¥Program Files¥FAST¥WIL¥Libです。

1. プロジェクト作成 MFCベースの新規プロジェクトを作成します。 1.メニューから「ファイル(F)」->「新規作成(N)」->「プロジェクト(P)」を選択し、「新しいプロジェクト」ダイアログを表示させます。

2.プロジェクトの種類を Visual C++に設定し、テンプレート(T)を選択します。 テンプレートにMFCアプリケーションを選択し、プロジェクト名、場所を設定して「OK」をクリックしてください。 今回は、ダイアログベースで「Filter」という名称のプロジェクトを作成します。アプリケーションの種類に「ダイアログベース」を指定し、プロジェクト名に「Filter」と入力し「OK」ボタンでウィザードを進めます。この後に表示されるウィザードでは、変更点が無いので

説明を省略いたします。

2. 画像表示領域の作成 1.右側のメニューから、リソースビューを選び IDD_FILTER_DIALOGを表示させます。 2.ダイアログエディタで Picture Controlを選択し、IDD_FILTER_DIALOGに貼り付けます。本チュートリアルでは、この張り付けた Picture Control内に画像を表示させます。

3.貼り付けた Picture Controlのプロパティを表示させ、IDを任意の名称に変更します。 本チュートリアルでは「IDC_STATIC_IMAGE_VIEW」と変更します。

4.貼り付けた Picture Controlを右クリックして「変数の追加(B)」を選択し、変数追加ウィザードを表示します。変数の種類を CStatic に、任意の変数名を記入して完了をクリックします。本チュートリアルでは、変数名をm_dummyとします。

3. GUIの作成

Picture Controlを貼り付けたダイアログにボタンコントロールを二つ追加します。それぞれのボタンに、画像ロードとフィルタ実行を割り当てます。 ファイルロードを行うボタンの IDを IDC_BUTTON_LOADとし、フィルタ実行ボタンをIDC_BUTTON_FILTER_EXECとします。

4. コードの記述(インクルード) ダイアログのヘッダファイルにWILのヘッダファイルをインクルードします。 CFilterDlgのヘッダファイル FilterDlg.hの上の方に、インクルード宣言を行います。 FVCLbasic.h:画像メモリクラスやフィルタクラスなど、基本的な画像処理を行うために必要なヘッダです。 FVCLpng.h:PNGファイルをロード/セーブするのに必要です。PNGファイルを使用しない場合はインクルードする必要はありません。 FVCLjpg.h:JPEG ファイルをロード/セーブするのに必要です。JPGE ファイルを使用しない場合はインクルードする必要はありません。 ※PNGと JPEGは libjpeg、 libpngというオープンソースを使用しております。したがって上記ファイル

をWILアプリケーションで使用する際には、それらの使用許諾条件を満たす必要があります。

EVCbasic.h:表示を行う CEvViewというクラスを使用する際に必要です。 CEvViewは、スクロールバー付きの表示クラスです。 5. コードの記述(変数宣言) CFilterDlg クラス内で使用できる変数を宣言します。今回のサンプルはフィルタを行います。フィルタでは、入力画像と結果画像の二つの画像が必要であるため、画像メモリの宣

言を行います。FilterDlg.hのクラス内に、下記に示す二つの宣言を行ってください。

#pragma once #include "FVCLbasic.h" // 画像処理用ヘッダ #include "FVCLpng.h" // pngファイル用ヘッダ #include "FVCLjpg.h" // jpegファイル用ヘッダ #include "EVCbasic.h" // 画像表示用ヘッダ

また、画像表示を行うクラス CEvViewの宣言を行います。 上記の画像メモリ宣言の下に、下記の宣言を追加してください。

afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public :

FVCL::CFvImage m_SrcImage; // 入力画像 FVCL::CFvImage m_DstImage; // 結果画像

public : FVCL::CFvImage m_SrcImage; // 入力画像 FVCL::CFvImage m_DstImage; // 結果画像 CEvView m_view; // 表示クラス

6. コードの記述(WILの初期化) MFCダイアログを使用した場合、ダイアログの生成時にOnInitDialog()が呼び出されます。WILの初期化を行うために、CFilterDlg::OnInitDialog()内で初期化に関するコードを記述します。 WIL ライブラリを使用するためには必ず、FVCL::InitVisionLibrary(); を最初に呼び出さなければいけません。そこで、CFilterDlg::OnInitDialog()内に次のように記述します。 また、CEvView m_view;の初期化を行います。CEvViewはMFCから派生したライブラリとなっております。OnInitDialog内で、m_viewのウィンドウを生成します。m_viewのウィンドウは Picture Box(CStatic m_dummy;)の子ウィンドウとしてフレームレスのウィンドウとします。

BOOL CFilterDlg::OnInitDialog() { //~~~~~~中略~~~~~~~

// TODO: 初期化をここに追加します。 // WIL初期化 FVCL::InitVisionLibrary();

BOOL CFilterDlg::OnInitDialog() { //~~~~~~中略~~~~~~~

// TODO: 初期化をここに追加します。 // WIL初期化 FVCL::InitVisionLibrary()

// EVCリソースの接続

FVCL::EVCbasic::DLLChainResource( NULL ); // Viewの生成

CRect rect; m_dummy.GetWindowRect( &rect ); ScreenToClient( &rect ); m_view.Create( IDC_STATIC_IMAGE_VIEW, rect, this );

EVCbasic.dll の DLLChainResource を実行する必要があります。 この関数は、EVCbasic の リソースをアプリケーションのリソースチェインに 連結する為の初期化処理です。 引数に NULL を指定すると EVCbasic に埋め込まれた日本語リソースを使用します。 7. コードの記述(画像ファイル読み込み) ファイル読み込みを作成します。CFilterDlg の Load ボタンをダブルクリックし、クリックメッセージを受け取る関数、void CFilterDlg::OnBnClickedButtonLoad()を生成してください。 この関数内で、ボタンが押された時の動作を記述します。 本チュートリアルでは、ファイルダイアログを表示し、選択されたファイルの拡張子から

BMP/JPEG/PNG のファイルを判断し、ロードを行うように記述します。ロードされた画像はm_SrcImageに格納され、それを画面上に表示します。 また、処理結果画像サイズをロードした画像と同じサイズに変更します。

void CFilterDlg::OnBnClickedButtonLoad() {

FVCL::CFvImageFile* pImageFile=NULL; // ファイル読み込み親クラス

CFileDialog dlg(TRUE, _T("bmp"), NULL, OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, _T("Imagefile(*.bmp,*jpg,*png)|*.bmp;*.jpg;*.png|All files(*.*)|*.*||"), this);

if( IDOK == dlg.DoModal() ) {

// 拡張子の取得 CString ext = dlg.GetFileExt();

// 拡張子を元にクラスの生成 if( 0==ext.CompareNoCase( _T("BMP") ))

pImageFile = new FVCL::CFvImageFileBmp; // BMPファイルクラスの生成 else if( 0==ext.CompareNoCase( _T("JPG") ))

pImageFile = new FVCL::CFvImageFileJpg; // JPEGファイルクラスの生成 else if( 0==ext.CompareNoCase( _T("PNG") ))

pImageFile = new FVCL::CFvImageFilePng; // PNGファイルクラスの生成 else {

MessageBox( _T("サポート対象外の拡張子です") ); return;

}

画像の表示は、CEvView::SetImage()で表示を行いたい画像メモリを指定し、ReDraw()関数で再描画を行います。 ※リテラル文字列を_T()で囲っていますが、これは、MBCSでも Unicode でもコンパイルが通

るようにするためです。

8. コードの記述(フィルタ実行) 入力画像にフィルタリングを行った結果を結果画像に格納する処理コードを記述します。

本チュートリアルでは、ソーベルフィルタ(FVCL::Filter::CFvSobelFilter)を用いたフィルタリングを行います。 また、フィルタ実行後の結果画像を画面上に表示します。 リソースエディタで、「Filter」ボタンをダブルクリックし、

// Load if( !pImageFile->Load( dlg.GetFileName(), &m_SrcImage ) )

MessageBox( _T("ファイルロード失敗") ); else {

// 画面上に表示 m_view.SetImage( &m_SrcImage ); m_view.ReDraw( false );

// 結果画像を入力画像と同じサイズに指定します。 // (入力画像の処理範囲==結果画像の処理範囲)であれば良いのですが、 // (入力画像の処理範囲>結果画像サイズ)となった場合、 // 必ず (入力画像の処理範囲!=結果画像の処理範囲)と // なってしまうため、本プログラムでは同じサイズにしています。 m_DstImage.SetSize( m_SrcImage.GetHorzSize(), m_SrcImage.GetVertSize(),

FVCL::ImageType::UC8, 1 ); // 8bit濃淡画像 }

// メモリ解放 if(pImageFile) delete pImageFile;

} }

void CFilterDlg::OnBnClickedButtonFilterExec()を生成してください。この関数内にFilter実行のソースを記述します。 処理を実行する場合は、画像メモリに対して処理範囲を指定します。WIL では処理範囲は画像メモリが持っており、画像処理クラスは画像メモリの処理範囲のみ実行します。 画像処理を実行するためには、Execute() 関数を呼び出します。 Execute() を行う前に SetSrcImage(), SetDstImage() 関数で処理対象の画像を設定しておきます。 また、各画像処理クラスには、 IsValid() 関数が用意されており、SetSrcImage(), SetDstImage() で指定された画像に対して、画像処理ができるかどうかを判別することが可能です。 (1) ソーベルフィルタクラスの宣言です。 (2) 処理範囲を設定します。ここでは、GetHorzSizeメソッド、GetVertSizeメソッドを使い、画像メモリの横方向画素数と縦方向画素数を取得し、その値を入力しています。

(3) m_SrcImageの処理範囲を適用します。

void CFilterDlg::OnBnClickedButtonFilterExec() {

// ソーベルフィルタクラス宣言 FVCL::Filter::CFvSobelFilter SobelFilter; ―――――(1)

// 処理範囲の設定 // 元画像の前面を処理し、結果画像の全面に格納します。 m_SrcImage.SetWindow( 0, 0, m_SrcImage.GetHorzSize(),

m_SrcImage.GetVertSize() ); ―――――(2) m_DstImage.SetWindow( m_SrcImage.GetWindow() ); ―――――(3)

// フィルタ入力画像 SobelFilter.SetSrcImage( 0, &m_SrcImage ); ―――――(4) // フィルタ結果画像 SobelFilter.SetDstImage( 0, &m_DstImage ); ―――――(5) // ソーベルフィルタパラメータ SobelFilter.SetCalcMode( FVCL::Filter::SobelCalcMode::XYMode ); ―――――(6)

(4) フィルタリングを行う画像を設定します。 (5) フィルタリング結果を格納する画像を設定します。 (6) ソーベルフィルタを行う際のパラメータを設定します。

if( SobelFilter.IsValid() ) {

// ソーベルフィルタ実行 if( SobelFilter.Execute() ) {

// 結果画像を画面上に表示 m_view.SetImage( &m_DstImage ); m_view.ReDraw( false );

} else { CString str; // エラーコードを取得しエラー出力メッセージを作成 str.Format( _T("CFvSobelFilter Execute() Error (%d)"),

SobelFilter.GetErrorCode() ); // メッセージボックスでエラーコードを出力

MessageBox( str, _T("Error") ); }

} else { CString str; str.Format( _T("CFvSobelFilter.IsValid() 入力画像または出力画像が不正です(%d)"),

SobelFilter.GetErrorCode() ); MessageBox( str, _T("Error") );

} }

9. プログラムの実行 以上でプログラムの作成は終了です。プログラムを保存したあとビルド・実行してみまし

しょう。「Load」をクリックし、任意の Gray画像をロードします。 画像が画面上に表示されましたら、「Filter」をクリックしてソーベルフィルタを実行して下さい。下図のように、フィルタ処理された画像が表示されれば終了です。

もし、実行時にエラーになった場合は、次の点を確認してみてください。 ・画像ファイルがカラー画像ではないか? カラーの画像を読み込むと、画像メモリのタイプが FVCL:: ImageType::RGB24 や

FVCL::ImageType::RGB32となってしまいます。FVCL::Filter::CFvSobelFilterで対応している画像タイプは、

FVCL::ImageType::UC8, FVCL::ImageType::S16, FVCL::ImageType::US16, FVCL::ImageType::D64

のみであるため実行できません。RGB24や RGB32からの変換はFVCL::Conversion::CFvGrayScaleクラスを使用します。

画像メモリのタイプは、FVCL::CFvImage::GetImageType()で取得することが可能です。