Multithreading 使用openCV和std::threads解决SegFault

Multithreading 使用openCV和std::threads解决SegFault,multithreading,opencv,segmentation-fault,stdthread,Multithreading,Opencv,Segmentation Fault,Stdthread,我尝试使用C++14个线程进入openCV。 操作系统是DebianLinux 我喜欢获得六个RTSP流,调整大小并在结果cv::Mat对象中排列它们,然后查看它。 我认为线程是处理中断流所必需的。 重新开放需要一些时间,我不希望其他流被阻塞 在启动过程中,程序或多或少会遇到SegFault。 调试输出在waitkey()方法之后停止 更常见的情况是,程序启动流并在数小时内运行良好 如何指出非法内存访问? (这是一个Segfault) cv::Mat对象中的某些重新分配是问题所在吗? 还是构造一

我尝试使用C++14个线程进入openCV。 操作系统是DebianLinux

我喜欢获得六个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,
                                            0,
                                            360,
                                            cv::Scalar( 0, 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,
                                        cv::Point( 50, 50 ),
                                        cv::Size(10,10 ),
                                        90,
                                        0,
                                        360,
                                        cv::Scalar( 0, 0, 255 ),
                                        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, "***");
    syslog (LOG_INFO, "Start Main");

    std::mutex  resultMutex;

    cv::Rect roi1 = cv::Rect(0            ,0,viewportSizeX, viewportSizeY);             // ROIs setzen
    cv::Rect roi2 = cv::Rect(viewportSizeX,0,viewportSizeX, viewportSizeY);
    cv::Rect roi3 = cv::Rect(viewportSizeX*2,0,viewportSizeX, viewportSizeY);

    cv::Rect roi4 = cv::Rect(0,viewportSizeY,viewportSizeX, viewportSizeY);
    cv::Rect roi5 = cv::Rect(viewportSizeX,viewportSizeY,viewportSizeX, viewportSizeY);
    cv::Rect roi6 = cv::Rect(viewportSizeX*2,viewportSizeY,viewportSizeX, 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"    , result, roi3, s, resultMutex));
    std::thread worker2 = std::thread (Worker("cam1", "rtsp://192.168.1.61:554/stream1", result, roi2, s, resultMutex));
    std::thread worker4 = std::thread (Worker("cam4", "rtsp://192.168.1.64:554/stream1", result, roi5, s, resultMutex));
    std::thread worker5 = std::thread (Worker("cam5", "rtsp://192.168.1.65:554/stream1", result, roi4, s, resultMutex));
    std::thread worker6 = std::thread (Worker("cam3", "rtsp://192.168.1.66:554/stream1", result, roi6, s, resultMutex));

    cv::ellipse     (
                        result,
                        cv::Point( 50, 50 ),
                        cv::Size(10,10 ),
                        90,
                        0,
                        360,
                        cv::Scalar( 0, 0, 255 ),
                        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;
}

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
bool-doExit=false;
uint16\u t
viewX=1600,//1920,
viewY=900,//1080,
imageXCount=3,
imageYCount=2,
viewportSizeX=viewX/imageXCount,
viewportSizeY=viewY/imageYCount,
暂停=50;
班主任
{
公众:
std::字符串名称,
网址;
cv::视频捕获RTSPStream;
cv::Mat RTSPImage,
RTSPResized;
int frameCount=-1;
cv::Mat图像;
cv::Mat和dest;
cv::Rect roi;
cv::大小;
std::mutex&mut;
Worker(std::string Name、std::string URL、cv::Mat&Dest、cv::Rect ROI、cv::Size Size、std::mutex&Mut):
名称(名称)、url(url)、目的地(目的地)、投资回报率(roi)、大小(大小)、mut(mut)
{
系统日志(日志信息,“线程初始化”);
标准::cout