반응형

C와 Python 프로그램간 이미지 데이터를 공유해 보자.

 

1) 파이썬 프로그램 데이터를 C 프로그램에 공유

mmap

 

import time
import mmap
import cv2

frame = cv2.imread("image.jpg", cv2.IMREAD_COLOR)
h, w, c = frame.shape
buffer_size = h * w * c

mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")

try:
    mm.write(frame.tobytes())

    while True:
        time.sleep(1000)  # Sleep to prevent busy waiting.
finally:
    mm.close()

 

#include <opencv2/opencv.hpp>
#include <Windows.h>

int main() {
    int height = 495;
    int width = 396;
    int channels = 3;
    int buffersize = height * width * channels;

    byte* buffer = new byte[buffersize];
    memset(buffer, 0, buffersize);

    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;

    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 0, 0, buffersize);
    if (PtrInFile == NULL)
        return -1;

    memcpy(buffer, PtrInFile, buffersize);
    // memcpy로 메모리 내용을 buffer로 복사할 필요없이 아래 Mat 생성자에서 PtrInFile을 인수로 줘도 된다.

    cv::Mat image = cv::Mat(height, width, CV_8UC3, buffer);
    if (image.empty())
        return -1;

    // 사용할 Mat이 이미 존재한다면 아래처럼 memcpy()를 사용할 수도 있다.
    //cv::Mat image(height, width, CV_8UC3); // 이미 존재하는 Mat
    //memcpy(image.data, buffer, buffersize); // buffer 사용하지 않고 메모리에서 image.data로 직접 복사해도 된다.

    cv::imshow("image", image);
    cv::waitKey(0);
        
    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    delete[] buffer;

    return 0;
}

 

 

파이썬 프로그램을 먼저 실행하고 C 프로그램을 실행한다.

 

 

2) C 프로그램 데이터를 파이썬 프로그램에 공유

 

#include <opencv2/opencv.hpp>
#include <Windows.h>

int main() {
    cv::Mat image = cv::imread("image.jpg");
    if (image.empty())
        return -1;

    int height = image.rows;
    int width = image.cols;
    int channels = image.channels();
    int buffersize = height * width * channels;

    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;

    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 0, 0, buffersize);
    if (PtrInFile == NULL)
        return -1;

    memcpy(PtrInFile, image.data, buffersize);
    // 버퍼를 사용하지 않고 바로 메모리에 데이터 복사.
        
    int a;
    std::cin >> a;
    // 대기

    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    
    return 0;
}

 

import mmap
import numpy as np
import cv2

height = 495
width = 396
channels = 3
buffer_size = height * width * channels

mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")

try:    
    buffer = mm.read(buffer_size)
    image_arr = np.frombuffer(buffer, np.ubyte)
    image = image_arr.reshape(height, width, channels)
    
    cv2.imshow("image", image)
    cv2.waitKey(0)
finally:
    mm.close()
    cv2.destroyAllWindows()

 

결과는 같다.

 

※ 참고

2025.02.16 - [OpenCV] - C# and Python OpenCV Image Data Share (Memory Mapped File)

2026.02.18 - [OpenCV] - [OpenCV] C# 에서 C++ DLL 사용하기

2026.02.19 - [OpenCV] - [OpenCV] Python 에서 C++ DLL 사용하기

 

반응형
Posted by J-sean
: