Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

You can use shared memory (Interprocess communication) to do this. It should be fast enough for 60 fps communication.

See this minimal-working-example that uses OpenCV and Windows. You might need to make changes for a different shared memory implementation, but the memory copy operations should remain the same.

You can use shared memory (Interprocess communication) to do this. It should be fast enough for 60 fps communication.

See this minimal-working-example that uses OpenCV and Windows. You might need to make changes for a different shared memory implementation, but the memory copy operations should remain the same.


edited by @sturkmen to take the attention

@iamsurya thanks for the code you provided.

(maybe useful i attached my test code below)

call the program with video file path param to start server.
call the program without param to start reciever

( you need to change )

    int HEIGHT = 720;
    int WIDTH = 1280;

according to your video

#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

#define MAX_LOADSTRING 100


void server(String video_path)
{
    cv::Mat currentFrame, resized;
    cv::VideoCapture video;
    int key;
    video.open(video_path);
    namedWindow("Sender");
    int HEIGHT = 720;
    int WIDTH = 1280;
    int CHANNELS = 3;

    /* Create Shared Memory */
    int shmem_size = CHANNELS * WIDTH * HEIGHT; /* Size of image buffer is Channels * Width * Height bytes */
    HANDLE shmem = INVALID_HANDLE_VALUE;
    HANDLE mutex = INVALID_HANDLE_VALUE;
    mutex = ::CreateMutex(NULL, FALSE, "camera_mutex");

    shmem = ::CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        shmem_size,
        "opencv_camera_buffer"
    );
    unsigned char *buf = (unsigned char*)::MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size);

    /* Run 700 frames */
    for (unsigned int c = 0; c < 700; c++) {

        /* Load frame */
        video.read(currentFrame);
        imshow("Sender", currentFrame);

        /* Copy to Shared memory */
        WaitForSingleObject(mutex, INFINITE);
        memcpy(buf, currentFrame.ptr(), shmem_size);

        ::ReleaseMutex(mutex);

        key = waitKey(1000 / 25);
        if (key > 31 && key < 127)
            break;

    }

    ::UnmapViewOfFile(buf);
    ::CloseHandle(shmem);
    ::ReleaseMutex(mutex);

    exit(0);
}

void receiver()
{
    cv::Mat resized;
    namedWindow("Receiver");
    int HEIGHT = 720;
    int WIDTH = 1280;
    int CHANNELS = 3;
    int key;
    int shmem_size = CHANNELS * HEIGHT * WIDTH; /* Size of image buffer is Channels * Width * Height */
    HANDLE shmem = INVALID_HANDLE_VALUE;
    HANDLE mutex = INVALID_HANDLE_VALUE;
    mutex = ::CreateMutex(NULL, FALSE, "camera_mutex");
    shmem = ::CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        shmem_size,
        "opencv_camera_buffer"
    );
    unsigned char *buf = (unsigned char*)::MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size);

    for (unsigned int c = 0; c < 700; c++) {

        WaitForSingleObject(mutex, INFINITE);
        resized = cv::Mat(Size(WIDTH, HEIGHT), 16, buf, CHANNELS * WIDTH);
        imshow("Receiver", resized);
        ::ReleaseMutex(mutex);
        key = waitKey(1000 / 25);
        if (key > 31 && key < 127)
            break;
    }
    ::UnmapViewOfFile(buf);
    ::CloseHandle(shmem);
    ::ReleaseMutex(mutex);

    exit(0);
}

int main(int argc, char* argv[])
{
    if( argc < 2 )
        receiver();
    else
        server(argv[1]);
}

You can use shared memory (Interprocess communication) to do this. It should be fast enough for 60 fps communication.

See this minimal-working-example that uses OpenCV and Windows. You might need to make changes for a different shared memory implementation, but the memory copy operations should remain the same.


edited by @sturkmen to take the attentionThe code is provided under MIT license please cite appropriately.

@iamsurya thanks for the code you provided.edit: Removed attempt to hijack answer and share copyright code.

(maybe useful i attached my test code below)

call the program with video file path param to start server.
call the program without param to start reciever

( you need to change )

    int HEIGHT = 720;
    int WIDTH = 1280;

according to your video

#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;

#define MAX_LOADSTRING 100


void server(String video_path)
{
    cv::Mat currentFrame, resized;
    cv::VideoCapture video;
    int key;
    video.open(video_path);
    namedWindow("Sender");
    int HEIGHT = 720;
    int WIDTH = 1280;
    int CHANNELS = 3;

    /* Create Shared Memory */
    int shmem_size = CHANNELS * WIDTH * HEIGHT; /* Size of image buffer is Channels * Width * Height bytes */
    HANDLE shmem = INVALID_HANDLE_VALUE;
    HANDLE mutex = INVALID_HANDLE_VALUE;
    mutex = ::CreateMutex(NULL, FALSE, "camera_mutex");

    shmem = ::CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        shmem_size,
        "opencv_camera_buffer"
    );
    unsigned char *buf = (unsigned char*)::MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size);

    /* Run 700 frames */
    for (unsigned int c = 0; c < 700; c++) {

        /* Load frame */
        video.read(currentFrame);
        imshow("Sender", currentFrame);

        /* Copy to Shared memory */
        WaitForSingleObject(mutex, INFINITE);
        memcpy(buf, currentFrame.ptr(), shmem_size);

        ::ReleaseMutex(mutex);

        key = waitKey(1000 / 25);
        if (key > 31 && key < 127)
            break;

    }

    ::UnmapViewOfFile(buf);
    ::CloseHandle(shmem);
    ::ReleaseMutex(mutex);

    exit(0);
}

void receiver()
{
    cv::Mat resized;
    namedWindow("Receiver");
    int HEIGHT = 720;
    int WIDTH = 1280;
    int CHANNELS = 3;
    int key;
    int shmem_size = CHANNELS * HEIGHT * WIDTH; /* Size of image buffer is Channels * Width * Height */
    HANDLE shmem = INVALID_HANDLE_VALUE;
    HANDLE mutex = INVALID_HANDLE_VALUE;
    mutex = ::CreateMutex(NULL, FALSE, "camera_mutex");
    shmem = ::CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        shmem_size,
        "opencv_camera_buffer"
    );
    unsigned char *buf = (unsigned char*)::MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size);

    for (unsigned int c = 0; c < 700; c++) {

        WaitForSingleObject(mutex, INFINITE);
        resized = cv::Mat(Size(WIDTH, HEIGHT), 16, buf, CHANNELS * WIDTH);
        imshow("Receiver", resized);
        ::ReleaseMutex(mutex);
        key = waitKey(1000 / 25);
        if (key > 31 && key < 127)
            break;
    }
    ::UnmapViewOfFile(buf);
    ::CloseHandle(shmem);
    ::ReleaseMutex(mutex);

    exit(0);
}

int main(int argc, char* argv[])
{
    if( argc < 2 )
        receiver();
    else
        server(argv[1]);
}

You can use shared memory (Interprocess communication) to do this. It should be fast enough for 60 fps communication.

See this minimal-working-example that uses OpenCV and Windows. Windows shared under MIT license. You might need to make changes for a different shared memory implementation, but the memory copy operations should remain the same.

The code is provided under MIT license please cite appropriately.

edit: Removed attempt to hijack answer and share copyright code.