2016/11/04

Free Delphi/C++ Builder 10.1 Berlin Starter Edition

Embacadero 사에서 그동안 유로로 배포해오던 Delphi/C++ Builder 10.1 Berlin Starter Edition을 무료로 공개하였다. 특별 제공이라 하는데 기한이 있는지는 모르겠다.

다운로드 경로
Delphi: https://www.embarcadero.com/products/delphi/starter/promotional-download
C++ Builder: https://www.embarcadero.com/products/cbuilder/starter/promotional-download

경로는 다르나 동일 파일인 것 같다. 아직 설치는 하지 않았지만 인터넷이 연결된 상태에서 설치가 가능할 파일로 설치시 패키지를 설정하는 것 같다.

다운로드를 위해서는 Embarcadero Developer Network (EDN)에 가입이 되어 있어야 한다. 가입이 되어 있지 않을 경우 간단한 가입 절차를 거쳐 다운로드 할 수 있으며 가입된 메일 계정으로 설치에 필요한 키가 전달이 된다.

Embacadero 사가 Starter 버전을 무료로 배포하는 이유는 아무래도 경쟁사 제품을 의식해서인듯 하다. 개발툴의 저변 확대를 노리고 있을테지만 그리 큰 효과를 볼 수는 없을 것 같다.
경쟁제품이라 할 수 있는 MS사의 Visual Studio는 아주 오래전부터 Express 버전을 제공해 왔고 얼마전부터는 거의 모든 기능을 포함하고 있는 Community 버전을 개인에 한하여 무료로 제공하고 있었다.
Embacadero 사의 Starter 버전은 얼마되지 않았으며 그 동안 유료(Delphi - $320.2, C++ Builder - $238.7)로 배포되고 있었다. 게다가 이번에 무료로 공개하는 Embacadero 사의 Starter 버전의 기능 제한이 매우 많아 보인다. MS의 Visual Studio Community 버전의 경우 일반 개발에 필요한 대부분의 기능을 사용할 수 있지만 Embacadero 사의 Starter 버전은 대부분의 기능을 사용하지 못 한다. 할 수 있는 것이라고는 윈도우에서 32비트 Application 개발에만 사용할 수있다.

아래 제품 비교표를 보면 쉽게 알 수 있다.
Visual Studio: https://www.visualstudio.com/vs/compare/
Delphi: https://www.embarcadero.com/products/delphi/product-editions
C++ Builder: https://www.embarcadero.com/products/cbuilder/product-editions

Community 버전을 생각하고 다운을 받았는데 확인해보니 그렇지 않아 설치를 망설이고 있다.
아마 하지 않을 것 같다.

2016/11/03

Using CEF(Chromium Embedded Framework) with MFC Part2

이전 글(http://neodreamer-dev.blogspot.kr/2016/11/UsingCEFwithMFCPart1.html)에 기록한대로 만든 libcef_dll_warpper.dll 을 테스트하여 보았다.
테스트에 사용된 코드는 인터넷에서 CEF 사용 방법을 찾아 돌아다니다 얻은 여러 코드를 조합하여 작성한 코드인데 출처가 기억이 나지 않는다.
단순히 CEF를 올리고 구글 페이지로 접속을 하는 코드이다.
프로젝트는 다이얼로그 기반으로 기본 컨트롤을 모두 삭제하고 브라우저를 생성하기 위해 Static  컨트롤 하나만 올린 상태이다.


//////////////////////////////////////////////////////////////////////////
// CEF
//#define CEF_USING_SANDBOX
#include "include/cef_app.h"
#include "include/cef_client.h"

//* CEF_3.2840.1511
 #ifdef _WIN64
  #ifdef _DEBUG
    #pragma comment(lib, "../CEF_3.2840.1511/bin_x64/Debug/libcef.lib")
    #ifdef CEF_USING_SANDBOX
      // MT Only
      #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Sandbox/Debug/libcef_dll_wrapper.lib")
    #else
      #ifdef _DLL
        // MD
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Debug/libcef_dll_wrapper_mdd.lib")
      #else
        // MT
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Debug/libcef_dll_wrapper_mtd.lib")
      #endif
    #endif
  #else // Release
    #pragma comment(lib, "../CEF_3.2840.1511/bin_x64/Release/libcef.lib")
    #ifdef CEF_USING_SANDBOX
      // MT Only
      #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Sandbox/Release/libcef_dll_wrapper.lib")
    #else
      #ifdef _DLL
        // MD
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Release/libcef_dll_wrapper_md.lib")
      #else
        // MT
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x64/Release/libcef_dll_wrapper_mt.lib")
      #endif
    #endif
  #endif
#else
  #ifdef _DEBUG
    #pragma comment(lib, "../CEF_3.2840.1511/bin_x86/Debug/libcef.lib")
    #ifdef CEF_USING_SANDBOX
      // MT Only
      #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Sandbox/Debug/libcef_dll_wrapper.lib")
    #else
      #ifdef _DLL
        // MD
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Debug/libcef_dll_wrapper_mdd.lib")
      #else
        // MT
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Debug/libcef_dll_wrapper_mtd.lib")
      #endif
    #endif
  #else // Release
    #pragma comment(lib, "../CEF_3.2840.1511/bin_x86/Release/libcef.lib")
    #ifdef CEF_USING_SANDBOX
      // MT Only
      #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Sandbox/Release/libcef_dll_wrapper.lib")
    #else
      #ifdef _DLL
        // MD
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Release/libcef_dll_wrapper_md.lib")
      #else
        // MT
        #pragma comment(lib, "../CEF_3.2840.1511/lib_x86/Release/libcef_dll_wrapper_mt.lib")
      #endif
    #endif
  #endif
#endif
//*/
//////////////////////////////////////////////////////////////////////////

BOOL CTestCEFinMFCDlg::DestroyWindow()
{
  CefShutdown();

  return CDialogEx::DestroyWindow();
}

BOOL CTestCEFinMFCDlg::OnInitDialog()
{
  :
  CRect rcBrowser;
  GetDlgItem(IDC_STATIC_BROWSER)->GetClientRect(&rcBrowser);

  //Create the necessary objects needed to initialize CEF 
  CefMainArgs cefMainArgs(theApp.m_hInstance);

  CefSettings cefSettings;
  CefBrowserSettings cefBrowserSettings;
  CefRefPtr<CefApp> cefApplication;
  CefWindowInfo cefWindowinfo;

  cefSettings.multi_threaded_message_loop = true; //needed for MFC projects (unless we want to implement custom message-loop)
  cefWindowinfo.SetAsChild(GetDlgItem(IDC_STATIC_BROWSER)->GetSafeHwnd(), rcBrowser);

  //   CefRefPtr<CefClient> client(new ClientHandler());
  //   m_Handler = (ClientHandler*)client.get();

  //Initialize CEF 
  bool bSucceeded = CefInitialize(cefMainArgs, cefSettings, cefApplication, nullptr);
  CefRefPtr<CefRequestContext> request_context;

  CefRefPtr<CefClient> client;
  if (bSucceeded)
  {
    CefBrowserHost::CreateBrowser(cefWindowinfo, client, L"http://www.google.com/", cefBrowserSettings, request_context);
  }  
  :
}


Using CEF(Chromium Embedded Framework) with MFC Part1

Using CEF(Chromium Embedded Framework) with MFC Part1

MFC를 이용하여 Application을 만들 때 Windows 기본 브라우저 말고 크롬을 올리기 위해 방법을 찾아 보았다.
Chromium Embedded Framework(이하 CEF) 라는 프로젝트를 찾았고 현재 버전 3까지 나와 있다. CEF를 MFC 프로젝트에 사용을 하려면 libcef_dll_wrapper.dll을 만들어야 한다.
이때, 컴파일러 옵션중 Runtime Library 설정에 따라 사용할 수 있는 libcef_dll_wrapper.dll을 만들어야 한다. 라이브러리를 만들 때 Sandbox 사용 설정 여부에따라 만들어진 라이브러리의 사용에 제한이 있는 것 같았다. 우선 Sandbox 설정을 제외하고 빌드 해 보았다.
빌드를 하는 방법은 어렵지 않으나 나중에 참고하기 위해 정리를 하였다.

libcef_dll_wrapper.dll를 만들기 위해서는 CEF Automated Builds 사이트(http://opensource.spotify.com/cefbuilds/index.html)에서 소스를 다운 받는다. 그리고 빌드 환경을 구성할 CMake 를 준비한다.
글을 작성하는 현재 버전은 CEF 3.2840.1512.g3f66e81(Chromium 54.0.2840.59) 이고, 빌드에 사용된 버전은 CEF 3.2840.1511.gb345083(Chromium 54.0.2840.59) 이다.
사용하고자 하는 버전과 일치하는 Standard Distribution 을 다운 받아 압축을 해제한다.
CMake를 실행하여 소스 경로에 압축을 해제한 경로를 설정하고 Build the binaries 경로에 프로젝트를 생성한 경로를 설정한고 Configure를 신행한다.
많은 설정 중 마지막에 있는 USE_OFFICIAL_BUILD_SANDBOX, USE_SANDBOX 설정을 해제한다.
해제하지 않을 경우 만들어 지는 프로젝트는 Runtime Library 옵션이 /MT 로 고정이 된다. 다른 옵션을 만들어 테스트해 보았지만 기존의 만들어진 cef_sandbox 라이브러리가 /MT 옵션으로 고정되어 있어서인지 다른 설정으로 바꾸면 프로젝트를 빌드 할 때 링크 에러가 발생하여고 빌드가 되지 않았다.
Sandbox를 사용하지 않는 경우에는 여러 Runtime Library에 대한 사용에 문제가 없었다. Sandbox 이용에 대해서는 나중에 좀 더 확인을 해 봐야겠다.
설정을 마치고 Configure 를 실행 한 후 Generate를 실행하여 프로젝트를 생성한다.

그리고 Build the binaries 경로에있는 cef.sln 을 Visual Studio로 열어 libdef_dll_wrapper 프로젝트의 속성 페이지를 열어 추가하고자 하는 프로젝트와 동일한 Runtime Library 옵션을 선택하고 빌드한다.
본인의 경우 /MD /MDd /MT /MTd 옵션을 각각 설정하고 출력 파일 이름을 달리하여 추후 사용할 때 골라서 사용할 수 있도록 빌드하였다. 그래서 만들어진 파일이 아래 파일들이다.
libcef_dll_wrapper_mtd.pdb
libcef_dll_wrapper_mdd.lib
libcef_dll_wrapper_mtd.lib
libcef_dll_wrapper_mdd.pdb
libcef_dll_wrapper_mt.lib
libcef_dll_wrapper_md.lib

이 파일들을 이용하여 MFC 프로젝트에 CEF를 사용하면 된다.

2016/10/20

Create barcode using Zint static library

이전 글에서 작성한 대로 생성한 Zint 정적 라이브러리를 이용하여 바코드를 생성해 보았다.
Build Zint static library on windows

라이브러리는 정상적으로 동작을 하였다.
사용법은 설명 보다는 코드로 남기는 것이 이해가 쉬울 것 같아 코드로 남긴다.

struct zint_symbol *pZintSymbolStruct;

    // Zint symbol 생성
    pZintSymbolStruct = ZBarcode_Create();
    if (pZintSymbolStruct != nullptr)
    {
        TRACE("Symbol successfully created!\n");

        // 생성할 바코드 문자열. 최대 128자
        unsigned char szBuf[ZINT_TEXT_SIZE] = "created barcode by Zint\0";

        // 주어진 문자열로 바코드 생성.
        // 문자열 길이를 0으로 입력하면 입력된 문자열의 첫번째 Null 까지 Encode.
        ZBarcode_Encode(pZintSymbolStruct, szBuf, 0);

        // 생성한 바코드를 파일로 저장.
        // 바코드 타입을 설정하지 않으면 기본으로 Code 128이 설정된다.
        // Symbol 생성시 기본 출력 파일 이름은 out.png
        // 각도는 0, 90, 180, 270 를 입력할 수 있다.
        // 그 이외의 각도를 넘기면 예외가 발생한다.
        ZBarcode_Print(pZintSymbolStruct, 0);


        // Symbol 초기화
        ZBarcode_Clear(pZintSymbolStruct);
        // Barcode를 QRCode로 지정
        pZintSymbolStruct->symbology = BARCODE_QRCODE;
        // 출력 파일은 out2.png로 지정
        strcpy_s(pZintSymbolStruct->outfile, FILENAME_MAX, "out2.png");
        // 바코드로 생성할 문자열 설정
        strcpy_s((char*)szBuf, ZINT_TEXT_SIZE, "한글 바코드, 韓字!");
        // 인코딩과 파일 저장을 한번에 수행
        ZBarcode_Encode_and_Print(pZintSymbolStruct, szBuf, 0, 0);


        // Symbol 초기화
        ZBarcode_Clear(pZintSymbolStruct);
        pZintSymbolStruct->symbology = BARCODE_QRCODE;
        strcpy_s((char*)szBuf, ZINT_TEXT_SIZE, "메모리에 바코드 생성");
        // 바코드를 인코딩하여 메모리에 저장
        // 바코드는 pZintSymbolStruct->bitmap 에 저장
        ZBarcode_Encode_and_Buffer(pZintSymbolStruct, szBuf, 0, 270);

        // 메모리에 저장된 바코드 이미지를 이용하여 OpenCV Mat 생성
        cv::Mat matBarcode = cv::Mat(
            pZintSymbolStruct->bitmap_height
            , pZintSymbolStruct->bitmap_width
            , CV_8UC3
            , pZintSymbolStruct->bitmap);

        // 화면에 보여주기
        cv::namedWindow("Barcode");
        cv::imshow("Barcode", matBarcode);
    }

    // Symbol 삭제
    ZBarcode_Delete(pZintSymbolStruct);

zint_symbol 구조체에 여러 설정을 하여 바코드를 생성할 수 있다.
설정할 수 있는 항목은 여백, 배경색, 전경색, 테두리 등을 설정할 수 있다.
자세한 설정 방법은 Zint 매뉴얼(http://www.zint.org.uk/Manual.aspx?type=p&page=1)에 설명되어 있다.

2016/10/19

Build Zint static library on windows

ZXing 자바 버전에는 바코드를 생성할 수 있지만 cpp 버전인 ZXing cpp에는 바코드 생성 기능이 포함되저 있지 않았다. 그래서 바코드를 생성할 수 있는 라이브러리를 찾다가 발견한 것이 ZInt 이다.
CMake를 지원하여 쉽게 빌드가 될 줄 알았는데 종속성때문에 쉽게 되지 않았다. ZInt를 빌드하려면 zlib와 libpng가 필요한데 Zint에 포함되어 있지 않아 직접 만들어서 구성을 해 줘야 한다. 직접 빌드하여 ZInt에 포함되어 있는 프로젝트를 빌드해보려 했지만 여러차례 실패하고 직접 프로젝트를 만들어 정적 라이브러리를 생성했다.
잊지 않기 위해 빌드 절차를 기록 했다.

우선 필요한 라이브러리인 zlib와 libpng를 빌드 한다.
CMake를 이용하여 빌드 환경을 구성 하였다.
zlib는 CMAKE_INSTALL_PREFIX만 설정하고 빌드 하였다.
빌드하면 동적 라이브러와 정적 라이브러리를 얻을 수 있다.

libpng의 경우 빌드해 놓은 zlib 정보를 설정해 주어야 한다.
아래 항목에 대하여 입력을 해 준다.
CMAKE_INSTALL_PREFIX: 설치 경로
ZLIB_INCLUDE_DIR: zlib CMAKE_INSTALL_PREFIX/include
ZLIB_LIBRARY_DEBUG: zlib project path/Debug/zlibstaticd.lib
ZLIB_LIBRARY_RELEASE: zlib project path/Release/zlibstatic.lib

이제 본격적으로 ZInt를 빌드할 차례이다.
먼저 Visual Studio에서 정적 라이브러리 프로젝트를 생성하고 ZInt 에 포함되어있는 backend 폴더의 소스를 생성한 프로젝트에 모두 추가한다.
그리고 Preprocessor 설정에 Zint 라이브러리 버전을 아래와 같이 설정해 주어야 한다.
Preprocessor definitions
ZINT_VERSION="2.4.3.0"

다음으로 추가 포함 경로에 zlib와 libpng 의 설치 경로의 include 폴더를 지정한다.
zlib's CMAKE_INSTALL_PREFIX\include
libpng's CMAKE_INSTALL_PREFIX\include

다음, 추가 라이브러리 경로를 Debug와 Release에 맞게 설정 한다.
Additional Library Directories
Debug
zlib project path\Debug
libpng project path\Debug

Release
zlib project path\Release
libpng project path\Release

마지막으로 추가 종속성 라이브러리를 설정 한다.
Librarian -> Additional Dependencies
Debug
zlibstaticd.lib, libpng16_staticd.lib

Release
zlibstatic.lib, libpng16_static.lib

이제 구성을 다 마쳤다. 빌드만 하면 된다.
Visual Studio 2015버전으로 빌드를 했는데 아무런 에러없이 정적 라이브러리를 얻을 수 있었다.
다음에는 만들어진 라이브러리를 이용해서 바코드를 만들어 보겠다.

2016/10/17

Reading barcode with zxing-cpp and OpenCV

zxing(https://github.com/zxing/zxing)을 이용하여 바코드 읽기를 테스트 해 보았다.
zxing은 원래 java로 만들어진 라이브러리인데 다양한 언어로 지원을 하고 있었다. C++의 경우 초기부터 지원을 해 오다가 zxing이 java 이외의 언어에 대한 지원이 소극적이더니 결국 C++은 더이상 지원을 하지 않고 있다. 다행이 C++을 지원하는 third-party projects(zxing cpp: https://github.com/glassechidna/zxing-cpp) 가 있어서 C++에서 쉽게 ZXing을 사용할 수 있었다.

ZXing cpp 빌드는 쉽게 하였는데 OpenCV 데이터를 ZXing에 넘기는게 문제였다. 컬러채널 및 흑백채널데이터를 넘겨도 ZXing에서 인식을 하지 못하였다.

인터넷을 검색하던 중 OpenCV의 이미지인 Mat 객체를 이용한 소스가 공개된 것을 찾았다.
https://github.com/geduino-foundation/zxing-cpp
MatSource는 LuminanceSource를 상속받아 getRow와 getMatrix 함수가 구현되어 있다. cv::Mat 객체로 생성을 하는 생성자가 있어 쉽게 객체를 생성할 수 있었다. 단 MatSource를 생성할 때 흑백 영상을 이용해야 한다.

아래 코드는 MatSource를 이용한 바코드 인식 코드 이다. OpenCV 예제소스는 QRCode만 인식하도록 되어 있어서 기본 코드에 있는 코드를 사용해 보았다.

source = MatSource::create(matGray);
 
vector<Ref<Result>>& vResult
string strResult;
try
{
    Ref<Binarizer> binarizer;
    if (bHybrid) 
    {
        binarizer = new HybridBinarizer(source);
    }
    else
    {
        binarizer = new GlobalHistogramBinarizer(source);
    }

    DecodeHints hints(DecodeHints::DEFAULT_HINT);
    hints.setTryHarder(false);
    Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
    if (bSearchMulti)
    {
        MultiFormatReader delegate;
        GenericMultipleBarcodeReader reader(delegate);
        vResult = reader.decodeMultiple(binary, hints);
    }
    else
    {
        Ref<Reader> reader(new MultiFormatReader);
        vResult.push_back(reader->decode(binary, hints));
    }
}
catch (const ReaderException& e) 
{
    strResult = "zxing::ReaderException: " + string(e.what());
}
catch (const zxing::IllegalArgumentException& e) 
{
    strResult = "zxing::IllegalArgumentException: " + string(e.what());
}
catch (const zxing::Exception& e) 
{
    strResult = "zxing::Exception: " + string(e.what());
}
catch (const std::exception& e) 
{
    strResult = "std::exception: " + string(e.what());
}

2016/10/09

Memory leak problem with OpenCV 3.1 custom build

OpenCV 빌드 후 라이브러리를 테스트 하는 도중 Debug 빌드 라이브러리의 메모리 누스가 포착 되었다.
오래전 2.2 버전을 빌드하여 테스트 할 때에도 비슷한 문제가 있었는데 동일하지는 않지만 유사한 것 같다.
Release 버전으로 테스트한 결과 문제가 없었다. 혹시나 해서 OpenCV.org에서 배포하는 배포(Release 버전 밖에 없는) 버전으로 테스트 해 보았는데 문제가 없었다.
공식 배포 버전은 Release 버전밖에 없어 Debug 모드에서의 테스트는 할 수 없었고 공식배포건 빌드한 버전이던 Release 버전에는 문제가 없었다.

Test OpenCV 3.1 with VTK 7.0 in Visual Studio 2015

지난 포스팅에서 설명한 OpenCV 3.1 빌드 후 생성 된 라이브러리는 테스트 해 보았다.

Build OpenCV 3.1 with VTK 7.0 in Visual Studio 2015

OpenCV 테스트는 opencv_world 라이브러리만 사용하면 되었고 VTK를 사용한 opencv_viz를 사용하려면 VTK include 파일과 opencv_world 가 아닌 개별 빌드한 라이브러리를 사용해야만 했다.

Hello OpenCV Viz

이전 포스트에서 테스트했던 OpenCV viz 소스가 문제없이 동작을 하였다.

+ 2016/10/12
opencv_viz 모듈이 opencv_core 모듈을 참조하는 것은 빌드할 때 opencv_core 라이브러리를 참조하였기때문이였다. dll 수를 줄이기 위해 opencv_world를 사용할 수 있도록 opencv_viz 빌들할 때 참조 라이브러리를 opencv_world로 변경을 하니 opencv_viz.dll 과 opencv_world.dll 파일만 있으면 opencv_viz 관련 함수들이 동작을 하였다.

2016/10/07

Build OpenCV 3.1 with VTK 7.0 in Visual Studio 2015

Build OpenCV 3.1 with VTK 7.0 in Visual Studio 2015

Visual Stuido 2015 버전에서 OpenCV 3.1과 VTK 7.0을 빌드해 보았다.

주인공인 OpenCV 3.1와 VTK 7.0 가 준비가 되어야 겠고 빌드 구성을 위해 CMake가 필요하다.
CMake 는 3.6.2 버전을 사용하였다.

우선 VTK를 OpenCV 빌드에 사용할 수 있도록 빌드를 해야 한다. 빌드를 신속하게 하기위해 필요 없는 것으 빌드하지 않도록 하였다. 그리고 이때 주의 할 사항은 OpenGL설정이다. VTK 7.0에서는 Rendering Backend가 OpenGL2 로 새롭게 작성이 되었고 이 것이 기본값으로 되어있다.
하지만 OpenCV 에서는 이를 지원하지 않고 이전 버전의 OpenGL을 사용해야 한다. 그래서 Rendering Backend 설정과 OpenGL 설정을 변경해 주어야 한다. 아래는 VTK를 빌드할 때 구성한 내용이다.

Srouce: E:/DevWork/OpenCV/VTK-7.0.0_x64
Build:  E:/DevWork/OpenCV/VTK-7.0.0_x64/VS2015_x64

Configuration options
  BUILD_EXAMPLES                   uncheck
  BUILD_SHARED_LIBS                uncheck
  BUILD_TESTING                    uncheck
  Module_vtkRenderingOpenGL        check
  Module_vtkRenderingContextOpenGL check
  Module_vtkRenderingVolumeOpenGL  check
  VTK_RENDERING_BACKEND            OpenGL
  CMAKE_INSTALL_PREFIX             BuildPath/install

Build projects
  ALL_BUILD with debug configuration
  INSTALL with release configuration

VTK 를 아무 문제없이 빌드를 했다면 이제 OpenCV를 빌드할 차례이다.
빠른 빌드를 위해 필요없는 항목은 제거를 했지만 간단한 테스트를 위해 Test 프로젝트를 빌드를 수행하였다.

Source: E:/DevWork/OpenCV/opencv_v3.1.0/sources
Build:  E:/DevWork/OpenCV/opencv_v3.1.0/VS2015_x64_vtk

Configuration options
  BUILD_DOCS            uncheck
  BUILD_EXAMPLES        uncheck
  BUILD_TESTS           check
  VTK_DIR               E:/DevWork/OpenCV/VTK-7.0.0_x64/VS2015_x64
  WITH_OPENGL           check
  WITH_OPENMP           check
 
  BUILD_opencv_python2  uncheck
  BUILD_opencv_python3  uncheck
  BUILD_opencv_viz      check

Build projects
  ALL_BUILD with debug configuration
  INSTALL with release configuration

위 설정으로 Configure를 마치면 로그화면에서 아래와 같이 VTK가 포함이 된 것을 확인 할 수 있다.
VTK support:                 YES (ver 7.0.0)

구성 완료후 빌드를 하여 bin 폴더의 test 파일들 중 opencv_text_viz.exe를 실행시켜 정상 동작을 확인 하였다.
마지막으로 opencv_world를 만들기 위해서 아래 설정을 변경하고 다시 빌드하였다.
viz와 world를 함께 빌드하면 문제가 발생을 하여 우선 viz를 제거하고 빌드하였다.
이 라이브러리를 정상적으로 사용이 가능한지는 추후 테스트를 해 봐야 알 수 있을 것 같다.

Configuration options
  BUILD_opencv_viz      uncheck
  BUILD_opencv_world    check
 
Build projects
  ALL_BUILD with debug & release configuration

Build 경로 아래의 install 폴더에 라이브러리를 사용하기 위한 파일들이 있다. 디버그용이 필요한 경우 Build 경로의 bin 폴더와 lib 폴더의 파일들을 이용하면 된다. 헤더파일은 install 폴더에 포함되어 있는 include 파일을 이용하면 된다.

라이브러리는 빌드 하였고 이제 테스트를 해 볼 차례이다.

2016/10/06

VTK Textbook and User Guide

VTK Textbook 과 User Guide가 PDF 버전으로 공개가 되었다.
내 기억으로는 구매를 인쇄본을 구매해야만 얻을 수 있었는데 이제 PDF 버전은 무료로 공개된 것 같다.


VTK Textbook
http://www.vtk.org/vtk-textbook/
http://www.kitware.com/products/books/VTKTextbook.pdf

VTK User Guide 11th
http://www.vtk.org/vtk-users-guide/
http://www.kitware.com/products/books/VTKUsersGuide.pdf

2016/10/05

Using VTK with MFC Project

VTK 버전 7.0이 나와서 새로 빌드도 해 보고 다시 공부좀 해볼까 하여 오랜만에 VTK를 빌드해 보았다.
아주 오랜만에 다시 해 보는 것이고 이전 기록이 많지않아 동일한 시행착오를 피할 수 없었다.
빌드를 무사히 마치고 Visual Studio 에서 테스트 하는데 더 큰 걸림돌이 있었다.
검색 결과 CMake를 이용하지 않는 경우 초기화(?) 코드가 필요 하였다.
게다가 버전 7은 버전 6에서 변경된 사항이 있어 동일한 코드로 초기화가 되지 않았다.
추후 동일한 문제로 고생하지 않기 위해 기록을 남긴다.


For VTK 6.x
다른 헤더파일을 포함하기 전에 먼저 "vtkAutoInit.h"를 포함하고 일부 모듈을 초기화 해 주어야 한다.

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingFreeTypeOpenGL);
VTK_MODULE_INIT(vtkRenderingOpenGL);

#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL,vtkRenderingOpenGL)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL)
http://www.vtk.org/Wiki/VTK/VTK_6_Migration/Factories_now_require_defines


For VTK 7.x
VTK 7.x의 경우 OpenGL이 OpenGL2로 새롭게 바뀌었으며 빌드할 때 별도의 설정을 하지 않은 경우 OpenGL2로 설정이 되기때문에 VTK 6.x 에서 초기에 수행한 OpenGL 설정을 OpenGL2 로 변경을 해 주어야 한다. 그리고 vtkRenderingFreeTypeOpenGL 은 삭제되었다 한다.

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingOpenGL2);

#define vtkRenderingCore_AUTOINIT 3(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingOpenGL2)
http://www.visitusers.org/index.php?title=VTK_7.1_Upgrade

2016/10/04

wofstream을 이용하여 한글 출력하기

wchar_t 문자열을 그대로 텍스트 파일에 출력하기위해 wofstream 객체에 << 연산자를 이용하였다. 잘 되는가 싶었는데 한글을 포함하여 기대대로 동작을 하지 않았다. 그래서 방법을 찾아보니 locale 설정을 해 주어야 한다고 한다. 전역으로 설정하던지 아니면 wofstream을 생성하고 해당 객체에 대해서 imbue함수를 이용하여 locale을 설정해 주면 된다.
 std::locale::global(std::locale("Korean")); // 방법 #1
 std::locale::global(std::locale("")); // 방법 #2
 wofstream fsOut;
 fsOut.imbue(std::locale("Korean")); // 방법 #3
 fsOut.imbue(std::locale("")); // 방법 #4
 fsOut.open( L"Output File Path", std::ios::out );

Write and read unicode test using wfstream

fstream을 이용하여 유니코드 문자를 저장하려 시도하였다. 쉽게 "w"만을 붙여서 wofstream을 이용하고 wchar_t 또는 wstring을 출력만 하면 될 줄 알았으나 기대대로 동작을 하지 않았다. 문자열 인코딩 문제등등 여러가지 복잡한 문제가 있었다. 여러 정보를 취합해 나중에 도움이 될 수 있도록 코드를 남겼다.

class Unicodecvt : public std::codecvt<wchar_t, char, mbstate_t>
{
protected:
 virtual bool do_always_noconv() const
 {
  return true;
 }
};

// Writting
std::wofstream fOut(L"D:\\test.txt", std::ios_base::binary);
fOut.imbue(std::locale(std::locale(""), ::new Unicodecvt));
fOut << wchar_t(0xFEFF);  // write BOM (UTF-16LE)
fOut << L"유니코드 출력 테스트: " << 12345 << std::endl;
fOut.close();

// Reading
std::wifstream fIn(L"D:\\test.txt", std::ios_base::binary);
fIn.imbue(std::locale(std::locale(""), ::new Unicodecvt));
if ( fIn.is_open() )
{
 fIn.seekg(2); // Skip BOM
 while ( !fIn.eof() )
 {
  wchar_t wszBuf[1024] = { 0, };
  fIn.getline( (wchar_t*)wszBuf, _countof(wszBuf));
 }
}
fIn.close();


참조 문서
https://golbenge.wordpress.com/2009/12/24/stl을-이용한-unicode-텍스트-파일-출력 http://saneh.tistory.com/entry/STL-유니코드-저장읽기

2016/05/11

MySQL 5.7 Manual Install

MySQL 최신 버전인 5.7 버전을 테스트할 일이 있어서 수동으로 설치해 보았는데 이전과 다른 사항이 있어 기록차원에서 정리하였다.

우선 설치에 필요한 압축 파일을 mysql.com 사이트로 부터 다운로드 받는다.
내가 받은 파일은 mysql-5.7.12-winx64.zip 이다. 이 파일을 특정 폴더에 압축을 풀어 놓는다.
여기에서는 E:\Dev\mysql-5.7.12-winx64 압축을 풀어 놓고 기록 하였다.

설정 파일 작성
설정 파일을 작성해야 하는데 압축해제 폴더의 my-default.ini 파일은 my.ini로 복사하여 편집한다.
# These are commonly set, remove the # and set as required.
basedir = E:\Dev\mysql-5.7.12-winx64
datadir = E:\Dev\mysql-5.7.12-winx64\data
port = 3316
# server_id = .....
basedir과 datadir을 필수이고 port는 필요시 지정 한다. 다른 MySQL을 운영으로 인해 또는 다른 이유로 인해 기본 포트인 3306을 사용하지 못하는 경우 다른 포트 입력한다.

환경 변수 등록
압축 해제 폴더를 시스템 환경 변수에 MYSQL_HOME 으로 등록한다. 임시로 사용하는 것으로 시스템 환경설정이 부담스러운 경우 도스창에서 mysqld 를 실행하기전에 아래 명령으로 환경변수 등록 한다.
E:\Dev\mysql-5.7.12-winx64\bin> set MYSQL_HOME = E:\Dev\mysql-5.7.12-winx64

MySQL  초기화
E:\Dev\mysql-5.7.12-winx64\bin> mysqld --initialize
위 명령으로 지정한 data 폴더에 필요한 파일 생성 된다. 혹시 실패한 경우 data 폴더의 내용을 모두 삭제하고 위 명령을 다시 수행한다.

권한 설정을 위한 데몬 실행
--skip-grant-tables 옵션으로 권한 설정을 무시하도록 데몬을 실행한다.
E:\Dev\mysql-5.7.12-winx64\bin> mysqld --skip-grant-tables

MySQL 접속
mysql.exe 실행파일을 이용하여 MySQL에 접속한다.
E:\Dev\mysql-5.7.12-winx64\bin> mysql -u root --port=3316
접속시 포트번호 지정은 설정에서 기본 포트인 3306을 사용하지 않고 다른 포트를 사용할 경우 입력한다.

root 암호 설정
--skip-grant-tables 옵션으로 인해 ALTER USER나 SET PASSWORD 명령을 사용할 수없어 mysql 데이터베이스에 접속하여 User 테이블을 직접 수정한다.
mysql> \u mysql
Database changed
mysql> UPDATE USER SET authentication_string = password('mypassword') WHERE user = 'root';

mysql 재시작
서비스 등록하지 않은 경우 Task Manager에서 mysqld 종료 후 --skip-grant-tables 옵션 없이 다시 시작 한다.
E:\Dev\mysql-5.7.12-winx64\bin> mysqld

MySQL 접속
위에서 설명한 방법으로 MySQL에 접속한다.

root 암호 재설정
위에서 root의 암호를 바꾸서 접속에 성공했음에도 불구하고 데이터베이스 선택 명령을 실행하면 아래와 같이 명령을 수행하기 전에 암호를 설정하로는 에러 메시지가 출력 된다.
RROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

아래 방법을 이용하여 root 암호를 다시 설정 한다.
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'mypassword';
또는
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('mypassword');

아래 사항은 필수 사항은 아니고 알아두면 나쁘지 않을 서비스 등록에 대한 내용이다.
mysql 서비스 등록또는 삭제
서비스 등록: E:\Dev\mysql-5.7.12-winx64\bin> mysqld --install [서비스이름]
서비스 삭제: E:\Dev\mysql-5.7.12-winx64\bin> mysqld --remove [서비스이름]
서비스 이름이 지정되지 않으면 기본적으로 'MySQL'로 서비스 등록 시도

서비스 시작: net start mysql
서비스 중지: net stop mysql

2016/05/03

Poco Library 빌드하기

얼마전에 공개된 Poco Library v1.7.3 버전을 빌드해 보았다.
배포되는 Poco Library 중 poco-1.7.3-all.zip 을 다운 받았다. 이 버전은 OpenSSL과 MySQL Client 라이브러리를 필요로 한다.

Poco Library 빌드를 위한 파일은 아래와 같다.
Poco Library
http://pocoproject.org/releases/poco-1.7.3/poco-1.7.3-all.zip
OpenSSL
https://slproweb.com/products/Win32OpenSSL.html
https://slproweb.com/download/Win32OpenSSL-1_0_2g.exe
https://slproweb.com/download/Win64OpenSSL-1_0_2g.exe
MySQL
32-bit ZIP Archive(http://dev.mysql.com/downloads/file/?id=462038)
64-bit ZIP Archive(http://dev.mysql.com/downloads/file/?id=462039)

우선 poco-1.7.3-all.zip 파일을 특정 경로에 압축을 해제 한다. 압축 해제  후 존재하지 않는 폴더 Bin, Bin64, Lib, Lib64를 생성한다. 여기서는 D:\poco-1.7.3-all 에 압축을 해제한 것으로 간주하고 기록 하였다.
Win32OpenSSL-1_0_2g.exe 설치후 설치 경로의 bin 폴더의 libeay32.dll, ssleay32.dll파일을 Bin 폴더에 복사하고 lib 폴더의 libeay32.lib, ssleay32.lib파일을 Lib 폴더에 복사한다. 그리고 lib/VC/static 폴더의 모든파일을 Lib 폴더로 복사한다.
Win64OpenSSL-1_0_2g.exe 파일의 경우 Bin64와 Lib64 폴더로 복사를 한다. 마지막으로 include 폴더의 openssl 폴더를 D:\poco-1.7.3-all\Crypto\include 폴더에 복사한다.

MySQL에 포함되어 있는 include 폴더의 모든 파일들을 D:\poco-1.7.3-all\Data\MySQL\include 복사하고 32비트 파일에 포함되어 있는 libmysql.dll파일과 libmysqld.dll 파일을 Bin 폴더로 libmysql.lib파일과 libmysqld.lib 파일을 Lib 폴더로 복사한다. 64비트 파일에 포함되어 있는 파일들은 각각 Bin64와 Lib64로 복사한다.

마지막으로 buildwin.cmd 파일을 열어 편집 한다.
수정해야할 내용은 set OPENSSL_LIB 부분으로 32비트 버전을 빌드 할 때에는 D:\poco-1.7.3-all\Lib 로 설정하고 빌드하고 64비트로 빌드 할 때에는 D:\poco-1.7.3-all\Lib64로 설정하고 빌드 한다.

이렇게 설정하고 아래와 같이 sample과 test프로젝트를 제외하고 빌드한다.
32bit: D:\poco-1.7.3-all\buildwin 110 build all both Win32 nosamples notests devenv
64bit: D:\poco-1.7.3-all\buildwin 110 build all both x64 nosamples notests devenv

buildwin 실행 결과 32비트와 64비트 모두 에러 없이 빌드를 마쳤고 dll과 lib 파일이 생성 되었다.

2016/03/21

Using wxPython phoenix with Python 3.5

http://wxpython.org/Phoenix/snapshot-builds/
위 사이트에서 받은 wxPython_Phoenix-3.0.3.dev1964+f780b21-cp35-cp35m-win32.whl 파일을 설치하고 간단한 코드로 테스트 하였더니 아래와 같은 에러 코드를 뿜어댔다.

Traceback (most recent call last):
  File "...\test.py", line 1, in <module>
    import wx
  File "D:\...\lib\site-packages\wx\__init__.py", line 17, in <module>
    from wx.core import *
  File "D:\...\lib\site-packages\wx\core.py", line 6, in <module>
    from ._core import *
ImportError: DLL load failed: [The respective module not found.
(message translated form the original localised version)]

위 에러 코드는 환경에따라 조금 다를 수 있다.
해결을 위해 구글링 해보았지만 답을 찾을 수 없었다. 문제로 wxmsw30u_core_vc140.dll 이 언급이 되어 파일의 존재를 확인해 보니 존재하고 있었다. 혹시 재배포 패키지가 해결책이 될 수 있을것 같아서 Visual C++ Redistributable for Visual Studio 2015를 아래 경로에서 다운받아 설치해 보았다.
https://www.microsoft.com/en-us/download/details.aspx?id=48145

재배포 패키지 설치 후 문제가 해결 되었다.

2016/01/10

Using wxPython on Python 3.4

wxPython 은 python에서 wxWidgets 라이브러리를 사용할 수 있도록 해 주는 라이브러리로 python v2 버전만을 지원한다.

python v3 버전을위해 wxPython Phoenix 이 개발중이다. python v3.4에 wxPython Phoenix을 설치하여 wxWidgets를 사용할 수 있다.

설치를 위해서는 wxPython Phoenix 홈페이지에서는 아래와 같은 명령어를 안내하고 있다.
    pip install -U --pre \
        -f http://wxpython.org/Phoenix/snapshot-builds/ \
        wxPython_Phoenix

하지만 종종 설치 실패를 하였다. 그래서 http://wxpython.org/Phoenix/snapshot-builds/ 사이트에서 최신 버전의 URL 주소를 가져와 직접 설치를 하면 된다.
현재(2016/01/10) 최신 버전은 wxPython_Phoenix-3.0.3.dev1836 이다.

아래 명령을 수행하여 설치를 하였다.
pip install http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1836+f764b32-cp34-none-win32.whl

그리고 간단하게 아래 코드를 이용하며 실행 여부를 확인하였다.
import wx

app = wx.App()

frame = wx.Frame(None, -1, "Hello World")
frame.Show()

app.MainLoop()

수동으로 python pip 설치하기

Python 설치 패키지(.msi)를 수동으로 압축해제하여 설치 할 때에는 pip가 설치되지 않는 것 같다.
그래서 수동으로 설치해야 하는데 설치하는 방법은 간단하다.

홈페이지에 아주 쉽게 설명되어 있다.
https://pip.pypa.io/en/stable/installing/#install-pip

https://bootstrap.pypa.io/get-pip.py 파일을 다운받아 아래와 같이 실행시켜주면 설치가 된다.

python get-pip.py