fc2ブログ

C++でOpenCVのフォームアプリを作る(6) - MFC -

 以下、MFCフォームアプリ作成方法の備忘録です。

1. Visial Studio 2015を起動させ、ファイル(F) - 新規作成(N) - プロジェクト(P)を選択し、テンプレートのVisual C++からMFC、MFCアプリケーションを選択し、プロジェクト名(ここではMatToBmp)を入力し、OKボタンを押す。MFC_set1_160626.png
2. 以下、「MFCアプリケーションウィザード」に従い、進む。「概要」ページは、「次へ」ボタンで次に進む。MFC_set2_160626.png
3. 「アプリケーションの種類」ページでは、「ダイアログベース」と、「スタティック ライブラリでMFCを使用する」にチェックを入れて、「次へ」ボタンを押す。MFC_set3_160626.png
4. 「ユーザーインターフェース機能」ページは、「次へ」ボタンで次に進む。MFC_set4_160626.png
5. 「高度な機能」ページも、「次へ」ボタンで次に進む。MFC_set5_160626.png
6. 「生成されたクラス」が表示されるので、「完了」ボタンを押す。MFC_set6_160626.png
7. フォーム(ダイアログ)と.NET Frameworkのようなツールボックスが表示される。ツールボックスのボタンを押した際の動作のプログラムは、「プロジェクト名+Dlg.cpp」内(ここではMatToBmpDlg.cpp)に記載する。MFC_set7_160626.png
8. 画像の表示部は、「Picture Control」をフォームに貼り付け、プロパティにて、IDをデフォルトのID_STATICで使用せずに、リネームする(ここでは、ID_STATIC_BMP)。また、Typeを「ビットマップ」に変更する。MFC_set8_160626.png

ボタンを押したときのコードは以下の通り。

void CMatToBmpDlg::OnBnClickedButton1()
{
CBitmap m_bmp; //画像(bitmapファイル)
Mat readimage = imread("c:\\flower.bmp",1); //画像読み込み
char* ColorBuf = (char*)calloc(readimage.rows * readimage.rows * 4, sizeof(RGBQUAD));

for (int y = 0; y < readimage.rows; y++) {
for (int x = 0; x < readimage.cols; x++) {
// Blue
ColorBuf[y * readimage.cols * 4 + x * 4 + 0] = readimage.data[y * readimage.step + x * 3 + 0];
// Green
ColorBuf[y * readimage.cols * 4 + x * 4 + 1] = readimage.data[y * readimage.step + x * 3 + 1];
// Red
ColorBuf[y * readimage.cols * 4 + x * 4 + 2] = readimage.data[y * readimage.step + x * 3 + 2];
//Reserved
ColorBuf[y * readimage.cols * 4 + x * 4 + 3] = 0;
}
}

m_bmp.CreateBitmap(readimage.cols, readimage.rows, 1, 32, ColorBuf);
free(ColorBuf);

CStatic* pictbox = (CStatic*)GetDlgItem(IDC_STATIC_BMP);
pictbox->SetBitmap(m_bmp); //Picture Controlに表示
}

コードは、OpenCVでMat形式で画像を読み込み、Bitmap変換して、Picture Controlに表示させるものです。4行目でOpenCVにて画像を読み込み、5行目で変換後のBitmapの各データの領域を確保し、7~18行目でMat形式のデータをBitmap形式のデータに代入します。20行目でBitmapを作成し、23、24行目でそのBitmapをPicture Controlに表示します。実行結果は、以下の通り。MFC_set9_160626.jpg
 無事に動作しました。大変苦労しました。MFCで「静的リンク」のフォームアプリを作成できることが分かりましたが、コーディング~ビルドまでが難儀ですね。手間と苦労を考えると、実使用上問題なければ、「静的リンク」せずに、C++/CLIでコードを組んで、DLLファイルを同居させておいても良いような気がしました。
スポンサーサイト



