用openCV和std :: threads解决SegFault

问题描述

我尝试使用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 (将#修改为@)