OpenCV & C++:返回 cv::Mat 导致分段错误

OpenCV & C++: returned cv::Mat causes a Segmentation Fault

我正在写一个 class,它使用 pylonAPI 从 basler USB 相机抓取帧并将它们转换为 openCV 格式。下面是抓取方法的代码:

std::pair<cv::Mat, cv::Mat> GrabPair()
    {
        int key;
        Pylon::CImageFormatConverter fmtConv;
        Pylon::CPylonImage pylonImg1, pylonImg2;
        fmtConv.OutputPixelFormat = Pylon::PixelType_BGR8packed;
        Pylon::CPylonImage pylonImgLeft, pylonImgRight;

        cv::Mat outImageL, outImageR;
        Pylon::CGrabResultPtr pResultLeft, pResultRight;

        if(cams.IsGrabbing()){
            cams[leftCamIndex].RetrieveResult(1000, pResultLeft, Pylon::TimeoutHandling_ThrowException);    
            cams[rightCamIndex].RetrieveResult(1000, pResultRight, Pylon::TimeoutHandling_ThrowException);  

            if(pResultLeft->GrabSucceeded() && pResultRight->GrabSucceeded()){
                fmtConv.Convert(pylonImgLeft, pResultLeft);
                
                outImageL = cv::Mat(pResultLeft->GetHeight(), 
                    pResultLeft->GetWidth(), 
                    CV_8UC3,
                    (uint8_t*)pylonImgLeft.GetBuffer()
                );

                fmtConv.Convert(pylonImgRight, pResultRight);

                outImageR = cv::Mat(pResultRight->GetHeight(), 
                    pResultRight->GetWidth(), 
                    CV_8UC3,
                    (uint8_t*)pylonImgRight.GetBuffer()
                );

                /*cv::namedWindow("OpenCV out L");
                cv::namedWindow("OpenCV out R");

                cv::imshow("OpenCV out L", outImageL);
                cv::imshow("OpenCV out R", outImageR);
                key = cv::waitKey(20);*/
            }
        }

        return std::make_pair(outImageL, outImageR);                
    }

这是来自 main() 的代码片段,我在其中尝试获取并显示抓取的帧

int key;
    BslrCap bc(40146142, 40146151); //the grabber object
    bc.PrintDevicesInfo();
    bc.Open();
    cv::Mat raw_left, raw_right;
    while(1)
    {        
        std::pair<cv::Mat, cv::Mat> images_pair = bc.GrabPair();
        cv::Mat raw_left = images_pair.first;
        cv::Mat raw_right = images_pair.second;

        if(!raw_right.empty() && !raw_left.empty()){            
            cv::namedWindow("OpenCV out L");
            cv::namedWindow("OpenCV out R");

            cv::imshow("OpenCV out L", raw_left);
            cv::imshow("OpenCV out R", raw_right);

            key = cv::waitKey(20);
        }
    }

但是当我调用 cv::imshow 时,我立即收到 SIGSEGV 并且我的程序崩溃了。

如果我在 GrabPair() 代码中取消注释这些行:

                    pResultRight->GetWidth(), 
                    CV_8UC3,
                    (uint8_t*)pylonImgRight.GetBuffer()
                );

                /*cv::namedWindow("OpenCV out L");
                cv::namedWindow("OpenCV out R");

                cv::imshow("OpenCV out L", outImageL);
                cv::imshow("OpenCV out R", outImageR);
                key = cv::waitKey(20);*/

我可以在屏幕上看到两个 openCV windows,其中包含两个捕获的帧。这意味着两个帧都被捕获而没有错误,问题是当我尝试 return std::pair 从方法 GrabPair() 回到 main()

知道我做错了什么吗?

非常感谢!

这里的问题是,使用 外部指针 的 Mat 构造函数未被重新计算。一旦你离开 GrabPair 函数,两个 Mat 都无效(悬空指针)

你需要克隆()它们(数据的深拷贝!)例如喜欢:

    return std::make_pair(outImageL.clone(), outImageR.clone());