问题描述
我尝试使用C ++ 14线程进入openCV。 操作系统是Debian Linux。
我喜欢获得六个RTSP流,在结果cv :: Mat对象中调整它们的大小并对其进行查看。 我认为线程是处理中断流所必需的。 重新打开将花费一些时间,我不希望其他流被阻止。
在启动过程中,程序或多或少会崩溃到SegFault中。 在waitkey()方法之后,调试输出停止。
程序经常启动流,并在数小时内运行良好。
如何指出非法的内存访问? (哪个是Segfault)
cv :: Mat对象中的某些重新分配是问题吗? 还是构造与线程相关的问题?
#include <thread>
#include <mutex>
#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <syslog.h>
#include <atomic>
#include <string>
bool doExit = false;
uint16_t
viewX = 1600,//1920,viewY = 900,//1080,imageXCount = 3,imageYCount = 2,viewportSizeX = viewX / imageXCount,viewportSizeY = viewY / imageYCount,pause = 50;
class Worker
{
public:
std::string name,url;
cv::VideoCapture RTSPStream;
cv::Mat RTSPImage,RTSPResized;
int frameCount = -1;
cv::Mat image;
cv::Mat& dest;
cv::Rect roi;
cv::Size size;
std::mutex& mut;
Worker(std::string Name,std::string URL,cv::Mat& Dest,cv::Rect ROI,cv::Size Size,std::mutex& Mut) :
name(Name),url(URL),dest(Dest),roi(ROI),size(Size),mut(Mut)
{
syslog (LOG_INFO,"Thread Init");
std::cout << "Name: \t" << name << std::endl;
std::cout << "URL: \t" << url << std::endl;
}
void operator () ()
{
syslog (LOG_INFO,"Thread Start");
while (!doExit)
{
if (RTSPStream.isOpened())
{
if (!RTSPStream.read(RTSPImage))
{
cv::ellipse (
RTSPImage,cv::Point( 50,50 ),cv::Size(10,10 ),90,360,cv::Scalar( 0,255 ),5
);
syslog (LOG_INFO,"Thread StreamRead Failed");
}
}
else
{
RTSPStream.open(url);
frameCount = 0;
syslog (LOG_INFO,"Thread Open RTSP");
}
if (RTSPImage.empty())
{
cv::ellipse (
RTSPImage,5
);
std::cout << url << " Image empty\n";
syslog (LOG_INFO,"Empty Image,reOpen");
RTSPStream.release();
RTSPStream.open(url);
} else
{
frameCount++;
cv::resize(RTSPImage,RTSPResized,size);
mut.lock();
// cv::medianBlur(RTSPResized,dest(roi),5);
RTSPResized.copyTo(dest(roi));
mut.unlock();
}
}
}
};
int main()
{
openlog ("CamViewer",LOG_PID,LOG_SYSLOG);
syslog (LOG_INFO,"***");
syslog (LOG_INFO,"Start Main");
std::mutex resultMutex;
cv::Rect roi1 = cv::Rect(0,viewportSizeX,viewportSizeY); // ROIs setzen
cv::Rect roi2 = cv::Rect(viewportSizeX,viewportSizeY);
cv::Rect roi3 = cv::Rect(viewportSizeX*2,viewportSizeY);
cv::Rect roi4 = cv::Rect(0,viewportSizeY,viewportSizeY);
cv::Rect roi5 = cv::Rect(viewportSizeX,viewportSizeY);
cv::Rect roi6 = cv::Rect(viewportSizeX*2,viewportSizeY);
cv::Size s = cv::Size (viewportSizeX,viewportSizeY);
cv::Mat result (viewY,viewX,CV_8UC3);
cv::namedWindow("Result",cv::WINDOW_norMAL);
cv::setwindowProperty("Result",cv::WND_PROP_FULLSCREEN,cv::WINDOW_FULLSCREEN);
std::thread worker1 = std::thread (Worker("cam2","rtsp://192.168.1.62:554/stream1",result,roi1,s,resultMutex));
std::thread worker3 = std::thread (Worker("cam6","rtsp://192.168.1.60:554/12",roi3,resultMutex));
std::thread worker2 = std::thread (Worker("cam1","rtsp://192.168.1.61:554/stream1",roi2,resultMutex));
std::thread worker4 = std::thread (Worker("cam4","rtsp://192.168.1.64:554/stream1",roi5,resultMutex));
std::thread worker5 = std::thread (Worker("cam5","rtsp://192.168.1.65:554/stream1",roi4,resultMutex));
std::thread worker6 = std::thread (Worker("cam3","rtsp://192.168.1.66:554/stream1",roi6,resultMutex));
cv::ellipse (
result,5
);
syslog (LOG_INFO,"Start MainLoop");
while (!doExit)
{
cv::Mat dblBuffer;
resultMutex.lock();
result.copyTo(dblBuffer);
resultMutex.unlock();
cv::imshow("Result",dblBuffer);
cv::waitKey(pause);
std::cout << ".";
}
worker1.join();
worker2.join();
worker3.join();
worker4.join();
worker5.join();
worker6.join();
return 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)