ぴぐノート

Good code is its own best documentation.

C/C++ MFC OpenCV

【OpenCV】MFCのピクチャーコントロールに描画しよう!

投稿日:2017年7月17日 更新日:

前回、OpenCVを使って画像の回転や二値化などを行って動作確認をしました。
今回はMFCでダイアログベースのアプリケーションを作成し、ピクチャーコントロールにOpenCVで読み込んだ画像を表示させてみましょう。

簡単なサンプルプログラムとして、「ボタンを押下されたらOpenCVで画像を読み込み、ピクチャーコントロールのサイズに合わせてリサイズし描画」させてみましょう。

サンプルプログラムの作成

プロジェクトを作成しよう!

では、サンプルプログラム用のプロジェクトを作成していきましょう。

  1. Visual Studio 2017を起動し、[ファイル]-[新規作成]-[プロジェクト]をクリックします。
  2. 「新しいプロジェクト」ダイアログでは、「MFCアプリケーション」を選択し、プロジェクト名とソリューション名を入力します。
    今回は前回のソリューションに追加する形で作成しています。
  3. 「MFCアプリケーションウィザード」のようこそ画面ではそのまま[次へ]ボタンをクリックします。
  4. 「アプリケーションの種類」は[ダイアログベース]を選択、[Security Development Lifecycleチェック]のチェックを外します。
  5. 「ユーザーインターフェイス機能」は特に変更せずに、[次へ]ボタンをクリック。
  6. 「高度な機能」ではすべてのチェックをを外します。
  7. 「生成されたクラス」では特に変更せずに、[完了]ボタンをクリックします。

ダイアログの外観を設定しよう!

次に、

  • 画像を読み込むためのButton
  • 画像を表示するPicture Control

を配置します。

画像表示用のPicture Controlのプロパティは以下のように設定しておきます。

・[ID]:
IDC_STATICからIDC_IMAGEに変更

・[Type]:
フレームから四角形に変更

次に、追加したボタンを右クリックし、[イベントハンドラーの追加]をクリック。
[イベントハンドラーウィザード]の内容は変更せずに、[追加して編集]ボタンをクリックします。

さて、これでコーディングを開始したいところですが、前回と同様に「追加のインクルードディレクトリ」と「追加のライブラリディレクトリ」を設定します。
追加の方法は前回の記事を参考にしてみてくださいネ。

コーディングしよう!

ではコードを入力していきます。

注意しなければならないのは、24行目の部分です。

イメージのサイズはPicture Controlのサイズに合わせてリサイズしていますが(27行目)、24行目で設定したサイズが4の倍数になっていない場合、上手く表示できません

そのため、幅と高さの下位2ビットを削り、必ず4の倍数になるように設定しています。
参考:Google 検索-[ウィンドウズDIB 4バイト境界]

また、33行目でBITMAPINFOHEADER::biHeightに正の値を設定しており、この画像はボトムアップDIBとなるため、28行目で画像を上下反転させています。
28行目をコメントアウトし、33行目のbiHeightに負数(-size.Height)を入力し、トップダウンDIBと指定しても同じ結果になります。
参考:トップダウン DIB とボトムアップ DIB | MSDN

28行目をコメントアウトし、33行目のbiHeightを変更しなければ上下反転された状態で描画されることも確認してみてくださいネ。

まとめ

これでOpenCVに画像処理を任せて、得られた結果をサンプルのようにPicture Controlに描画させることができました。
今回は単純にするためボタンが押されたら、特定の画像を読み込み表示するようなサンプルでしたが、実際には、

  • ボタンが押されたらファイル選択ダイアログが表示される
  • 画像のデータをImageクラスで保持する
  • 表示した画像をマウスホイールで拡大・縮小する

などなどたくさんの実装が必要になると思います。
まだまだ改善の余地は多くありますが、ひとまず動くことが確認できたので改善もしやすいのではないでしょうか。

スポンサーリンク

スポンサーリンク

-C/C++, MFC, OpenCV

執筆者:

関連記事

【Visual C++】フルパスを指定してフォルダー階層を作成する。

MFCなどでファイル走査などのプログラミングを行っていると、D&D(ドラッグアンドドロップ)されたフォルダー内の全ファイル(サブフォルダー含め)に何か処理を行い、同じような階層を維持したまま別 …

【Boost】boost::property_treeでXMLファイルを読み込もう!

以前はアプリケーションの設定ファイルに単純なテキストである、INIファイルを用いていたアプリケーションも多かったですが、最近はXML(Extensible Markup Language:拡張可能なマ …

Eclipse NeonとCDT/MinGWでC++開発環境を作成しよう!(1)

MFCなどを利用する場合にはほぼVisualStudio一択ですが、簡単なコンソールアプリケーションを作る場合にはEclipseのほうが便利な場合も多いです。 特に「普段はJavaで開発を行っているけ …

C++のプリプロセッサの復習をしよう その1

C++を勉強していた時期から苦手だったのがプリプロセッサでした。 インクルートガードに#ifndefやら#defineやら#pragma onceやら…。 C++に限った話ではありませんが …

【Boost】Boostライブラリの日付を使ってみよう!

先日の記事でBoostをインストールできたのでBoostのライブラリを使って遊んでみましょう。 今回は日付に関する情報をBoostから取得・表示したり、〇月〇日~□月□日が何日間あるか(期間)取得して …