【问题标题】:Converting Basler image to OpenCV将 Basler 图像转换为 OpenCV
【发布时间】:2011-12-05 18:36:40
【问题描述】:

我正在尝试将从 Basler 相机捕获的帧转换为 OpenCV 的 Mat 格式。 Basler API 文档中的信息并不多,但 Basler 示例中的这两行应该有助于确定输出的格式:

// Get the pointer to the image buffer
const uint8_t *pImageBuffer = (uint8_t *) Result.Buffer();
cout << "Gray value of first pixel: " << (uint32_t) pImageBuffer[0] << endl << endl;

我知道图像格式是什么(目前设置为单声道 8 位),并尝试过这样做:

img = cv::Mat(964, 1294, CV_8UC1, &pImageBuffer);
img = cv::Mat(964, 1294, CV_8UC1, Result.Buffer());

这两种方法都不起作用。任何建议/建议将不胜感激,谢谢!

编辑:我可以通过以下方式访问 Basler 图像中的像素:

for (int i=0; i<1294*964; i++)
  (uint8_t) pImageBuffer[i];

如果这有助于将其转换为 OpenCV 的 Mat 格式。

【问题讨论】:

  • 它不起作用是什么意思?它会崩溃,还是你得到一个有图案的图像(即,你离开了几行或几列,甚至可能是通道)?如果有的话,你可以发布输出吗?看起来您使用的是 1294x964 的全帧参数。 Basler 是否返回了那些真正有效的行,或者它们是有效行前/后有效行并且是 1280x960?相机是提供拜耳输出还是单色?
  • 您好,代码编译并运行,但如果我尝试使用cv::imshow() 显示图像,我会弹出一个错误窗口,提示“basler_camera.exe 已停止工作”。 1294*964 是相机的最大分辨率,所以这是正确的。我相信问题出在从pImageBuffer 复制到img,但无法弄清楚如何正确执行。

标签: opencv


【解决方案1】:

您正在创建 cv 图像以使用相机的内存 - 而不是拥有自己内存的图像。问题可能是相机正在锁定该指针 - 或者可能希望在每个新图像上重新分配和移动它

尝试不使用最后一个参数创建图像,然后使用 memcpy() 将像素数据从相机复制到图像。

// Danger! Result.Buffer() may be changed by the Basler driver without your knowing          
const uint8_t *pImageBuffer = (uint8_t *) Result.Buffer();  

// This is using memory that you have no control over - inside the Result object
img = cv::Mat(964, 1294, CV_8UC1, &pImageBuffer);

// Instead do this
img = cv::Mat(964, 1294, CV_8UC1); // manages it's own memory

// copies from Result.Buffer into img 
memcpy(img.ptr(),Result.Buffer(),1294*964); 

// edit: cvImage stores it's rows aligned on a 4byte boundary
// so if the source data isn't aligned you will have to do
for (int irow=0;irow<964;irow++) {
     memcpy(img.ptr(irow),Result.Buffer()+(irow*1294),1294);
 }

【讨论】:

  • 您好,您能举例说明您的意思吗?谢谢
  • 感谢您的代码。不幸的是,这似乎不起作用,因为图像没有被复制。目前我已经通过for (int i=0; i&lt;basler_height; i++) for (int j=0; j&lt;basler_width; j++) img.at&lt;uchar&gt;(i,j) = (uint32_t) pImageBuffer[i*basler_width+j];逐像素复制图像,这不是最好的方法,但似乎可行,同时仍在尝试找到解决此问题的方法...
  • 你的 memcpy 参数是错误的。应该是memcpy(img.ptr(), Result.Buffer(), basler_width*basler_height)。函数定义为memcpy(destination, source, length)。
【解决方案2】:

从 Pylon cam 获取 Mat 帧的 C++ 代码

Pylon::DeviceInfoList_t devices;
... get pylon devices if you have more than a camera connected ...

pylonCam = new CInstantCamera(tlFactory->CreateDevice(devices[selectedCamId]));
Pylon::CGrabResultPtr ptrGrabResult;
Pylon::CImageFormatConverter formatConverter;

formatConverter.OutputPixelFormat = Pylon::PixelType_BGR8packed;
    pylonCam->MaxNumBuffer = 30;
    pylonCam->StartGrabbing(GrabStrategy_LatestImageOnly);
    std::cout << " trying to get width and height from pylon device " << std::endl;


pylonCam->RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);

formatConverter.Convert(pylonImage, ptrGrabResult);

Mat temp = Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t*)pylonImage.GetBuffer());

【讨论】:

    猜你喜欢
    • 2011-11-29
    • 2020-09-15
    • 2015-05-23
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 2014-05-21
    • 2015-06-26
    相关资源
    最近更新 更多