기본 콘텐츠로 건너뛰기

Windows에서 Column-by-Column 비디오 믹서 앱 개발환경 구축 가이드


Windows에서 Column-by-Column 비디오 믹서 앱 개발환경 구축 가이드

Windows 10 이상의 환경에서 Python과 C++를 함께 사용하여 컬럼 단위 비디오 믹서 애플리케이션을 개발하기 위해 필요한 환경 설정 과정을 단계별로 설명합니다. Python 3.10을 기반으로 GUI는 Tkinter로 구성하고, 성능을 위해 C++ 백엔드를 작성하여 Pybind11로 Python과 연동하며, 영상 처리에는 OpenCV 라이브러리를 활용합니다. 아래에서는 Python 패키지 설치부터 MinGW 컴파일러 설정, Pybind11/CMake 구성, OpenCV 설치, CMake 빌드 예시, .pyd 모듈 사용법, 그리고 예제 프로젝트 구조까지 차례로 자세히 다룹니다.

1. Python 패키지 설치 (pip로 설치)

먼저 Python 측 패키지를 설정합니다. pip를 사용하여 필요한 패키지를 설치합니다:

  • Pybind11: C++ 코드를 Python에 바인딩하기 위한 헤더 라이브러리입니다. PyPI를 통해 설치할 수 있으며, 설치하면 Python 환경에 Pybind11 헤더와 CMake 설정 파일 등이 포함됩니다. 명령: pip install pybind11. (Pybind11은 헤더-only 라이브러리로, C++ 컴파일 시에만 사용되고 실행 시간에는 추가 의존성이 없습니다.)

  • OpenCV-Python (선택사항): Python 측에서 OpenCV를 사용하거나 빠른 테스트를 위해 설치할 수 있습니다. pip install opencv-python 또는 GUI 기능이 필요 없으면 pip install opencv-python-headless로 설치합니다. 이 패키지는 OpenCV의 Python 바인딩을 제공하므로, C++에서 직접 OpenCV를 사용할 계획이라면 필수는 아니지만, 설치해 두면 Python으로 영상 파일을 불러오거나 결과를 확인하는 데 도움이 될 수 있습니다.

  • NumPy (선택사항): Pybind11로 C++에서 넘기는 배열 데이터를 Python에서 다루려면 NumPy가 필요합니다. OpenCV-Python을 설치하면 자동으로 NumPy가 설치되지만, 별도로 사용한다면 pip install numpy로 설치합니다.

  • 기타 GUI/멀티미디어: Tkinter는 Python에 내장되어 있으므로 별도 설치가 필요하지 않습니다. 영상 재생이나 GUI 확장을 위해 Pillow 등의 라이브러리가 필요하다면 pip install pillow 등으로 추가합니다.

참고: pip로 패키지를 설치할 때는 반드시 Python 3.10 환경(64비트)에 맞는 pip를 사용해야 합니다. python -m pip ... 형태로 실행하면 현재 사용 중인 Python에 설치됩니다. 설치 후 pip list로 pybind11, opencv-python 등의 버전을 확인합니다.

2. MinGW 컴파일러 설치 방법 및 권장 버전

C++ 코드를 Windows에서 컴파일하기 위해 MinGW-w64 컴파일러를 설치합니다. MinGW는 GCC 컴파일러의 Windows 버전으로, 64비트 Python과 호환되도록 64비트(x86_64) MinGW-w64를 사용해야 합니다. 설치에는 두 가지 방법이 있습니다:

  • MSYS2 기반 설치 (권장): MSYS2는 패키지 관리 시스템(pacman)을 통해 최신 MinGW-w64 툴체인을 쉽게 설치할 수 있는 환경입니다.

    1. MSYS2 공식 사이트에서 설치 프로그램을 내려받아 설치합니다. 설치 후 MSYS2 MinGW 64-bit용 터미널을 실행합니다.

    2. 첫 실행 시 pacman -Syu를 실행해 MSYS2 자체를 업데이트하고, pacman -Su로 최신 패키지를 모두 업데이트합니다.

    3. MinGW-w64 컴파일러와 도구 모음을 설치합니다: pacman -S --needed base-devel mingw-w64-x86_64-toolchain. 이 명령은 gcc, g++, gdb, make, pkg-config 등을 한꺼번에 설치합니다. (중간에 설치 여부를 묻는 패키지가 나오면 모두 설치 확인).

    4. 설치가 끝나면 gcc --version 또는 g++ --version으로 버전을 확인합니다. (예: GCC 12.x or 13.x 등 최신 버전일 것입니다.)

  • 독립 실행형 MinGW-w64 설치: MSYS2를 사용하지 않고 순수 MinGW-w64만 설치할 수도 있습니다.

    1. MinGW-w64 공식 사이트에서 WinLibs 또는 MinGW-w64 온라인 설치 프로그램을 사용할 수 있습니다. 온라인 설치기를 사용할 경우, 아키텍처는 x86_64, 스레드 모델은 posix, 예외 모델은 seh로 선택하여 설치하세요. Posix thread를 선택해야 Windows에서 <mutex> 등 C++11 스레드 관련 기능(OpenCV에서 사용)을 사용할 수 있습니다.

    2. 설치 경로의 mingw64\bin 디렉터리를 PATH 환경변수에 추가합니다. (예: C:\Program Files\mingw-w64\x86_64-<버전>\mingw64\bin). PATH 설정 후 새 명령 프롬프트를 열어 g++ --version이 정상적으로 표시되는지 확인합니다.

    3. CMake 설치: 독립형으로 작업하는 경우 CMake 공식 사이트에서 Windows용 CMake를 설치하고 PATH에 추가하십시오. (MSYS2 환경에서는 pacman -S mingw-w64-x86_64-cmake로 설치 가능).