C++でOpenCVのフォームアプリを作る(5) - MFC -

 前回までで、OpenCV 3.1(Visual Studio 2015)環境において、フォームなしのソースコードで「静的リンク」のビルドはできましたが、フォームがついた状態では、またまたエラーで前に進めませんでした。作成したプログラムで.NET Frameworkを使っており、C++/CLIで書いていたため、「静的リンク」でビルドすると、「コマンド ライン エラー D8016」が出てしましました。コマンドラインオプション'/clr'と'/MT'は同時に指定できません、とのこと。
 【C++/CLI】
  .NET Frameworkの共通言語基盤 (CLI)上で実行するプログラムを作るためにC++を拡張したプログラミング言語。

 このエラーは、なんじゃこりゃ、と思いつつ、調べると、'/clr'は「共通言語ランタイムをサポートする」、'/MT'は「アプリケーションで、マルチスレッド バージョンの静的なランタイム ライブラリが使用されます。 」とのこと。C++/CLIを使用する限り、'/clr'を使う必要があり、静的リンクではなく、動的リンク(DLL)にしてねということなのでしょう・・。念のため、今まで動かしていたコードのビルド条件を確認すると、'/clr'と'/MD'の組み合わせでした。'/MD'は「アプリケーションでランタイム ライブラリのマルチスレッド対応および DLL 対応バージョンが使用されます。」とのこと。やはりです。.NET Framework関係のDLLファイルは、Windowsパソコンならどのパソコンにも入っている状況なので、「静的リンク」などする必要もないですね。いまさらですが、大変勉強になりました。

 やりたいことは、この2つの両立だったのですが、できないようなので、別の方法を調べる必要がありました。結局、MFCでできそうな感じがしたので、初めてトライしました。
 【共通言語ランタイム(Common Language Runtime, CLR)】
  .NET Frameworkアプリケーションを実行するための仮想マシン。
 【MFC(Microsoft Foundation Class)】
  マイクロソフトがVisual C++用に開発した、Windows用のアプリケーション構築のためのアプリケーションフレームワーク(クラスライブラリ)

C++でOpenCVのフォームアプリを作る(4) - 静的リンク -

 前回の続きで、OpenCV 3.1(Visual Studio 2015)の環境での静的リンクのコードです。

//-------------------------------------------------------
// OpenCV 3.1 静的リンク
// リンカー設定:入力
// 追加の依存ファイル : msvcrt.lib;msvcmrt.lib
// 特定の既定のライブラリを無視 : Libcmt.lib;msvcprt.lib
//-------------------------------------------------------
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "vfw32.lib")

#pragma comment(lib, "opencv_core310.lib")
#pragma comment(lib, "opencv_imgcodecs310.lib")
#pragma comment(lib, "opencv_highgui310.lib")
#pragma comment(lib, "opencv_imgproc310.lib")

#pragma comment(lib, "zlib.lib")
#pragma comment(lib, "IlmImf.lib")
#pragma comment(lib, "libjasper.lib")
#pragma comment(lib, "libjpeg.lib")
#pragma comment(lib, "libpng.lib")
#pragma comment(lib, "libtiff.lib")
#pragma comment(lib, "libwebp.lib")
#pragma comment(lib, "ippicvmt.lib")

using namespace cv;

void main(void)
{
Mat readimage = imread("c:¥¥flower.bmp");
namedWindow("Read Image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
imshow("Read Image", readimage);
waitKey(0);
}
コード上でOpenCV 2.4.10と異なるのは、大きく二箇所。
 ① 8、16行目のimread関数の管轄クラスがimgcodecsに変わったこと
 ② 26、27行目のlibwebp.libippicvmt.libの2つのライブラリを追加すること。
 
 ①については、以前二度ほどしくじったことがありましたので、対応は取れていましたが、エラーの原因の一つは②でした。このサイトを確認し、OpenCV 2.4.10にはない2つのライブラリを実装する必要があることに気づきました。20〜27行目のライブラリファイルは、私の環境ではC:\opencv310\build\3rdparty\libのDebug/Releaseフォルダに作成されていたので、OpenCVのstaticlibの入っているフォルダにコピーしてビルド処理を行いました。
 もう一つのエラー原因は、「追加の依存ファイルにmsvcrt.libとmsvcmrt.libを追加」することで解決しました。msvcrt.libを設定しないとリンク時にLNK2001のエラーが多発しました。結局リンカーの入力設定は以下の通りになりました。lnksetting160625.png ビルドも無事に終了し、Windows Tabletで実行してみると無事に動作しました。tablet_res160625.png

C++でOpenCVのフォームアプリを作る(3) - 静的リンク -

 前回から苦戦していた、開発環境 OpenCV 3.1とVisual Studio 2015での「静的リンク」のその後の進捗です。結果から言うと、うまく行きました。私自身の理解が足りない所もありました。以下、その備忘録です。

 OpenCV 3.1では静的リンク用のライブラリが、OpenCV 3.0まで保存されていたstaticlibフォルダにありません。よって、CMakeでビルド用OpenCV.slnを作成する際にオプション設定(BUILD_SHARED_LIBSのチェックをOFF)して作成する必要があります。CmakeSetting160625.png このチェック項目を素通りすると、Defaultがチェックありなので、DLLファイル(動的リンクの環境)が作成されます。一連の作成手順は、このサイトを参考にしました。

 作成されたStatic Link用のlibファイル(Release版)と、DLLファイルを利用するときのlibファイル(Release版)の容量は下表の通りです。ライブラリファイル名は同じですが、ファイル容量が異なります。当然、staticlink用のlibファイルの方が容量大です。imageprocはstaticlibにするだけで、62倍(6,200%)にもなるのですね。LIBfile160625.png
 Static Link用のlibファイルも無事に作成できましたので、動的リンク(DLLファイル利用)で問題なく動作していたプログラム(C++のフォームアプリ)を、静的リンクでビルドしてみました。・・しかし、リンクエラーのオンパレードでした。何が原因か切り分けるため、まずは、
  ① フォームなしのOpenCVのコード(C++)のみで確認する。次に
  ② フォームを付けて確認する
の2段階で攻めていくことにしました。

 ①は特定の画像のファイルをimreadで読み込んで、Windowに表示させる単純なものでしたが、OpenCV 3.1ではうまくいかなかったので、実績のあったOpenCV 2.4.10(Visual Studio 2010)で検証しました。

//-------------------------------------------------------
// OpenCV 2.4.10 静的リンク
// リンカー設定:入力
// 特定の既定のライブラリを無視:Libcmt.lib;msvcprt.lib
//-------------------------------------------------------

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "vfw32.lib")

#pragma comment(lib, "opencv_core2410.lib")
#pragma comment(lib, "opencv_highgui2410.lib")
#pragma comment(lib, "opencv_imgproc2410.lib")

#pragma comment(lib, "zlib.lib")
#pragma comment(lib, "IlmImf.lib")
#pragma comment(lib, "libjasper.lib")
#pragma comment(lib, "libjpeg.lib")
#pragma comment(lib, "libpng.lib")
#pragma comment(lib, "libtiff.lib")

using namespace cv;

void main(void)
{
Mat readimage = imread("c:¥¥flower.bmp");
namedWindow("Read Image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
imshow("Read Image", readimage);
waitKey(0);
}
 このプログラムをOpenCVのインストールされていないWindows Tabletで実行すると、無事に動作しました。OpenCV 3.1(Visual Studio 2015)でリンクを成功させるためには、OpenCV自身のバージョンアップによる変更点等を考慮する必要がありました。このことについては、次回お話しします。

IT pro EXPO 2016 名古屋に行く

 6/17(金)に名古屋国際会議場で開催された「IT pro EXPO 2016 名古屋」に行って来ました。3月に大阪で開催された展示会Cloud Daysの名古屋版も含み、日経BP社主催の6つの展示会が開催されていました。今回も会社の出張ではなく、休暇を取って個人的に参加しました。大阪圏、名古屋圏ならば気軽に出かけられる距離でもあり、会社への出張報告もしなくてもよく、気楽ですから・・・そうそう、前回(4月)のリベンジである「みそカツ」を食べに行くことも忘れてはいけません。

 メインはセミナーを聴講しました。日本ガイシさん、アマゾンウェブサービスさん、富士ゼロックスさん、トレンドマイクロさんの4講演を聞き、講演の間に展示ブースを回りました。特に日本ガイシさんのビッグデータ活用事例は具体例があり、大変参考になりました。クラウド関係に興味があったので、AWSとMicrosoft(Softbank)のブースで話を聞きました。いろいろ知らないことを勉強できたので、今回の展示会は収穫ありでした。

 夕方は、名古屋定番のブタのお相撲さんのお店で「わらじとんかつ」を食べました。yabaton160617.png味噌だれとソースだれの半々で大変美味しく頂きました。今日の収穫はこれが一番かも。
 

C++でOpenCVのフォームアプリを作る(2) - 静的リンク -

 前回の続きです。このプログラムの開発環境は、OpenCV 3.1とVisual Studio 2015です。
今回、OpenCVのインストールされていない環境でも使用できるように「静的リンク」にチャレンジしました。いろいろやってみましたが、これがうまく行きません。
 以前、OpenCV 2.4.10とVisual Studio 2010の組み合わせの時は、苦労しながらもうまく行ったので、今回も同じようにできるのではと思っていましたが、大間違い・・・。この週末、ひたすら格闘していましたが、結果NGでした。(ぐったりです・・)

 うまく行ったOpenCV 2.4.10とVisual Studio 2010(VC10)の組み合わせの時は、OpenCVのインストールの際に、静的リンク用のライブラリがstaticlibのフォルダに入っていましたので、そのまま使えました。
 OpenCV 3.0にもstaticlibのフォルダ内にライブラリは準備されていますが、それは最新がVisual Studio 2013(VC12)用のものでした。そのまま使ってみると案の定、リンクエラーのオンパレードです。
 OpenCV 3.1は、staticlibのフォルダすらありません。静的リンク用のライブラリは、Cmakeでビルド用OpenCV.slnを作成する際にオプション設定(BUILD_SHARED_LIBSのチェックをOFF)する必要があります。この方法で無事にライブラリは作成できたのですが、実際の作成コードをビルドすると、これまた、リンクエラーのオンパレードです。
 私自身の能力不足で、何か抜けていることに気が付いていないのかも知れません。不具合内容をネットで調べても、記事にヒットしませんね。しばらく、頭を冷やそうと思います。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: