OpenCV를 정적 라이브러리(static library)로 사용한 c++ 배포용 프로그램 만들기

프로그래밍/opencv 2013.03.28 22:03

opencv 를 사용하여 프로그램을 만들 때 보통은 동적 라이브러리(shared dll) 버전을 사용합니다. 그런데, 동적 라이브러리를 사용하면 자신이 만든 프로램을 배포할 때 opencv에 딸린 dll들도 같이 보내야 합니다. 또는 아무 컴퓨터에서나 실행파일 하나만 가지고 프로그램을 돌렸으면 좋겠는데, opencv dll들도 같이 들고 다녀야 하니 여간 불편합니다. 이럴 때, 사용할 수 있는 방법이 opencv 정적 라이브러리(static library) 버전을 사용하는 것입니다.


그런데, opencv에 기본적으로 포함된 static library를 사용할 경우에는 다음과 같은 문제점이 있습니다. ① win32 콘솔 어플리케이션으로 하면 문제가 없지만, mfc 어플리케이션을 생성하면 highgui와 라이브러리 충돌이 발생한다. ② 기본 static library에는 ipp나 tbb와 같은 고속/병렬처리 라이브러리가 포함되어 있지 않기 때문에 매우 느리다.


따라서, 본 글에서는 파일 하나만 있으면 언제 어디서나 실행 가능한 프로그램을 만들어 보려고 합니다. 제가 목표로 하는 최종 프로그램 파일 형태는 다음과 같습니다.

  • 실행파일(.exe)외에 어떤 부가 파일도 필요로 하지 않는다.
  • opencv가 설치되지 않은 컴퓨터에서도 실행되어야 한다.
  • visual studio가 설치되지 않은 컴퓨터에서도 실행되어야 한다.
  • win7 뿐만 아니라 vista, win xp 등에서도 모두 실행가능해야 한다.
  • opencv의 풀 기능을 사용하여 프로그램이 동작한다 (tbb, ipp 포함)


제가 개발한 프로그램들을 블로그에 올릴 때 사용할 목적으로 이러한 번거로운 변환작업을 시작하게 되었는데 정말 난관이 한두가지가 아닙니다. 정적 빌드를 왜 이렇게 어렵게 해 놓았는지 모르겠습니다. 일단 저의 작업 환경은 다음과 같습니다.


※ (2015.7.2) 외부 배포용이 아니라 연구개발용, 테스트용이라면 굳이 아래와 같은 복잡한 과정을 거칠 필요가 전혀 없습니다. 그냥 동적 라이브러리(dll)로 빌드하여 사용하시면 됩니다. 또한 opencv의 함수에 따라서 병렬처리를 지원하는 것도 있고 지원하지 않는 것도 있으며 병렬처리를 지원하는 함수의 경우에만 속도향상이 됩니다. 병렬처리를 지원하는 opencv 함수는 소스코드에 parallel_for_가 포함되어 있습니다.


OpenCV 기본 static library 그대로 이용하기


opencv를 다운받아 압축을 해제하면 미리 컴파일해 놓은 static library 버전이 기본적으로 포함되어 있습니다. 위치는 예를 들어, 저처럼 32비트OS visual c++ 9.0에서 사용할 경우 static library 위치는 opencv2.4.4\build\x86\vc9\staticlib 입니다. 여기에 있는 lib 파일들을 링크시키고 컴파일하면 opencv_XXX.dll들 없이도 실행 가능한 프로그램이 만들어집니다.  이 때, 주의할 사항들은 다음과 같습니다.

  • visual studio에서 프로젝트를 생성할 때 win32 어플리케이션으로 생성. mfc 어플리케이션을 생성하면 highgui와 라이브러리 충돌이 발생함 (제 경우는 그런데 다른 컴퓨터에서도 그런지는 잘 모르겠네요. 혹시 되는 분 있음 알려주세요)
  • 프로젝트 속성을 /MT(release), /MTd(debug)로 변경 (visual studio 기본 설정인 /MD 나 /MDd를 그대로 사용하면 엄청난 라이브러리 충돌 메시지를 보게 됩니다. 설정 위치는 프로젝트속성-C/C++-코드생성-런타임라이브러리입니다)
  • 사용할 opencv 모듈들(opencv_corexxx.lib, opencv_imgprocxxx.lib, ...) 뿐만 아니라 IlmImf.lib, libjasper.lib, libjpeg.lib, libpng.lib, libtiff.lib, zlib.lib도 모두 링크시켜야 함. opencv의 staticlib 폴더에 같이 들어있음. (debug 버전이면 뒤에 d 붙은 파일들 링크)
  • 추가적으로 vfw32.lib, comctl32.lib도 링크시켜야 함 (highgui 사용시 필요, debug/release 공통)


이와 같이 하면 opencv 없이도 exe 파일 하나만으로 실행 가능한 프로그램이 만들어집니다. 그런데, 문제는 CDialog 등 mfc 개발환경을 이용할 수 없으며 또한 tbb(threading building blocks)나 ipp (intel performance primitives)와 같은 고속 병렬처리 라이브러리를 이용할 수 없다는 점입니다. 특히 요즘 컴퓨터는 대부분 멀티코어이기 때문에 tbb를 사용했을 때와 안했을 때의 프로그램 속도 차이는 엄청납니다 (단, opencv 함수에 따라서 병렬처리를 지원하는 것도 있고 지원하지 않는 것도 있으며 병렬처리를 지원하는 함수의 경우에만 속도향상이 됩니다).


참고로 opencv 2.4.3 버전부터는 병렬처리를 위해 universal parallel_for_를 구현하여 tbb뿐만 아니라 OpenMP, Concurrency를 모두 지원합니다 (그 이전 버전에서는 tbb만 지원했었음). Concurrency는 visual studio 2010, 2012에 내장된 기능으로서 특별히 다른 처리를 안해도 visual studio가 알아서 병렬처리 코드로 컴파일해 준다고 합니다. 저는 아직 visual studio 2008이라서 이런 기능을 체험해 보지는 못했습니다. opencv에서 기본 제공되는 static library 버전을 그대로 사용해서 프로그램을 visual studio 2010 이상에서 컴파일했을 때, opencv 루틴들이 병렬로 처리될지는 아직 확인해 보지 못해서 모릅니다. 만일 그렇다면 굳이 아래와 같은 복잡한 일을 안해도 되겠네요.


본격적으로 설명을 하기 전에 앞서서 기본적으로 알아야 될 사항들이 몇 가지 있습니다.


/MT와 /MD 차이


컴파일 옵션중에 /MT(multi-threaded), /MD(multi-threaded dll)라는게 있습니다 (설정위치: 프로젝트속성-C/C++-코드생성-런타임라이브러리). 특히나, 정적 라이브러리를 사용할 경우에는 이것 때문에 무척 골치가 아픕니다. XXX is already defined in YYY 어쩌구 하는 라이브러리 충돌 컴파일 에러들은 모두 이놈들 때문에 발생합니다. 사용한 라이브러리가 하나는 /MT로 생성되었고 하나는 /MD로 생성되었다면 짤없이 라이브러리 충돌 에러 메시지를 보게 됩니다. http://msdn.microsoft.com/ko-kr/library/2kzt1wy3(v=vs.90).aspx에 보면 /MT, /MD가 설명되어 있지만 핵심 내용은 컴파일시 정적 버전의 C 런타임 라이브러리를 사용할 것이냐(/MT) 아니면 동적 버전을 사용할 것이냐(/MD)의 차이입니다.


/MT: 응용 프로그램에서 다중 스레드 정적 버전의 런타임 라이브러리를 사용하도록 지정합니다. 즉 응용 프로그램에서 입출력, 메모리 할당과 같은 C 런타임 라이브러리(CRT, C Run-Time library) 기능을 사용할 때 정적 링크 버전인 LIBCMT.lib를 사용하여 프로그램이 빌드됨.


/MD: 응용 프로그램에서 다중 스레드 DLL 전용 버전의 런타임 라이브러리를 사용하도록 지정합니다.  즉 응용 프로그램에서 C 런타임 라이브러리 기능을 사용할 때 이것의 동적 링크 버전인 MSVCRT.lib를 사용하여 프로그램이 빌드됨.


만일 사용하는 외부 라이브러리는 /MT로 빌드되었는데, 현재 응용 프로그램은 /MD로 빌드하면 동일한 기능에 대해 서로 다른 두 버전의 라이브러리가 동시에 사용되기 때문에 XXX is already defined in YYY 어쩌구 하는 무수한 충돌 메시지를 보게 됩니다. 외부에서 가져온 라이브러리라면 /MD, /MT를 맞추거나 /NODEFAULTLIB:library 외에는 별 방법이 없지만(이렇게 해도 해결 안되는 경우가 많음), 자신이 직접 정적 라이브러리를 만들 경우에는 라이브러리든, 응용프로그램이든 모조건 다 /MT 옵션으로 맞추면 됩니다(debug용은 /MTd).


target 윈도우 버전


만든 응용 프로그램이 win7, vista, win xp 관계없이 다 동작하기 위해서는 프로그램 컴파일시 WINVER과 _WIN32_WINNT를 win xp에 맞추어 주어야 합니다. Visual studio로 만든 프로젝트에 보면 targetver.h 파일이 자동 생성됩니다. 여기에서 타겟 윈도우 버전을 다음과 같이 win xp로 수정합니다.

#define WINVER 0x0501

#define _WIN32_WINNT 0x0501

만일 targetver.h 파일이 없을 경우에는 프로젝트속성에서 컴파일 옵션에 /D 매크로를 사용해서 두 상수를 추가로 정의해 주면 됩니다. 각 윈도우별 버전은 win 2000은 0x0500, win xp는 0x0501, windows server 2003은 0x0502, vista는 0x0600, win 7은 0x0601입니다.



그럼 이제 본격적으로 단독 실행 가능한 프로그램을 위한 opencv 정적 라이브러리 만드는 방법을 차례차례 설명하겠습니다.


1. tbb를 static library로 변환하기


opencv는 병렬처리 라이브러리인 tbb를 지원합니다. 그래서, tbb를 포함해서 opencv를 빌드(build)하면 멀티코어 컴퓨터에서 고속으로 영상처리 루틴의 처리가 가능해집니다. opencv 배포판에 있는 미리 빌드된 파일들(동적/정적 모두 해당됨)에는 tbb가 포함되어 있지 않기 때문에 속도가 느립니다. tbb를 사용할 경우 약 4~10배까지 opencv 속도가 향상됩니다. 그런데, tbb를 사용하기 위해서는 자신이 직접 opencv 소스코드를 다시 컴파일해야 합니다.


tbb는 공개(free) 라이브러리로 http://threadingbuildingblocks.org/에서 소스코드 및 바이너리를 다운받을 수 있습니다. 그런데, 문제는 tbb가 동적 라이브러리(shared dll) 형태로만 배포된다는 것입니다. tbb 홈페이지에 보면 static 버전을 사용하면 원치않는 여러가지 문제가 발생할 수 있기 때문에 자기들은 dll 버전만을 지원한다고 명시되어 있습니다. 따라서, tbb를 사용하면 tbb.dll 파일도 항상 같이 가지고 다녀야 한다는 말이 됩니다.


하지만, 제가 원하는 것은 어떤 부가 파일도 필요없이 exe 파일 하나만으로 실행되는 프로그램이기 때문에 tbb도 직접 static library 버전으로 만들기로 했습니다.


tbb를 static library로 빌드하기 위해 필요한 사항들은 다음과 같습니다.

  1. tbb 홈페이지에서 tbb 소스코드를 다운로드 받는다.
  2. visual studio에서 win32 static library 프로젝트를 하나 생성한다.
  3. tbb가 설치된 경로를 TBB라고 했을 때, dll버전을 컴파일하기 위한 프로젝트 파일인 TBB\build\vsproject\tbb.vcproj을 참조하여 동일하게 소소코드 파일들(cpp, h)을 프로젝트에 포함시킨다. tbb.vcproj를 열면 tbb, tbbmalloc, tbbmalloc_proxy 이렇게 3개의 프로젝트가 한 workspace에 같이 들어있는데, 첫번째 tbb만 참조하면 된다. 리소스 파일은 포함시킬 필요 없음.
  4. 프로젝트 설정에서 코드생성 옵션을 릴리즈 버전은 /MT로, 디버그 버전은 /MTd로 설정한다(설정위치: 프로젝트설정-C/C++-코드생성-런타임라이브러리).
  5. 프로젝트 설정에서 preprocessor definitions에 __TBB_BUILD, USE_WINTHREAD, __TBB_SOURCE_DIRECTLY_INCLUDED 이렇게 3개를 추가해 준다. (설정위치: 프로젝트속성-C/C++-전처리-전처리정의). 컴파일 옵션에 /D 매크로를 사용해서 명령행으로 추가해도 됨.
  6. 프로젝트 설정에서 컴파일 옵션에 WINVER과 _WIN32_WINNT을 모두 0x0501로 정의해 줌. 0x0501은 windows xp에 해당하는 버전번호로서 이걸 해 주지 않으면 tbb가 vista 이상에서만 동작하게 됨. xp에서도 실행되도록 하기 위해서는 target window version을 이렇게 명시해 주어야 함. 컴파일 전처리 옵션에 추가하기 위해서는 /D 매크로를 사용하여 명령행 옵션란에 /DWINVER=0x0501와 /D_WIN32_WINNT=0x0501를 추가해 줌 (설정위치: 프로젝트속성-C/C++-명령행라인-추가옵션)
  7. tbb_misc.cpp 파일에서 __TBB_machine_store8_slow 함수 부분을 주석처리한다. 요놈 때문에 아무리 해도 컴파일이 안되었었는데 호출되는 곳을 보니 Linux 머신에서 사용할 때 뿐이라서 과감히 삭제했습니다. 실제 프로그램을 돌려보니 삭제해도 이상없이 잘 돌아갑니다.


2. ipp 사용하기


ipp(intel performance primitives)는 인텔에서 제공하는 라이브러리로서 인텔 cpu 칩에 최적화된 연산 루틴을 제공한다고 합니다. opencv에서 ipp 사용을 지원하고 있는데 ipp를 사용하면 tbb만큼은 아니지만 opencv 루틴의 처리 속도가 어느 정도는 향상됩니다. ipp를 사용하기 위해서는 http://software.intel.com/intel-ipp에서 30일 평가판을 무료로 다운로드 받습니다. ipp에서는 tbb와 달리 static library 버전도 같이 제공됩니다. 평가판이긴 하지만 우리가 필요로 하는 것은 몇몇 static lib 파일들과 include 헤더 파일들이기 때문에 이 파일들만 따로 복사해 놓고 무한히 사용할 수 있습니다. opencv에서 필요로 하는 ipp 파일들은 ippcc_l.lib, ippcore_l.lib, ippcv_l.lib, ippi_l.lib, ipps_l.lib, ippvm_l.lib 이렇게 6개 뿐입니다. 정적 라이브러리 버전이기 때문에 dll 파일도 필요없으니 ipp 설치 폴더의 include 폴더에 있는 헤더 파일들과 이 6개 파일만 있으면 OK 입니다.


☞ (2015.6.15) 그런데 요즘 나오는 최신 ipp 버전에서는 위 static lib들이 사라졌다고 하는 얘기가 있기 때문에 위 6개 lib 파일들을 구하기 위해서는 예전버전(7.XX 이하)을 구해야 할 것 같습니다. 정확히 어떤 버전부터 사라졌는지는 잘 모르겠습니다만 7.0까지는 있었던 것 같습니다.


3. OpenCV 정적 라이브러리(static library) 직접 빌드하기


opencv를 소스코드로부터 직접 빌드하기 위해서는 cmake가 필요합니다. 정적 라이브러리 뿐만 아니라 기본 제공되는 동적 라이브러리 dll 버전도 tbb나 ipp를 포함하고 있지 않기 때문에 어차피 한번은 직접 빌드를 해 주는게 좋습니다.


cmake는 http://www.cmake.org/에서 다운로드 받을 수 있는 free 소프트웨어입니다. cmake 사용법은 다루지 않겠습니다만, opencv를 static library로 빌드하기 위해서 저는 다음과 같이 cmake를 설정했습니다. 중요한 사항은 BUILD_SHARED_LIBS는 체크해제하고(정적 라이브러리를 빌드할 것이므로) BUILD_WITH_STATIC_CRT도 체크해제(아니면 엄청난 라이브러리 충돌이 발생함)합니다. 그리고 BUILD_PACKAGE도 체크해제합니다(아니면 컴파일하다가 날 샙니다). WITH_IPP와 WITH_TBB는 사용할 것이기 때문에 체크해 줍니다. 그러면 ipp, tbb에 대한 include, lib 경로를 물어보는데 적절히 세팅해 주면 됩니다. tbb의 경우에는 앞에서 static 버전으로 컨버팅한 lib 파일 경로를 입력해 줍니다. png, tiff, jpeg, zlib 등도 체크해 줍니다.






이렇게 해서 cmake로 생성한 프로젝트에서 build all을 하면 정적 라이브러리 버전의 opencv가 생성되는데, 몇 가지 세팅해 주어야 할 게 있습니다.

  • cmake로부터 기본적으로 생성된 opencv 프로젝트는 컴파일러 코드생성 옵션이 모두 /MD, /MDd로 되어 있는데 저는 opencv_core, opencv_highgui, ... 등등 opencv 모듈들의 옵션을 모두 일일히 /MT, /MTd로 바꾼 후에 컴파일했습니다.
  • 프로젝트 설정에서 컴파일 옵션에 /D 매크로를 이용해서 WINVER과 _WIN32_WINNT을 모두 0x0501로 정의해 줍니다. xp에서도 동작하게 하고 싶다면 모든 opencv 모듈을 일일히 설정해 줍니다.
  • highgui 소스파일 중 window_w32.cpp파일이 있는데 안에 보면 #include <MultiMon.h>하는 코드가 있습니다. 이놈을 주석처리합니다. 처음엔 그대로 빌드했는데 계속 라이브러리 충돌이 나서 이놈을 제거하니 잘 되네요. 저만의 문제인지 일반적인 현상인지는 잘 모르겠군요. 주석처리 하지 않아도 잘 동작한다면 굳이 주석처리할 필요 없을 것입니다.


☞ CMake를 사용한 OpenCV 빌드 방법에 대한 글을 최근 올렸습니다: OpenCV 설치 및 CMake GPU+TBB+IPP 빌드(컴파일)하기



4. 독립 실행되는 응용 프로그램 생성하기


이제 마지막으로 지금까지 생성한 static library들을 가지고 독립 실행이 가능한 opencv 응용 프로그램을 만들면 됩니다. 이 때, 주의 사항은 다음과 같습니다.

  • 만일 콘솔 어플리케이션이라면 프로젝트 속성에서 standard windows library를 사용하고, mfc 어플리케이션이라면 static library로 mfc를 사용하도록 설정한다.
  • 프로젝트 속성에서 코드생성 옵션을 릴리즈 버전은 /MT로, 디버그 버전은 /MTd로 설정한다(설정위치: 프로젝트설정-C/C++-코드생성-런타임라이브러리). 안해주면 엄청난 라이브러리 충돌이 발생합니다.
  • opencv static libary 모듈들 뿐만 아니라,  IlmImf.lib, libjasper.lib, libjpeg.lib, libpng.lib, libtiff.lib, zlib.lib, vfw32.lib, comctl32.lib, 만들어 두었던 tbb.lib, 그리고 ipp 라이브러리들인 ippcc_l.lib, ippcore_l.lib, ippcv_l.lib, ippi_l.lib, ipps_l.lib, ippvm_l.lib 들을 전부다 링크시킨다. 예를 들어 use_opencv_static.h라는 이름으로 헤더 파일을 별도로 하나 만들어서 #pragma comment(lib,"opencv_core244d.lib"), #pragma comment(lib,"vfw32.lib") 등과 같이 필요한 정적 라이브러리 파일들을 일괄적으로 링크시키면 편리합니다.


5. 테스트 프로그램


이상의 내용을 가지고 아래와 같은 샘플 프로그램을 하나 만들어 보았습니다. opencv에 있는 샘플 프로그램중의 하나인 facedetect.c 예제를 그대로 포팅한 프로그램입니다. face DB 파일과 실행파일만 달랑 하나 있는데 opencv나 visual c++ 없이도 여러분 컴퓨터에서 실행되는지 확인해 보시기 바랍니다.

StaticTestFaceDetect.zip






