C++ 两个单独的进程共享同一个摄影机提要OpenCv
我有两个独立的过程,同时使用视频捕获来获取网络摄像头的图像流。是否有一种方法可以对多个进程使用相同的视频捕获(以有效节省资源) 我曾考虑使用mmap将当前图像从一个进程传输到另一个进程,但我认为有更好的方法。有人知道如何在Opencv中与两个进程共享同一个视频提要吗 此外,共享相同的视频捕获在计算上是否值得?或者有两个进程不断地获取网络摄像头图像在资源方面会更好C++ 两个单独的进程共享同一个摄影机提要OpenCv,c++,python,opencv,C++,Python,Opencv,我有两个独立的过程,同时使用视频捕获来获取网络摄像头的图像流。是否有一种方法可以对多个进程使用相同的视频捕获(以有效节省资源) 我曾考虑使用mmap将当前图像从一个进程传输到另一个进程,但我认为有更好的方法。有人知道如何在Opencv中与两个进程共享同一个视频提要吗 此外,共享相同的视频捕获在计算上是否值得?或者有两个进程不断地获取网络摄像头图像在资源方面会更好 谢谢你的建议 第一个也是最好的选择是让第二个进程挂钩并截取第一个进程的映像。这是两个进程几乎同时访问图像的最快方式。当然,一个人总是比
谢谢你的建议 第一个也是最好的选择是让第二个进程挂钩并截取第一个进程的映像。这是两个进程几乎同时访问图像的最快方式。当然,一个人总是比另一个人先拥有它 如果您选择使用sharememory方式,那么以下内容可能对您有用: SharedMemory.hpp:
#ifndef SHAREDMEMORY_HPP_INCLUDED
#define SHAREDMEMORY_HPP_INCLUDED
#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include <tchar.h>
#include <iostream>
#include <map>
class SharedMemory
{
private:
void* FromFile;
void* hFileMap;
void* pData;
std::string MapName;
std::size_t Size;
bool Debug;
std::map<std::string, void*> Events;
public:
SharedMemory(std::string MapName);
SharedMemory(std::string MapName, std::size_t Size);
~SharedMemory();
SharedMemory(const SharedMemory& Shm) = delete;
SharedMemory(SharedMemory && Shm) = delete;
SharedMemory& operator = (const SharedMemory& Shm) = delete;
SharedMemory& operator = (SharedMemory && Shm) = delete;
void* GetDataPointer();
bool OpenMemoryMap(std::size_t Size);
bool MapMemory(std::size_t Size);
bool ReleaseMemory();
bool CreateNewEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, bool bManualReset, bool bInitialState, std::string EventName);
std::uint32_t OpenSingleEvent(std::string EventName, bool InheritHandle, bool SaveHandle = false, std::uint32_t dwDesiredAccess = EVENT_ALL_ACCESS, std::uint32_t dwMilliseconds = INFINITE);
bool SetEventSignal(std::string EventName, bool Signaled);
bool DeleteSingleEvent(std::string EventName);
bool DeleteAllEvents();
void SetDebug(bool On);
};
#endif // SHAREDMEMORY_HPP_INCLUDED
#如果包含NDEF SHAREDMEMORY#HPP#
#定义SHAREDMEMORY\u HPP\u包括
#如果已定义_WIN32 | |已定义_WIN64
#包括
#否则
#包括
#包括
#包括
#包括
#包括
#恩迪夫
#包括
#包括
#包括
类共享内存
{
私人:
作废*文件;
void*hFileMap;
无效*pData;
std::字符串映射名;
标准:大小;
bool调试;
映射事件;
公众:
SharedMemory(标准::字符串映射名);
SharedMemory(std::string映射名,std::size\u t size);
~SharedMemory();
SharedMemory(const SharedMemory&Shm)=删除;
SharedMemory(SharedMemory&&Shm)=删除;
SharedMemory&operator=(const SharedMemory&Shm)=删除;
SharedMemory&operator=(SharedMemory&Shm)=删除;
void*GetDataPointer();
bool OpenMemoryMap(std::size\u t size);
boolmapmemory(std::size\u t size);
bool releasemory();
bool CreateNewEvent(LPSECURITY_属性lpEventAttributes、bool bManualReset、bool bininitialstate、std::string EventName);
std::uint32\u t OpenSingleEvent(std::string EventName,bool InheritHandle,bool SaveHandle=false,std::uint32\u t dwDesiredAccess=EVENT\u ALL\u ACCESS,std::uint32\u t dwms=无穷大);
bool-SetEventSignal(std::string-EventName,bool-Signaled);
bool DeleteSingleEvent(std::string EventName);
bool DeleteAllEvents();
void SetDebug(bool On);
};
#endif//SHAREDMEMORY\u水电站\u包括在内
SharedMemory.cpp:
#include "SharedMemory.hpp"
SharedMemory::SharedMemory(std::string MapName) : hFileMap(nullptr), pData(nullptr), MapName(MapName), Size(0), Debug(false), Events() {}
SharedMemory::SharedMemory(std::string MapName, std::size_t Size) : hFileMap(nullptr), pData(nullptr), MapName(MapName), Size(Size), Debug(false), Events() {}
SharedMemory::~SharedMemory()
{
ReleaseMemory();
DeleteAllEvents();
}
void* SharedMemory::GetDataPointer()
{
void* Ptr = pData;
return Ptr;
}
bool SharedMemory::OpenMemoryMap(std::size_t Size)
{
this->Size = Size;
#if defined _WIN32 || defined _WIN64
if ((hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, MapName.c_str())) == nullptr)
{
if (Debug) std::cout << _T("\nCould Not Open Shared Memory Map.\n");
return false;
}
if ((pData = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, Size)) == nullptr)
{
if (Debug) std::cout << _T("\nCould Not Map View Of File.\n");
CloseHandle(hFileMap);
return false;
}
#else
if ((hFileMap = open(MapName.c_str(), O_RDWR | O_CREAT, 438)) == -1)
{
if (Debug) std::cout << _T("\nCould Not Open Shared Memory Map.\n");
return false;
}
if ((pData = mmap(nullptr, Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0)) == MAP_FAILED)
{
if (Debug) std::cout << _T("\nCould Not Map View Of File.\n");
close(hFileMap);
return false;
}
#endif
if (Debug) std::cout << _T("\nInter-Process Communication Successful.\n");
return true;
}
bool SharedMemory::MapMemory(std::size_t Size)
{
this->Size = Size;
#if defined _WIN32 || defined _WIN64
if ((hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, Size, MapName.c_str())) == nullptr)
{
if (Debug) std::cout << _T("\nCould Not Create Shared Memory Map.\n");
return false;
}
if ((pData = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, Size)) == nullptr)
{
if (Debug) std::cout << _T("\nCould Not Map View Of File.\n");
CloseHandle(hFileMap);
return false;
}
#else
if ((hFileMap = open(MapName.c_str(), O_RDWR | O_CREAT, 438)) == -1)
{
if (Debug) std::cout << _T("\nCould Not Create Shared Memory Map.\n");
return false;
}
if ((pData = mmap(nullptr, Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0)) == MAP_FAILED)
{
if (Debug) std::cout << _T("\nCould Not Map View Of File.\n");
close(hFileMap);
return false;
}
#endif
if (Debug) std::cout << _T("\nMapped Shared Memory Successfully.\n");
return true;
}
bool SharedMemory::ReleaseMemory()
{
bool Result = false;
#if defined _WIN32 || defined _WIN64
if (pData)
{
Result = UnmapViewOfFile(pData);
pData = nullptr;
if (Result && Debug)
{
std::cout << _T("\nMemory Un-Mapped Successfully.\n");
}
}
if (hFileMap)
{
if (CloseHandle(hFileMap))
{
hFileMap = nullptr;
Result = Result && true;
if (Debug) std::cout << _T("\nMemory Map Closed Successfully.\n");
}
}
#else
if (pData)
{
Result = munmap(pData, Size);
if (!Result && Debug)
{
std::cout << _T("\nMemory Un-Mapped Successfully.\n");
}
pData = nullptr;
return true;
}
if (hFileMap)
{
if (!close(hFileMap))
{
hFileMap = nullptr;
if (Debug) std::cout << _T("\nMemory Map Closed Successfully.\n");
}
}
#endif
return Result;
}
bool SharedMemory::CreateNewEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, bool bManualReset, bool bInitialState, std::string EventName)
{
std::map<std::string, void*>::iterator it = Events.find(EventName);
if (it != Events.end())
{
if (Debug)
{
std::cout << _T("\nCreateNewEvent Error: An Event With That Key Already Exists!\n");
}
return false;
}
Events.insert(std::pair<std::string, void*>(EventName, CreateEvent(lpEventAttributes, bManualReset, bInitialState, EventName.c_str())));
it = Events.end();
return ((--it)->second != nullptr);
}
std::uint32_t SharedMemory::OpenSingleEvent(std::string EventName, bool InheritHandle, bool SaveHandle, std::uint32_t dwDesiredAccess, std::uint32_t dwMilliseconds)
{
void* hEvent = OpenEvent(dwDesiredAccess, InheritHandle, EventName.c_str());
if (hEvent)
{
if (SaveHandle)
{
std::map<std::string, void*>::iterator it = Events.find(EventName);
if (it != Events.end())
{
CloseHandle(it->second);
it->second = hEvent;
}
else
Events.insert(std::pair<std::string, void*>(EventName, hEvent));
}
std::uint32_t Result = WaitForSingleObject(hEvent, dwMilliseconds);
if (!SaveHandle) CloseHandle(hEvent);
return Result;
}
CloseHandle(hEvent);
return WAIT_FAILED;
}
bool SharedMemory::SetEventSignal(std::string EventName, bool Signaled)
{
std::map<std::string, void*>::iterator it = Events.find(EventName);
if (it == Events.end())
{
if (Debug)
{
std::cout << _T("\nSetEventSignal Error: No Event With That Key Exists!\n");
}
return false;
}
if (Signaled) return SetEvent(it->second);
return ResetEvent(it->second);
}
bool SharedMemory::DeleteSingleEvent(std::string EventName)
{
std::map<std::string, void*>::iterator it = Events.find(EventName);
if (it == Events.end()) return true;
bool Result = CloseHandle(it->second);
Events.erase(it);
return Result;
}
bool SharedMemory::DeleteAllEvents()
{
bool Result = false;
for (std::map<std::string, void*>::iterator it = Events.begin(); it != Events.end(); ++it)
{
Result = Result && CloseHandle(it->second);
}
Events.clear();
return Result;
}
void SharedMemory::SetDebug(bool On)
{
Debug = On;
}
#包括“SharedMemory.hpp”
SharedMemory::SharedMemory(std::string MapName):hFileMap(nullptr)、pData(nullptr)、MapName(MapName)、大小(0)、调试(false)、事件(){}
SharedMemory::SharedMemory(std::string映射名,std::size\u t size):hFileMap(nullptr),pData(nullptr),MapName(映射名),size(size),Debug(false),Events(){}
SharedMemory::~SharedMemory()
{
释放内存();
DeleteAllEvents();
}
void*SharedMemory::GetDataPointer()
{
void*Ptr=pData;
返回Ptr;
}
bool SharedMemory::OpenMemoryMap(标准::大小\u t大小)
{
这个->大小=大小;
#如果已定义_WIN32 | |已定义_WIN64
if((hFileMap=OpenFileMapping(FILE\u MAP\u ALL\u ACCESS,false,MapName.c\u str())==nullptr)
{
如果(调试)std::你可以在收到共享内存时将它们写入共享内存吗?有一个同步方法,让第二个进程知道它何时可以读取内存。也可以让一个线程向内存馈电,然后让两个进程读取。有什么原因需要两个进程同时处理一个网络摄像头视频吗?@CantChooseUsernames我也有同样的问题。第一个过程是由一个做图像处理的软件执行的。第二个过程是由一个运行在Visual Studio中的程序执行的,该程序执行相同的任务,但其性能和质量需要测量。因此,我需要用一个网络摄像头同时捕获相同的图像输入。你能显示吗您所评论内容的一些示例或教程?谢谢您的代码,但是如何准备GetOpenCVCameraFeed()和GetOpenCVCameraFeedSize()?PtrToImagePixel可以是指向图像本身的指针吗?(我指的是Mat或Iplimage对象)。它仅适用于Windows操作系统吗?
SharedMemory mem("OpenCVMap", 1980 * 1024 * 4); //Assuming max image size is 1980*1024*RGBA.
mem->CreateNewEvent(nullptr, true, false, "ImageReplySignal");
unsigned char* PtrToImagePixel = GetOpenCVCameraFeed();
unsigned char* MemPtr = static_cast<unsigned char*>(mem->GetDataPointer());
*reinterpret_cast<int*>(MemPtr) = GetOpenCVCameraFeedSize();
MemPtr += sizeof(int);
for (int i = 0; i < GetOpenCVCameraFeedSize(); ++i)
{
*MemPtr += *PtrToImagePixels++;
}
mem->SetEventSignal("ImageReplySignal", true);
SharedMemory mem("OpenCVMap");
mem->OpenMemoryMap(1980 * 1024 * 4);
std::vector<unsigned char> Image;
while(true)
{
if (mem->OpenSingleEvent("ImageReplySignal", true, true) == WAIT_OBJECT_0)
{
unsigned char* MemPtr = static_cast<unsigned char*>(mem->GetDataPointer());
int size = *(reinterpret_cast<int*>(MemPtr));
MemPtr += sizeof(int);
Image.resize(size);
for (int i = 0; i < size; ++i)
{
Image[i] = *MemPtr++;
}
mem->SetEventSignal("ImageReplySignal", false);
}
}