MinGW-w64 버전 권장: Python 3.10과 호환되도록 64비트 MinGW-w64 최신 버전을 사용하세요. GCC 10 이상이라면 C++17 등 최신 표준을 지원합니다. (예: MinGW-w64 GCC 12.x).
스레드 및 예외 모델: posix 스레드 모델 + seh 예외 모델 조합이 64비트 Windows에 적합합니다. (posix는 표준 스레드 지원, seh는 64비트용 구조적 예외 처리)

3. MinGW에서 Pybind11 사용을 위한 CMake 설정법

이제 C++ 코드를 Python 확장 모듈로 컴파일하기 위한 CMake 설정을 구성합니다. Pybind11은 CMake와의 연동을 돕는 모듈을 제공하며, MinGW에서도 이를 활용할 수 있습니다.

(a) Pybind11 헤더 포함: Pybind11은 헤더-only이므로, 컴파일 시 Pybind11의 include 경로와 Python의 C API 헤더 경로가 필요합니다. 이를 CMake에서 설정하는 방법은 두 가지입니다:

  • Pybind11 패키지 사용(find_package): 앞서 pip install pybind11을 했다면, Pybind11이 Python 패키지로 설치되어 있습니다. 다만 pip로 설치한 Pybind11의 CMake 설정을 바로 찾으려면 pip install "pybind11[global]"로 전역 헤더를 배치하거나, 환경변수를 설정해야 할 수도 있습니다. 쉽게 하는 방법은 MSYS2처럼 Pybind11 CMake 패키지가 있는 환경을 사용하는 것입니다. MSYS2에서는 pacman -S mingw-w64-x86_64-pybind11로 Pybind11을 설치하면 CMake용 config 파일이 등록됩니다. 그런 경우 find_package(pybind11 CONFIG REQUIRED)로 Pybind11을 찾을 수 있습니다.
    Pybind11이 설치된 상태라면 CMakeLists에 아래와 같이 작성합니다:

    cmake_minimum_required(VERSION 3.15)
    project(example LANGUAGES CXX)
    find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
    find_package(pybind11 CONFIG REQUIRED)  # Pybind11 패키지 찾기
    pybind11_add_module(example MODULE src/example.cpp)  # Pybind11 모듈 타겟 생성
    

    위 예에서 pybind11_add_module는 Python 확장 모듈을 빌드하기 위한 헬퍼로, 대상 이름과 소스 파일을 인자로 받아 .pyd (또는 .so) 모듈을 생성합니다. find_package(Python3 ...)는 Python 인터프리터와 개발 헤더/라이브러리를 찾습니다. Python 3.10 64bit가 설치되어 있으면 해당 경로를 자동 탐색하며, 필요시 -DPython3_ROOT_DIR="C:/Python310" 같은 변수를 주어 Python 위치를 지정할 수 있습니다.

  • Pybind11 소스 포함(add_subdirectory): Pybind11 저장소를 직접 내려받아 프로젝트에 포함시킬 수도 있습니다. 예를 들어 프로젝트 폴더 내에 extern/pybind11에 소스(또는 git submodule) 넣은 뒤 add_subdirectory(extern/pybind11)로 추가하면, 위와 동일하게 pybind11_add_module 등을 사용할 수 있습니다. 이 경우 별도의 find_package는 필요 없고, Pybind11이 Python도 같이 찾도록 CMake 설정이 포함되어 있습니다.

(b) MinGW용 컴파일러 설정: CMake를 사용할 때 MinGW로 빌드하려면 몇 가지 유의점이 있습니다.

  • CMake Generators: MSYS2 MinGW 쉘에서 실행한다면 cmake -G "MinGW Makefiles" 또는 Ninja를 사용하는 경우 -G "Ninja"를 지정합니다. Windows의 일반 명령 프롬프트에서 CMake를 쓸 때는, MinGW의 g++.exe를 CMake가 인식하도록 PATH가 설정되어 있어야 하며, 동일하게 "MinGW Makefiles" 제너레이터를 선택합니다. (Visual Studio가 설치되어 있어도, 명시적으로 MinGW를 쓰려면 제너레이터를 지정해야 합니다.)

  • 툴체인 파일(Optional): 필요에 따라 MinGW용 툴체인 파일(.cmake)을 작성해 -DCMAKE_TOOLCHAIN_FILE=mingw_toolchain.cmake로 지정할 수도 있지만, 단순히 로컬에서 MinGW를 사용할 경우 대부분 불필요합니다. MSYS2 환경에서는 기본 gcc를 사용하므로 별도 툴체인 설정 없이도 -G "MinGW Makefiles"만으로 동작합니다.

  • 컴파일러 플래그: Pybind11 모듈을 컴파일할 때 C++ 표준을 C++11 이상으로 설정해야 합니다. 예를 들어 target_compile_features(example PRIVATE cxx_std_17) 또는 set(CMAKE_CXX_STANDARD 17) 등을 CMakeLists에 지정합니다. 또한 MinGW에서는 대형 객체 지원을 위해 -Wa,-mbig-obj 플래그가 필요할 수 있으나, Pybind11의 CMake 모듈이 pybind11::windows_extras를 통해 /bigobj 등의 설정을 자동으로 해줍니다.
    64비트 Windows에서 MinGW로 컴파일할 때는 -DMS_WIN64 매크로가 정의되어야 하는데, 최신 CMake/pybind11 조합에서는 자동으로 정의되는지 확인합니다. (수동으로 필요시 target_compile_definitions(example PRIVATE "MS_WIN64") 추가 가능).
    릴리즈 빌드에는 최적화 플래그 -O3 등이 자동 적용되지만, 모듈 크기를 줄이기 위해 CMake 설정에서 pybind11_strip(example) (MinGW에서는 strip 명령으로 심볼 제거)를 적용할 수도 있습니다.

(c) Python 라이브러리 링크: Pybind11 모듈은 기본적으로 Python 해더와 라이브러리에 링크되어야 합니다. find_package(Python3 ... Development)를 쓰면 Python3::Python (또는 Python3::Module) 인터페이스를 얻을 수 있고, Pybind11 CMake는 이를 내부적으로 처리해 줍니다. 수동으로 한다면 Python 3.10 설치 폴더의 Include 디렉터리를 include 패스에, libs/python310.lib (또는 MinGW용 import lib) 을 링커에 지정해야 합니다. 다행히 Pybind11에서는 pybind11_add_module로 생성 시 자동으로 Python 라이브러리를 링크해주므로 별도 지정이 없더라도 동작해야 합니다.
주의: CPython 공식 빌드는 MSVC용 import library (python310.lib)를 제공합니다. MinGW에서 이 .lib을 사용해 링크할 수 있으며, 실행 시에는 Python DLL(python310.dll)을 로드합니다. 일반적으로 호환되지만, 만약 .lib 인식을 못 하면 pexports/dlltool 등을 통해 MinGW용 import library (libpython310.a)를 생성할 수도 있습니다. 대부분의 경우 find_package(Python3 Development)가 알아서 처리합니다.

요약하면, CMakeLists.txt에서 Pybind11 모듈을 설정할 때는 다음과 같이 작성할 수 있습니다 (OpenCV 연동 전까지 기본 형태):

cmake_minimum_required(VERSION 3.15)
project(MyVideoMixer LANGUAGES CXX)

find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
find_package(pybind11 REQUIRED)  # CONFIG 옵션은 pybind11 설치 방식에 따라 추가

pybind11_add_module(videomixer MODULE src/main.cpp src/other.cpp)
target_compile_features(videomixer PRIVATE cxx_std_17)
# (Pybind11 모듈은 자동으로 Python과 링크; 필요시 추가 라이브러리는 뒤에서 설정)

이제 OpenCV 라이브러리를 설치하고 CMake에 연결하는 방법을 알아보겠습니다.

4. OpenCV C++ 라이브러리 설치 (MinGW 호환)

