OpenCVをスタティックリンクライブラリでビルドする方法

シェアする

  • このエントリーをはてなブックマークに追加

スタティックリンクライブラリを使うと他のPCへ作成した実行ファイルを移植する時にexeファイルをコピーすればOpenCVをインストールする事なく実行できるので、メリットはあるので、使ってみたいのですが、これが、なかなか分かりづらい。

OpenCV2.3.1ではファイル(OpenCV-2.3.1-win-superpack.exe)をダウンロードし、解凍するとスタティックリンクライブラリらしきフォルダ(staticlib)があるのですが、*.libファイルが不足しているらしく、未解決のシンボルのエラーが出て使う事が出来なさそうです。

そのため、OpenCV-2.3.1-win-superpack.exeのソースからCMakeを使ってスタティックリンクライブラリをビルドしてみました。

CMakeでビルドする方法はOpenCV2.3の入手、ダウンロード、インストール、環境設定のページを参考にして頂きたいのですが、上記のページから異なるポイントを示したいと思います。

今回OpenCV-2.3.1-win-superpack.exeを c:\ に解凍している事を想定しています。

まずCMakeで作成するプロジェクトの保存先のフォルダを作成しておきます。

今回は C:\opencv\userbuild というフォルダを作成するとします。

CMakeを起動し

Where is the source codeに C:/opencv

Where is the source codeに C:/opencv/userbuid

を指定します。

Make_Static_OpenCV_Library

次にConfigureボタンをクリックします。

すると下図のようなウィンドウが開くので、使用するVisual Studioのバージョンを選択します。

Make_Static_OpenCV_Library

Finishボタンをクリックすると下図のように表示されるので、BUILD_SHARED_LIBSのチェックを外します。CUDAに対応していないPCの場合はWHITH_CUDAのチェックも外して下さい。

Make_Static_OpenCV_Library

次にConfigureボタンをクリックするとBUILD_WITH_STATIC_CRTという項目が表示されるので、チェックを入れたまま、Configureボタンをクリックします。

Make_Static_OpenCV_Library

すると赤く表示された部分が無くなるので、Generateボタンをクリックします。

Make_Static_OpenCV_Library

するとWhere is the source codeで指定したフォルダ(\userbuild)にソリューションファイル(OpenCV.sln)が作成されるので、このファイルをダブルクリックし、VisualStudioを開きます。

開いたVisualStudioのメニューからビルド→構成マネージャーを選択します。

次にINSTALLの項目にあるビルドの部分にチェックを入れます。

左上のアクティブソリューション構成の部分のDebugReleaseを選択しそれぞれにチェックを入れます。

Make_Static_OpenCV_Library

この状態で、Visual Studioのメニューのビルド→ソリューションのビルドを選択し、OpenCVをビルドします。このビルドには、かなり時間がかかりますが、ReleaseDebugの両方でビルドを行って下さい。

これでWhere is the source codeで指定したフォルダ(\userbuild)内に必要なヘッダファイルとライブラリファイルが作成されます。

スタティックリンクライブラリを使用する方法

まず、Visual Studioを起動し、ファイル⇒新規作成と選択し、Visual C++⇒Win32内のWin32コンソールアプリケーションを選択し、ウィンドウの下の方にある名前をプロジェクトを作成する場所を指定します。

次に表示されたウィンドウで完了をクリックするとスケルトンプログラムが作成されます。

次にVisual Studioのメニューのプロジェクト⇒(プロジェクト名)のプロパティを選択し、構成のプロパティ⇒C/C++⇒全般と選択し、追加のインクルードディレクトリの部分に先程作成したOpenCVのopencv2のあるフォルダを指定します。(右上の構成の部分でDebugとReleaseを切り替えて同じ設定をして下さい。)

C:\opencv\userbuild\install\include

Make_Static_OpenCV_Library

同じウィンドウで構成のプロパティ⇒リンカー⇒入力と選択し特性の指定のライブラリの無視の部分で

(Debugの場合)

LIBCMTD.lib;msvcprtd.lib

(Releaseの場合)

LIBCMT.lib;msvcprt.lib

を指定します。

これで、ソースコード上に下記のようにヘッダファイル(*.hpp)とライブラリファイル(*.lib)の設定を行うと、OpenCVをスタティックリンクライブラリとして使用する事が可能になります。

下記はWebカメラを撮影する簡単なコードです。

// OpenCVStaticSample.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//*******************************************************************************
// プロジェクトの設定
// ①プロジェクトのプロパティ⇒C/C++⇒全般 の追加のインクルードディレクトリに
//      C:\opencv\userbuild\install\include
//   を追加
// ②プロジェクトのプロパティ⇒リンカー⇒入力 の特定の規定のライブラリの無視に
//    Debugのとき
//        LIBCMTD.lib;msvcprtd.lib
//    Releaseのとき
//        LIBCMT.lib;msvcprt.lib
//    を追加
//*******************************************************************************

#include "opencv2\\opencv.hpp"

#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"vfw32.lib")	// Video for Windows

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_core231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_imgproc231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_highgui231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_objdetect231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_contrib231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_features2d231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_flann231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_gpu231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_legacy231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_ts231d.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_video231d.lib")

    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\zlibd.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libtiffd.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libpngd.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libjpegd.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libjasperd.lib")

#else
    //Releaseモードの場合
	#pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_core231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_imgproc231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_highgui231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_objdetect231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_contrib231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_features2d231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_flann231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_gpu231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_legacy231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_ts231.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\lib\\opencv_video231.lib")

    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\zlib.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libtiff.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libpng.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libjpeg.lib")
    #pragma comment(lib,"C:\\opencv\\userbuild\\install\\share\\OpenCV\\3rdparty\\lib\\libjasper.lib")

#endif

int _tmain(int argc, _TCHAR* argv[])
{

	// カメラオープン
	cv::VideoCapture cap(0);

	// カメラがオープンできたかの確認
	if(!cap.isOpened()) return -1;

	cv::namedWindow("Capture", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
	while(1) {
		cv::Mat frame;
		cap >> frame;  // キャプチャ
		// 様々な処理
		// ...
		cv::imshow("Capture", frame); // 表示
		if(cv::waitKey(30) >= 0)
		{
			cv::imwrite("cap.png", frame);
			break;
		}
	}

	return 0;
}

※実際に開発したPCとは別のPCへ実行ファイル(*.exe)を移植する場合、別途、C++のランタイムが必要となります。

移植先のPCに開発したPCで使用したVisual Studioと同じバージョンがインストールされていない場合、C++の再頒布パッケージというものをインストールします。

Visual Studio 2010 C++(32bit)の場合、以下の場所よりダウンロードして下さい。

Microsoft Visual C++ 2010 SP1 再頒布可能パッケージ (x86)

これで、OpenCVをスタティックリンクライブラリで使えていると思うのですが、この特定のライブラリの無視する部分と、comctl32.libとvfw32.libを追加しないといけない部分が分かりづらかった...

ただ、warning LNK4049のワーニングが幾つか出てしまい、いまいち、このwarningの消し方は分かりませんでした...

OpenCVへ戻る

関連記事

関連記事

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント