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());
我正在写一个 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());