OpenCV를 C++에서 사용하기 위해 라이브러리를 설치합니다. 중요한 점은 Windows용 OpenCV 공식 배포본은 MSVC용으로 컴파일되어 있어 MinGW와 바로 호환되지 않는다는 것입니다. 따라서 다음과 같은 방법 중 하나를 사용해야 합니다:

  • MSYS2 패키지 이용 (간편): MSYS2는 MinGW-w64용으로 빌드된 OpenCV 패키지를 제공합니다. MSYS2 MinGW 64-bit 쉘에서 아래 명령으로 설치 가능합니다:

    pacman -S mingw-w64-x86_64-opencv
    

    이 패키지는 OpenCV 최신 버전(예: 4.x)을 MinGW용으로 컴파일한 바이너리(.dll)들과 C++ 헤더, CMake 설정 파일들을 포함합니다. 위 명령으로 설치하면 OpenCV 라이브러리가 MSYS2의 mingw64\ 경로 아래 설치됩니다. (예: 헤더는 mingw64\include\opencv4, 라이브러리 dll은 mingw64\bin, import library는 mingw64\lib에 위치합니다.)
    장점: 직접 빌드할 필요 없이 바로 사용 가능하고, find_package(OpenCV)로 손쉽게 찾을 수 있습니다.
    주의: MSYS2 환경 밖에서 이 라이브러리를 사용할 경우, OpenCV DLL 파일들이 필요하므로 추후 .pyd를 배포하거나 실행할 때 해당 DLL들을 경로에 둬야 합니다.

  • OpenCV 소스 직접 빌드: OpenCV를 MinGW로 직접 빌드할 수도 있습니다. 이 방법은 시간이 오래 걸리지만, 자신이 필요한 모듈만 포함하거나 정적 라이브러리로 빌드하는 등 커스터마이즈가 가능합니다.

    1. OpenCV 공식 GitHub에서 소스 코드를 다운로드 합니다. (필요에 따라 opencv_contrib도 다운로드)

    2. CMake GUI나 터미널에서 빌드 설정을 합니다. 소스 디렉터리와 별도의 빌드 출력 디렉터리를 정하고, CMake에서 **Generator를 "MinGW Makefiles"**로 선택합니다. CMake 옵션에서 BUILD_SHARED_LIBS를 ON (공유 DLL 빌드) 또는 OFF (정적 라이브러리 빌드) 원하는 대로 설정합니다. 기본값은 ON이어서 DLL(.dll) + import lib(.a)를 생성합니다.

    3. mingw32-make -j4 (또는 make -j4)로 빌드를 진행하고, mingw32-make install로 설치합니다. 설치 결과 install 폴더에 include, lib, bin 등이 생성됩니다.

      • 공유 DLL 빌드: install\x64\mingw\bin에 다수의 opencv_*.dll이 생성되고, install\x64\mingw\lib에 대응되는 libopencv_*.a import 라이브러리들이 생깁니다. Python 모듈에서 OpenCV를 사용할 때는 이 DLL들이 필요합니다.

      • 정적 라이브러리 빌드: BUILD_SHARED_LIBS=OFF로 설정하면 libopencv_core.a 등 정적 링크 라이브러리가 생성됩니다. 이 경우 OpenCV를 .pyd에 완전히 포함시킬 수 있으나, OpenCV가 의존하는 여러 라이브러리도 함께 정적으로 링크해야 합니다. 또한 OpenCV 라이선스나 용량 문제도 고려해야 합니다.

    4. 빌드/설치가 완료되면, CMake의 OpenCVConfig.cmake 파일 경로를 기억합니다 (예: <install_dir>\x64\mingw\lib\cmake\opencv4\OpenCVConfig.cmake). 이후 CMake에서 find_package(OpenCV CONFIG REQUIRED)를 쓸 때 -DOpenCV_DIR="<경로>"를 지정하여 해당 파일이 있는 디렉토리를 가리키면 OpenCV를 찾을 수 있습니다.

  • 타인이 빌드한 MinGW용 OpenCV 사용: 직접 빌드가 어려운 경우, 커뮤니티에서 제공하는 MinGW용 빌드본을 활용할 수도 있습니다. 예를 들어 GitHub의 huihut/OpenCV-MinGW-Build 저장소에서는 여러 버전의 OpenCV를 MinGW로 빌드한 바이너리를 제공합니다. 이러한 바이너리를 사용할 경우, 제공된 압축파일을 풀고 include/lib/bin 경로를 CMake나 환경변수로 맞게 설정해주면 됩니다. (주의: 공식 배포가 아니므로 버전 호환성이나 신뢰성을 검토하세요.)

MinGW에서의 OpenCV 링크 방식:
기본적으로 OpenCV를 동적 링크(공유 DLL)로 사용하는 것이 일반적입니다. 즉, 컴파일 시에는 import library(.a 또는 .lib)를 링크하고, 실행 시 .dll 파일이 필요합니다. 정적 링크의 경우 OpenCV를 빌드할 때 BUILD_SHARED_LIBS=OFF 설정이 필요하며, 정적 링크 시에도 libgcc나 libstdc++ 등의 런타임 라이브러리를 정적으로 묶을지(-static-libgcc, -static-libstdc++) 결정해야 합니다. 하지만 MinGW에서 OpenCV를 정적으로 묶는 것은 복잡하며, OpenCV가 FFmpeg 등 여러 DLL을 또 의존하므로 완전한 정적 링크는 어려울 수 있습니다. 따라서 권장 방법은 DLL을 사용하는 것이며, Python 프로그램 배포 시 해당 DLL들을 .pyd와 함께 제공하거나 PATH에 포함시켜야 합니다.

MSYS2로 설치한 경우 OpenCV DLL은 mingw64\bin\에 있고, CMake에서 OpenCV를 찾으면 OpenCV_DIR 경로와 함께 알아서 라이브러리 목록 (OpenCV_LIBS)을 제공합니다. 다음 섹션에서는 Pybind11 모듈에 OpenCV를 링크하는 CMake 설정 예시를 보여드립니다.

5. Pybind11 + OpenCV + MinGW를 위한 CMake 설정 예시

이 섹션에서는 앞서 설치한 Pybind11과 OpenCV를 이용하여 .pyd 확장 모듈을 컴파일하는 CMakeLists.txt 예시와 빌드 방법을 제시합니다.

먼저, 프로젝트 디렉토리 구조를 예시로 가정하겠습니다:

MyProject/
├── CMakeLists.txt
├── src/
│   ├── main.cpp        # PYBIND11_MODULE 정의 및 모듈 초기화 코드
│   └── videomixer.cpp  # (예시) 비디오 믹싱 관련 C++ 구현
└── python/
    └── app.py          # Tkinter GUI 및 Python 코드, videomixer 모듈 사용

CMakeLists.txt 내용 예시:

cmake_minimum_required(VERSION 3.15)
project(MyVideoMixer LANGUAGES CXX)

# 1. Find Python and Pybind11
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
find_package(pybind11 CONFIG REQUIRED)

# 2. Find OpenCV (OpenCVConfig.cmake should be in PATH or specified by OpenCV_DIR)
find_package(OpenCV REQUIRED)

# 3. Create pybind11 module target
pybind11_add_module(videomixer MODULE src/main.cpp src/videomixer.cpp)
target_compile_features(videomixer PRIVATE cxx_std_17)  # use C++17

# 4. Link OpenCV libraries to the module
target_link_libraries(videomixer PRIVATE ${OpenCV_LIBS})

# (Optional) Include OpenCV headers explicitly (usually included by OpenCVConfig)
target_include_directories(videomixer PRIVATE ${OpenCV_INCLUDE_DIRS})

# 5. (Optional) Additional compiler/linker flags for MinGW
if(MINGW)
    target_compile_definitions(videomixer PRIVATE "MS_WIN64")
    # MinGW용 최적화 또는 필요에 따라 플래그 추가 가능
endif()

위 CMake 설정에서 주요 사항을 설명하면:

  • find_package(OpenCV REQUIRED)는 OpenCVConfig를 찾아 OpenCV 라이브러리와 헤더 경로를 설정합니다. MSYS2 환경에서는 별도 OpenCV_DIR 지정 없이도 패키지 설치 시 경로가 설정되어 찾아집니다. 직접 빌드했거나 별도 경로에 있다면 -DOpenCV_DIR="설치경로\lib\cmake\opencv4"를 CMake 실행시에 넘겨줘야 합니다. 찾기가 성공하면 OpenCV_LIBSOpenCV_INCLUDE_DIRS 변수가 설정됩니다.

  • pybind11_add_module(videomixer MODULE ...)videomixer라는 이름의 Python 모듈 (Windows에서는 videomixer.pyd)을 생성합니다. MODULE 키워드는 해당 타겟이 라이브러리(.dll/.pyd)임을 나타냅니다. Pybind11이 내부적으로 pybind11::module 인터페이스 링크 등을 적용하여 PythonEmbed 등의 설정을 해줍니다.

  • target_link_libraries(videomixer PRIVATE ${OpenCV_LIBS})로 OpenCV의 각 라이브러리를 링크합니다. (${OpenCV_LIBS}에는 opencv_core, opencv_imgproc 등 여러 라이브러리 명이 들어있습니다.)

  • MinGW에서는 추가로 MS_WIN64 정의를 넣은 것은 앞서 언급한 대로 64비트 타겟 정의입니다. 그리고 필요하다면 -static-libgcc 등의 플래그를 target_link_options나 컴파일러 플래그에 넣을 수 있지만, 큰 문제없다면 기본 설정으로도 충분합니다.

  • (참고) 만약 OpenCV를 정적 링크로 빌드했다면, target_link_libraries${OpenCV_LIBS} 외에 OpenCV가 필요로 하는 pthread, zlib, libjpeg 등의 라이브러리도 추가로 링크해야 할 수 있습니다. 동적 링크일 경우 import lib를 링크하면 DLL 의존은 자동 처리되므로 신경쓰지 않아도 됩니다.

빌드 및 컴파일:
CMake 설정을 마친 후, 실제 빌드하는 절차는 다음과 같습니다.

  1. CMake Configure 단계:
    MSYS2 MinGW 64-bit 터미널에서 프로젝트 디렉토리로 이동하여, 빌드 디렉토리를 만들고 CMake를 실행합니다:

    mkdir build && cd build
    cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ..
    

    위 명령은 상위(..)의 CMakeLists.txt를 읽어 MinGW Makefiles를 생성합니다. (-DCMAKE_BUILD_TYPE=Release는 최적화 빌드를 지정.)
    만약 MSYS2가 아닌 일반 명령 프롬프트에서 했다면, cmake -G "MinGW Makefiles" -DOpenCV_DIR="C:/opencv/install/..." -DPython3_ROOT_DIR="C:/Python310" .. 등으로 필요 경로를 명시해줄 수도 있습니다.

  2. 컴파일 단계:
    Makefile 생성이 성공했다면, mingw32-make (또는 MSYS2의 경우 make 심볼릭 링크 사용 가능)로 컴파일합니다:

    mingw32-make -j4
    

    -j4는 4개의 병렬 작업으로 빌드하는 옵션입니다. 성공적으로 완료되면 build/src/ 또는 build/ 경로에 videomixer 모듈이 생성됩니다. 파일 이름은 Windows의 경우 videomixer.cp310-win_amd64.pyd 와 같이 Python 버전과 플랫폼이 포함될 수 있습니다 (Pybind11/CMake가 소나미(soabi) 규칙을 적용한 경우). 그렇지 않으면 videomixer.pyd로 나오기도 합니다.
    컴파일 중 에러가 발생한다면, 오류 메시지를 보고 부족한 의존성 (예: OpenCV 헤더를 못 찾는다면 OpenCV_DIR 설정 확인) 등을 해결해야 합니다.

  3. 생성된 모듈 확인:
    .pyd 파일이 생성되면, 해당 파일 크기나 의존 DLL을 확인합니다. videomixer.pyd (혹은 cp310...pyd) 파일이 수 메가바이트 이상이고, OpenCV를 동적 링크했다면 depends 등 도구로 어떤 DLL을 필요로 하는지 볼 수 있습니다 (예: opencv_core411.dll 등).

다음으로, 이렇게 생성된 .pyd 모듈을 Python에서 사용하는 방법을 설명합니다.

6. 컴파일된 .pyd 모듈의 Python 사용법

이 단계에서는 C++로 빌드된 Pybind11 모듈(.pyd 파일)을 Python에서 임포트하고 사용하는 방법을 다룹니다:

  • 모듈 파일의 위치: Python에서는 .pyd 파일을 파이썬 모듈로 취급합니다. 예를 들어 우리가 만든 모듈 이름이 videomixer라면, videomixer.pyd (또는 videomixer.cp310-win_amd64.pyd) 파일을 Python 스크립트에서 import videomixer로 로드할 수 있습니다. 이를 위해 해당 .pyd 파일이 import하는 스크립트와 같은 디렉터리에 있거나, PYTHONPATH에 포함된 경로에 위치해야 합니다. 가장 간단하게는 Python 실행 스크립트 (app.py)와 같은 폴더에 .pyd 파일을 복사해 두는 것입니다. 그러면 import videomixer가 해당 파일을 찾아 모듈을 로드합니다. (현재 작업 디렉터리가 모듈 파일을 포함하면 Python이 모듈을 찾습니다.)

  • DLL 의존성: OpenCV 등의 동적 라이브러리에 의존하는 경우, 해당 DLL 파일들이 시스템 PATH에 있거나 .pyd와 같은 디렉터리에 있어야 합니다. MSYS2로 설치한 경우 mingw64\bin에 OpenCV DLL들이 있는데, 이를 모듈과 동일한 폴더로 복사하거나, os.add_dll_directory를 통해 경로를 추가하거나, PATH 환경변수에 해당 경로를 넣어야 합니다. 예를 들어 opencv_world411.dll과 같은 파일을 요구한다면, 프로그램 시작 시 os.add_dll_directory(r"C:\msys64\mingw64\bin")처럼 추가해줄 수 있습니다 (Python 3.8+ 기능).

  • 모듈 임포트와 함수 호출: .pyd 파일을 준비한 후 Python 코드에서 사용해봅니다. 예를 들어:

    import videomixer
    print(dir(videomixer))         # 모듈 내 함수를 나열
    result = videomixer.mix(video1, video2)  # C++에서 구현한 함수 호출 (예시)
    

    Pybind11로 바인딩한 함수나 클래스는 일반 Python 모듈의 함수처럼 사용할 수 있습니다. 이전 C++ 코드에서 PYBIND11_MODULE(videomixer, m) { m.def("add", &add); }와 같은 함수를 정의했다면, Python에서 videomixer.add(x, y)로 호출할 수 있습니다.

  • 모듈이 로드되지 않는 경우 문제 해결:

    • ModuleNotFoundError: import시 모듈을 찾을 수 없다는 오류이면, .pyd 파일의 경로 문제입니다. PYTHONPATH를 조정하거나 sys.path.append로 경로를 추가하세요.

    • ImportError (DLL load failed): .pyd 자체는 찾았지만 의존 DLL을 찾지 못한 상황입니다. 이 경우 앞서 언급한 DLL 경로 문제이므로, OpenCV DLL 등 의존성을 확인하고 경로를 설정해야 합니다.

    • AttributeError: 모듈은 임포트됐는데 함수가 없다고 하면, C++ 쪽 Pybind11 바인딩에서 이름이 잘못되었거나 파일 이름-모듈명 불일치일 수 있습니다. 예를 들어 PYBIND11_MODULE 매크로의 모듈명과 .pyd 파일명이 다르면 문제가 생깁니다. (Pybind11/CMake 조합은 자동으로 맞춰주지만, 수동 빌드 시 example.cpp -> example.pyd -> import example 식으로 이름을 맞춰야 합니다.)

파이썬 인터프리터에서 동적으로 이 모듈을 불러와 잘 동작하는지 반드시 테스트해봅니다. >>> import videomixer; videomixer.some_function()처럼 호출해서 예상대로 동작하면 환경 구축과 빌드가 성공한 것입니다.

7. 예제 템플릿 구조 및 개발 순서

마지막으로, 전체 프로젝트의 템플릿 구조와 개발 흐름을 정리합니다. 이는 Windows에서 처음 개발을 시작하는 사용자가 참고할 수 있도록 한 것입니다:

  • 프로젝트 디렉토리 구조: 앞서 예시한 구조처럼, C++ 소스코드와 Python 코드를 분리하여 구성합니다. 예를 들어:

    MyProject/
    ├── src/                     # C++ 소스 디렉토리
    │   ├── main.cpp             # Pybind11 모듈 초기화 코드 (PYBIND11_MODULE 정의)
    │   └── mixer.cpp            # 실제 비디오 믹싱 로직 구현 (OpenCV 사용)
    ├── include/                 # (선택) 헤더 파일 디렉토리
    │   └── mixer.hpp            # mixer.cpp에 대응되는 헤더 (함수/클래스 선언)
    ├── python/                  # Python 코드 디렉토리
    │   ├── app.py               # Tkinter GUI 코드, videomixer 모듈 임포트 및 사용
    │   └── ...                 
    ├── CMakeLists.txt           # CMake 빌드 스크립트 (위에서 설명한 내용)
    └── README.md                # (선택) 프로젝트 설명 파일
    

    이렇게 해두면, C++ 코드는 모듈 빌드를 통해 .pyd를 생성하고, Python 폴더의 코드에서 그 모듈을 불러쓰는 형태로 개발을 진행할 수 있습니다.

  • 개발 및 빌드 순서:

    1. C++ 구현: OpenCV C++ 코드를 mixer.cpp/hpp 등에 작성하고 Pybind11로 함수를 노출 (main.cpp의 PYBIND11_MODULE 내에서 m.def(...) 또는 py::class_<> 등 사용)합니다.

    2. CMake 빌드: MSYS2 MinGW64 터미널에서 cmakemake로 빌드하여 .pyd 파일을 생성합니다.

    3. Python 테스트: python/app.py 또는 대화형 Python에서 모듈을 임포트하여 함수들이 잘 호출되는지, OpenCV 연산이 기대대로 동작하는지 테스트합니다.

    4. Tkinter GUI 연동: Tkinter를 통해 파일 선택, 영상 표시 등을 구현하고, Pybind11 모듈의 함수를 호출하여 영상 데이터를 처리합니다. 예를 들어, OpenCV로 로드한 영상(frames)을 NumPy 배열로 변환 후 Tkinter PhotoImage로 보여주거나, C++에서 처리한 결과 영상을 임시 파일로 저장 후 Tkinter로 표시하는 방법 등이 있습니다.

    5. 디버깅: 문제가 발생하면 C++ 쪽에서는 gdb로 .pyd를 로드한 Python 프로세스를 디버깅하거나, Python쪽에서는 print/logging으로 상태를 확인하며 수정합니다.

    6. 배포: 앱을 배포할 때는 Python 스크립트와 .pyd 모듈, 그리고 필요한 OpenCV DLL들을 함께 포함시켜야 합니다. OpenCV를 static 링크했다면 DLL은 줄일 수 있지만, 그렇지 않다면 opencv_world###.dll 등 파일을 포함해야 합니다.

이상으로 Windows 10+에서 Python Tkinter + C++(Pybind11) + OpenCV + MinGW 조합으로 개발환경을 구축하는 방법을 상세히 설명하였습니다. 이 가이드를 따라 하시면, 필요한 패키지 설치, 컴파일러 설정, CMake 구성, OpenCV 세팅, 모듈 빌드 및 사용까지 순차적으로 진행할 수 있을 것입니다. 초기 세팅이 다소 복잡하지만, 한 번 환경을 구축해 두면 C++의 성능과 Python의 생산성을 결합하여 효율적인 비디오 처리 앱을 개발할 수 있습니다.

참고 자료: Windows에서 Pybind11 모듈 빌드 예제, MSYS2를 통한 OpenCV 설치 방법, MinGW 컴파일러 설정 관련 권장사항, Pybind11 공식 문서 및 OpenCV 포럼 조언 등. 필요한 경우 각 출처를 확인하여 세부사항을 참조하시기 바랍니다.

댓글

이 블로그의 인기 게시물

(VBA) 009 - 닫힌 파일에서 데이터 읽어오기 (ExecuteExcel4Macro)

#毎日育ちゃん可愛い大会 예시의 매크로 파일을 테스트 할 때는 저장된 폴더를 사용하실 폴더로 꼭 바꿔주세요! (pptx파일) pptx파일 (xlsx파일) 예제데이터파일   Macro파일 ★ 진행목적 : 왜 이걸 사용합니까 . 1) 행이나 열 , 또는 Sheet 과 같이 다른 특성을 가지는 1,2,3 차 데이터배열에 대한 처리 방법을 지금까지 설명드렸습니다 . 2) 그럼 이제 , 다른 파일에서 데이터를 읽어올 방법을 알아볼 필요가 있습니다 . 어째선가 회사의 데이터를 처리하다보면 , 주기적인 이름의 엑셀 파일 특정 Sheet, Cell 에 있는 경우가 많았습니다 . 3) 엑셀에서 이미 열려있는 파일의 참조는 ‘=‘ 을 사용하면 가능하지만 , 닫힌 파일은 데이터를 읽지 못합니다 . 4) 그래서 이를 처리하기 위해 VBA 의 ‘ExecuteExcel4Macro( 주소 )’ 를 사용합니다 ! ★ 다른 파일의 참조는 어떻게 합니까 ? 1) 열려 있는 다른 파일의 데이터를 읽는 방식은 ‘=‘ 을 입력하고 해당 Cell 을 클릭하면 됩니다 ! 2) 그러면 아래와 같이 (=‘ 파일이 있는 폴더 [ 파일명 ]Sheet 명 ’!Cell 주소 ) 의 형태로 기록 이 됩니다 . ★ 닫힌 파일에 대해서는 INDIRECT 는 사용이 되질 않습니다 ! 1) INDIRECT 로는 처리가 되질 않습니다 . 2) 어째선가 전에 사용하던 INDIRECT 를 사용하고 싶지만 , 사용이 되질 않습니다 . 검색을 해봐도 안된다는 답변만 있네요 ! 3) 파일이 하나 두 개라면 , 이전과 같이 ‘=‘ 를 쓰면 되겠지만 , 그러면 자동화를 통한 효율화가 불가능해지겠죠 ! 4) 그래서 이를 처리하기 위해 VBA 의 ‘ExecuteExcel4Macro( 주소 )’ 를 사용합니다 ! ★ ExecuteExcel4Macro 는 어떻게 사용합니까 ? 1) VBA 의 ExecuteExcel4Macro 란 매크로...

(VBA) 004 - Object 이름으로 이미지 복사 붙여넣기

(VBA) 004- Object 이름으로 이미지 복사 붙여넣기 진행목적  :  왜 이걸 사용합니까 . → Object  이름을 사용해서 주기적 복사가 가능한 경우가 있습니다 .     ( 예  :  사진의 이름이  ‘ 사진  1’ ‘ 사진  2’…  로 되어있거나 , ‘Picture 1’, ‘Picture 2’…  로 됨 ) (설명자료는 여기) 설명자료 ( 예제파일은 여기 ) 예제파일 (VBA 진행에 대해) 이제 VBA 세션 자료를 필요할 때 보려고 이 블로그에 남기려고 해요. 앞선 001-003도 옮겨야겠습니다. 올해 내에 100가지 주제를 가지고 포스팅 할 수 있도록 할게요. ( 中谷 育 さんのイメージで に対して) 本当に可愛い中谷 育さんのイメージが 含まれています。 ありがとうございます。 何か問題があったら、教えてください。 直ちに処理します。

(Node.js) XLSX 모듈 사용 / 행렬 파싱 및 조건에 맞는 데이터만 추출

요번에는 Node.js로 아래와 같이 KRX에서 코스피/코스닥 상장사 정보를 취득한 후 네이버에서 원하는 조건에 맞는 정보만 크롤링하는 모듈을 만들어보려고 합니다! 그러면 주식하는 친구들은 조건식을 걸어놓기만 해도 손 안대고 틈틈히 자동으로 수집된 정보를 확인할 수 있게 되겠네요!  (이후에는 자동 메일링까지 추가할 건데 우선은 크롤링해서 유의미한 XLSX로 Export하는 것 까지를 먼저 만들려고 합니다!) 네이버 주식에서 페이지를 확인해보니 종목코드를 기준으로 페이지 주소가 매칭이 되고, 그 유니크한 종목 코드에 유니크한 Selector를 확인하면 데이터 크롤링이 되겠네요! ----- 저는 KRX 사이트에서 업체리스트를 xls로 받아온 뒤에 추출된 결과를 중간에 result.xls로 먼저 저장해놨다가 크롤링할 때 다시 리딩해서 쓰는 방식을 구현해보려고 합니다. VBA / C++ 데이터 처리 방식이 익숙하기도 하고 나중에 불필요하면 떼버리면 되니까요? XLSX Import하는 모듈은 앞서 설명을 드렸었고요, 데이터를 Readfile한 뒤에 조건에 맞는거만 옮겨담는 작업이 필요한데요, 이를 위해 stackoverflow에서 parsing하는 알고리즘을 참고해서 아래와 같이 변형합니다! https://stackoverflow.com/questions/30859901/parse-xlsx-with-node-and-create-json 원본은 data[row][headers[col]] = value인데, XLSX에서 가상의 sheet에 데이터를 넣어주려면 array of arrays 방식이 되어야 하기 때문에, 아래와 같이 우선 빈 배열을 선언하고, row / column을 동적할당(new array()) 후 push 하는 방식으로 처리해줘야 합니다. 제가 아는 방법 중엔 이게 제대로 동작을 하기 때문에 이렇게 바꿔서 사용했습니다. 조건식은 나중에 입력받겠지만,...