☞ 쓰고 보니 글이 길어졌네요. 그 만큼 제가 삽질을 많이 했다는 ... ^^ 어쨌든 지금은 모든 문제가 클리어되어서 홀가분합니다. 제 글이 opencv를 직접 build하려는 이들, opencv에서 tbb나 ipp를 사용하고자 하는 이들, opencv를 정적 라이브러리로 사용하고자 하는 이들, 자신이 만든 프로그램을 독립 실행 가능한 버전으로 만들고자 하는 이들에게 도움이 되길 바랍니다. 혹 내용중 잘못된 부분이나 관련된  경험, 코멘트 등에 대해서는 댓글로 남겨 주시기 바랍니다.

by 다크 프로그래머

저작자 표시 비영리 변경 금지
신고
  • 이전 댓글 더보기
  • openav 2014.11.05 12:33 신고 ADDR 수정/삭제 답글

    opencv 주소가 바꼇네요

    • BlogIcon 다크pgmr 2014.11.05 16:35 신고 수정/삭제

      네 감사합니다 ^^
      주소를 수정하였습니다.

  • 루키즈 2014.12.27 09:40 신고 ADDR 수정/삭제 답글

    많이 배웁니다. 감사합니다.

  • 안녕하세요~
    영상처리의 마지막은 항상 이곳에 오게 되는 것 같습니다.ㅜ
    제가 다른 분꼐서 올려둔 프로젝트를 실행해 보려고 하는데
    에러를 잡는다고 잡았는데도 아직
    CarNumber.obj : error LNK2019: "public: virtual __thiscall CvvImage::~CvvImage(void)" (??1CvvImage@@UAE@XZ) 외부 기호(참조 위치: "public: virtual __thiscall CCarNumberDlg::~CCarNumberDlg(void)" (??1CCarNumberDlg@@UAE@XZ) 함수)에서 확인하지 못했습니다.
    1>CarNumberDlg.obj : error LNK2001: "public: virtual __thiscall CvvImage::~CvvImage(void)" (??1CvvImage@@UAE@XZ) 외부 기호를 확인할 수 없습니다.
    1>CarNumberDlg.obj : error LNK2019: "public: __thiscall CvvImage::CvvImage(void)" (??0CvvImage@@QAE@XZ) 외부 기호(참조 위치: "public: __thiscall CCarNumberDlg::CCarNumberDlg(class CWnd *)" (??0CCarNumberDlg@@QAE@PAVCWnd@@@Z) 함수)에서 확인하지 못했습니다.
    1>libcmtd.lib(crt0.obj) : error LNK2019: _main 외부 기호(참조 위치: ___tmainCRTStartup 함수)에서 확인하지 못했습니다.
    1>C:\YuKyeong\VS2010\carnumbertest\carnumbertest\Debug\carnumbertest.exe : fatal error LNK1120: 3개의 확인할 수 없는 외부 참조입니다.
    이런 말들이 뜹니다.

    libjpeg.lib, libpng.lib, libtiff.lib, zlib.lib
    vfw32.lib, comctl32.lib
    를 더 사용할수 있게 추가종속성에 넣으려고 했는데
    윗줄의 경우 참조할 수없다며 에레가 뜨고
    밑에 vfw32.lib, comctl32.lib의 경우 파일을 찾을 수가 없습니다.

    http://cafe.naver.com/opencv/27168이곳에 있는 소스인데
    제가 win8.1에 vs2010 , opencv2.4.9인데..버전의 문제일까요...?

    • BlogIcon 다크pgmr 2015.02.14 10:46 신고 수정/삭제

      CvvImage 오브젝트 코드가 없어서 나는 에러인데.. 구글링을 해보니 CvvImage는 opencv2.2 이후부터 없어졌다고 합니다 (http://comvision.tistory.com/4 글 참조)

  • 답변감사합니다.
    CvvImage추가해보겠습니다~

  • 뚜림 2015.04.19 11:26 신고 ADDR 수정/삭제 답글

    잘보았읍니다... 엄청 어렵네요 ^^

  • BlogIcon 사신출두 2015.05.13 13:32 신고 ADDR 수정/삭제 답글

    안녕하세요.
    항상 귀중한 강의 감사드립니다.
    다름이 아니라 한가지 궁금한점이 있어서
    이렇게 질문 올려드립니다.
    실습하기전,
    제환경은 비쥬얼스튜디오2012, opencv2.4.10버젼을 사용하고있습니다.
    단순한 책에 있는 소스입니다.
    웹켐에서 영상을 읽어와서 얼굴을 검출하는건데
    올려주신 파일로 얼굴 검출하는것과 속도차이가 엄청나서(프레임이 제가 컴파일한 파일에선 뚝뚝 끊깁니다. 게다가 CPU점유율도 상당히 높구요)
    2.4.3버전 이상부터는 병렬처리를 제공한다는데 제공 받아도 이정도인지 궁금합니다.
    올리신 파일StaticTestFaceDetect 여기에 제작된 소스와 많이 다른건가요?
    IPP전용 소스코드를 이용해서 소스를 제작하셔서 배포하신것인지 궁금합니다.

    • BlogIcon 다크pgmr 2015.05.13 12:42 신고 수정/삭제

      안녕하세요. 굳이 이렇게 긴 코드를 올리실 필요는 없었을 것 같은데요.. ㅠ.ㅠ
      본문에 적어 놓았듯이 올려놓은 프로그램은 opencv에서 제공하는 예제코드를 있는 그대로 병렬처리(tbb+ipp) 기능만 활성화하여 컴파일한 것입니다.

    • 사신출두 2015.05.13 13:31 신고 수정/삭제

      지금 IPP버전을 8.2 버전만 제공하고있어서
      lib폴더를 보니 말씀하신 파일이 없습니다.
      다른 게시물 댓글을 참조하니 기본 패키지에 포함을 안한다고 했는데
      이럴 경우에는 IPP기능을 사용 못하는것인지요?

    • BlogIcon 다크pgmr 2015.05.13 20:03 신고 수정/삭제

      static 빌드에 필요한 파일들이 제외되었기 때문에 ipp를 static 빌드용으로는 사용하기 힘들 것 같습니다. 그런데, ipp는 눈에 띨 만큼의 속도향상이 있는 것은 아니기 때문에 반드시 사용할 필요는 없으십니다.

  • BlogIcon 야매코더 2015.06.03 13:02 신고 ADDR 수정/삭제 답글

    감사합니다. static 으로 만드는것 성공 했습니다.
    출처 밝히고 내용을 조금 발췌 해도 될까요 ?

    그리고 아주 나머지 설명들이 잘 되어 있어 도움이 많이 될듯 합니다. 나중에 여유가 생기면 tbb 도 해봐야 겠습니다.

  • 화이팅 2015.06.05 00:58 신고 ADDR 수정/삭제 답글

    다크pgmr 과정대로 TBB와 IPP 설정 및 라이브러리,환경변수를 지정하고 VS2012버전에 설정을 다 했습니다. 하지만 속도차이는 변함이 없는데....추가적으로 다운 받거나 업데이트 해야 하는 과정 이 더있는 건가요??

    • BlogIcon 다크pgmr 2015.06.05 05:54 신고 수정/삭제

      아니요, 그런건 없습니다. 혹시 테스트하신 코드가 병렬처리와는 관계가 없는 건 아닌지 모르겠습니다. opencv의 모든 코드가 다 병렬처리되어 있는 것은 아니고 병렬처리가 효과적인 부분에 대해서만 병렬처리되어 있습니다. 사용하신 opencv 기능의 소스코드를 확인해 보시면 좋을 것 같습니다.

  • 화이팅 2015.06.05 15:01 신고 ADDR 수정/삭제 답글

    아~~ 그렇군요 감사합니다!!

  • 나그네 2015.06.14 00:45 신고 ADDR 수정/삭제 답글

    안녕하세요. 늘 감사한 마음으로 게시글들 잘 보고 있습니다.
    기존에 배포되는 static 라이브러리 잘 쓰고 있었는데, 속도 욕심이 생겨 도전해볼까 합니다.
    질문이 있는데, TBB와 IPP는 모두 Intel 용입니다. 만약 이 글의 방법대로 빌드한 라이브러리를 사용한 프로그램을, AMD CPU에서 사용하게 되면 호환이 안되나요? 아니면 TBB & IPP를 쓰지 않도록 내부적으로 처리가 되게 되나요??

    • BlogIcon 다크pgmr 2015.06.15 07:55 신고 수정/삭제

      안녕하세요. tbb의 경우 구글링을 해보니 관계없이 동작하는것 같습니다.

  • 나그네 2015.07.02 00:36 신고 ADDR 수정/삭제 답글

    안녕하세요. 답변 감사합니다. 또 이렇게, 늘 감사한 마음으로, 질문 하나 남기겠습니다.
    이 글의 방법대로 했을 때, 기존 코드를 라이브러리 교체만으로도 성능향상을 할 수 있다는게 다크님 말씀이신데, IPP는 실제로 그러한듯 합니다만, TBB는 아닌 것 같습니다. 각 모듈의 소스코드를 봐도 병렬처리가 구현된 부분이 없습니다. 그리고 실제로 IPP없이 TBB만 추가하여 재빌드 하였을 때는 성능 향상이 전혀 없었습니다. CPU 점유율도 그대로 였고요.
    제가 실험한 버전은 2.4.9, 2.4.11, 3.0.0 입니다.
    다크님은 TBB를 포함하여 재빌드 하는 것만으로도 내부적인 병렬처리가 되어있다고 믿으시는 것 같은데 확인 부탁드립니다.(극히 일부 함수는 되어있는 것 같습니다만, 템플릿매칭이나 푸리에변환 같은 것들은 되어있지 않은 듯 합니다.)

    • BlogIcon 다크pgmr 2015.07.02 10:24 신고 수정/삭제

      네, opencv 함수에 따라서 병렬처리 루틴이 구현된 것도 있고 구현되지 않은 것도 있는 것은 알고 있습니다. 그런데, 이 부분이 블로그 글에 명시되어 있지 않아서 괜한 오해를 불러일으킨 것 같아서 미안한 마음입니다. 관련 내용을 글 서두에 추가하였습니다.

      연구용, 테스트용이라면 동적 라이브러리로 충분하지만 저는 배포용이 목적이라서 정적 라이브러리로 빌드하게 되었습니다. 과정이 힘들긴 하지만 한번 만들어 놓으면 유용하게 사용될 수 있다고 생각합니다. 영상처리 알고리즘을 구현하면서 opencv 기능을 한가지만 사용하는 것이 아니다 보니 전체를 최적 라이브러리로 만들어 놓고 그중 일부라도 성능향상이 되는 부분이 있으면 좋다고 생각해 주시면 좋겠습니다.

      opencv 기능들 중에서 병렬처리 루틴이 구현되어 있는 것들을 찾아보니 생각보다 많진 않은 것 같습니다. 참고로 opencv에서 병렬처리가 구현되어 있는 모듈들은 다음과 같습니다.
      옵티컬 플로우 계산, 색상변환 루틴들, 히스토그램 계산, 이진화(thresholding), k-means clustering, solvepnp, 스테레오 매칭, retina 필터, image warp, smoothing, HOG 물체인식, Haar 물체인식, surf, svm, 노이즈제거 루틴, feature matching, 베이지안 classifier, k-nearest neighbor, 뉴럴 네트워크 루틴, Hough 변환, distance transform, ...

  • 서덕찬 2015.11.25 14:57 신고 ADDR 수정/삭제 답글

    안녕하세요. 먼저 좋은 글 감사합니다.
    위 말씀하신 TBB 사이트 가서 Download 페이지에서 Windows OS용 파일들을 받으니 static lib가 있는거 같은데요. 그럼 위에 설명하신 TBB static library 빌드는 따로 할 필요가 없는거 같은데요. tbb44_20151010oss_win_1.zip 파일 내부에 lib 하위에 ia32, intel64 에 static lib가 있는것 같습니다. 확인 부탁드립니다. 그리고 ia32와 intel64 차이는 뭔가요? 32, 64 bit 차이인가요?

    • BlogIcon 다크pgmr 2015.11.25 15:59 신고 수정/삭제

      말씀하신 것은 static용이 아니라 일반 dll용 lib 파일들입니다.. static용은 staticlib라고 폴더명 등에 명시되는 게 보통입니다. ia32는 intel architecture 32의 약자로서 32비트 시스템용이고, intel64는 64 비트 시스템용입니다.

    • 서덕찬 2015.11.25 18:31 신고 수정/삭제

      아 그렇군요. 저는 static lib 인줄 알았습니다. 매번 답변 감사합니다. ^^

  • DDongk 2016.02.16 14:44 신고 ADDR 수정/삭제 답글

    이 부분에 대한 자료가 없어서 검색끝에 왔는데, 예전에 tracking 관련 공부할때도 자주 왔던 블로그였네요 너무나 대단하신듯합니다! 좋은정보 잘얻고 갑니다!

    • BlogIcon 다크pgmr 2016.02.17 01:43 신고 수정/삭제

      부족한 지식이지만 어떤 분들에게는 도움이 된다니 감사합니다 ^^

  • SW 2016.03.09 06:50 신고 ADDR 수정/삭제 답글

    라이브러리 파일들을 정적으로 넣엇는데 제가 필요한 cv.h , highgui.h 가 include 파일안에 있던데 실행파일만 생성하기위해서는 이 h파일의 내용도 프로젝트안에 추가하고 h파일이 include 하는 library들의 .h .hpp 파일들도 추가해야되나요?

    • BlogIcon 다크pgmr 2016.03.09 10:04 신고 수정/삭제

      네 당연히 추가해야 합니다만, 일일히 추가할 필요는 없으며 예를 들어 highgui.hpp만 추가하면 관련된 h, hpp 파일들이 알아서 내부적으로 추가되기 때문에 자신이 직접 추가할 필요는 없습니다. 즉, 자신이 생성한 프로젝트에는 highgui.hpp만 추가하면 됩니다.

    • SW 2016.03.09 15:25 신고 수정/삭제

      highgui.hpp를 추가하면 다른 관련된 h,hpp를 알아서 내부적으로 추가한다고 하셨는데 제가 다른컴퓨터로 실행파일을 전송할때 관련된 h,hpp도 보내야하지 않나요?? 저는 실행파일만 전송하여 동작하게 하고싶은데..ㅠㅠ

    • BlogIcon 다크pgmr 2016.03.10 09:03 신고 수정/삭제

      h, hpp 등 소스코드는 프로그램을 컴파일할 때(실행파일을 build 할 때)만 필요하고 실행파일을 실행시킬 때는 필요가 없습니다. 당연히 h, hpp 등을 따로 보내실 필요는 없습니다.

  • 샤 쟈 2016.03.15 23:34 신고 ADDR 수정/삭제 답글

    정말 유용한 정보 감사합니다^^ 대학원생인데 실력이 한단계 늘 수 있는 계기가 된 것 같습니다!

  • ㅈㅈ 2016.05.27 12:01 신고 ADDR 수정/삭제 답글

    vfw32.lib 와 comctl32.lib가 생성되지 않아요 ..
    1>main.obj : error LNK2019: "class cv::Mat __cdecl cv::imread(class cv::String const &,int)" (?imread@cv@@YA?AVMat@1@AEBVString@1@H@Z) 외부 기호(참조 위치: main 함수)에서 확인하지 못했습니다.
    1>opencv_highgui310d.lib(window_w32.obj) : error LNK2019: "bool __cdecl cv::imwrite(class cv::String const &,class cv::_InputArray const &,class std::vector<int,class std::allocator<int> > const &)" (?imwrite@cv@@YA_NAEBVString@1@AEBV_InputArray@1@AEBV?$vector@HV?$allocator@H@std@@@std@@@Z) 외부 기호(참조 위치: "void __cdecl showSaveDialog(struct CvWindow *)" (?showSaveDialog@@YAXPEAUCvWindow@@@Z) 함수)에서 확인하지 못했습니다.
    1>opencv_highgui310d.lib(window_w32.obj) : error LNK2019: cvConvertImage 외부 기호(참조 위치: cvShowImage 함수)에서 확인하지 못했습니다.

    이런 에러가 발생하는데 저 두 lib없어서 그런거 맞나요?

    • BlogIcon 다크pgmr 2016.05.27 14:17 신고 수정/삭제

      vfw32.lib, comctl32.lib는 윈도우즈 OS 시스템에서 기본적으로 제공되는 것으로서 따로 생성하는 것이 아니라 그냥 컴퓨터에 깔려 있는 것을 사용하기만 하면 됩니다. 즉, 프로젝트에서 링크만 걸어주면 됩니다. 에러 메시지로 볼 때 필요한 *.lib 파일들에 대한 링크가 누락된 것으로 보입니다.

  • BlogIcon 너부리이놈 2016.07.14 14:48 신고 ADDR 수정/삭제 답글

    안녕하세요.
    윈도우7
    비주얼스튜디오2015
    opencv 3.1인데
    리눅스(centos)에서 작동하는 파일로 만드려면 어떻게 하나요?

  • 감사합니다 2016.08.28 13:43 신고 ADDR 수정/삭제 답글

    오류 20 error LNK2001: _ippicvsSortDescend_8u_I@8 외부 기호를 확인할 수 없습니다. C:\Users\junhee\Documents\Visual Studio 2012\Projects\VS_0828\VS_0828\opencv_core300.lib(matrix.obj) VS_0828
    이런 류의 에러메시지가 많이 뜨네요 링크는 누락된 것이 없는것 같은데요
    dynamic 라이브러리에서 돌아가던 코드가 static 라이브러리에서 안 돌아가거나 혹은 함수가 다르거나 그런 경우가 있나요?

    • BlogIcon 다크pgmr 2016.08.29 09:10 신고 수정/삭제

      저도 3.0 이상은 빌드해 보지 않아서.. 구글에 한번 검색해 보시면 좋을 것 같습니다.

  • 안녕하세요 2016.09.23 10:22 신고 ADDR 수정/삭제 답글

    안녕하세요, opencv와 mfc를 이용해서 실행파일을 만들어서 다 합쳐보려고 합니다. 그런데 혹시 tbb와 ipp 없이 cmake 만으로 하게되면 동작을 안하나요?

    • BlogIcon 다크pgmr 2016.09.23 11:32 신고 수정/삭제

      아니요.. 부가적인 것으로서 없어도 동작하는데는 전혀 문제가 없습니다.

  • BlogIcon farobi 2017.01.02 16:17 신고 ADDR 수정/삭제 답글

    안녕하세요. 다크님의 항상 도움이 되는 자료 감사드립니다.ㅎㅎ
    저는 현재 VS2010과 MFC, openCV 2.4.10을 사용하고 있습니다.
    CMake를 사용해서 새로이 빌드를 완료했고(다크님께서 중요하다고 하신 부분만 체크박스 해제하였습니다.TBB랑 ipp는 사용하지 않을거라 체크하지 않았습니다.) openCV 프로젝트 안에 들어있는 모든 프로젝트들의 런타임 라이브러리를 /MTd로 바꾸었습니다.(디버그용)
    링크를 연결하고 컴파일해보니
    1>libcmtd.lib(wwincrt0.obj) : error LNK2005: __aenvptr already defined in libcmtd.lib(dllcrt0.obj)
    1>libcmtd.lib(wwincrt0.obj) : error LNK2005: __wenvptr already defined in libcmtd.lib(dllcrt0.obj)
    1>libcmtd.lib(wwincrt0.obj) : error LNK2005: ___error_mode already defined in libcmtd.lib(dllcrt0.obj)
    1>libcmtd.lib(wwincrt0.obj) : error LNK2005: ___app_type already defined in libcmtd.lib(dllcrt0.obj)
    1>C:\Users\Giyeon Lee\Documents\Visual Studio 2010\Projects\StaticLibTest\Debug\MFCTest.exe : fatal error LNK1169: one or more multiply defined symbols found
    계속 중복정의되어있다고 오류가 발생합니다.
    환경변수에 설정되어 있던 opencv 링크도 제거하였습니다.
    동적 환경(dll 사용)에서 컴파일할 때는 잘 동작하던 프로그램이라 static 환경에서 작동하지 않는 이유를 모르겠습니다.ㅜㅜㅜ

    • BlogIcon 다크pgmr 2017.01.02 16:44 신고 수정/삭제

      저도 잘은 모르겠습니다만 혹시 opencv를 빌드할 때 BUILD_WITH_STATIC_CRT를 체크해제 하였는지 확인해 보시기 바랍니다.



티스토리 툴바