4

I'm trying to convert frames captured from a Basler camera to OpenCV's Mat format. There isn't a lot of information from the Basler API documentation, but these are the two lines in the Basler example that should be useful in determining what the format of the output is:

// 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;

I know what the image format is (currently set to mono 8-bit), and have tried doing:

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

Neither of which works. Any suggestions/advices would be much appreciated, thanks!

EDIT: I can access the pixels in the Basler image by:

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

If that helps with converting it to OpenCV's Mat format.

chocobo_ff
  • 45
  • 1
  • 1
  • 5
  • What do you mean by it doesn't work? Does it crash, or do you get a patterned image (i.e., you're off a few rows or columns or maybe even channels)? Can you post the output if any? It looks like your using the full frame parameters of 1294x964. Are those truly valid lines returned by the Basler, or are they pre/post-valid lines and it is 1280x960? Is the camera providing bayered output or just monochrome? – mevatron Oct 12 '11 at 16:04
  • Hi, the code compiles and runs, but if I try to display the image using `cv::imshow()`, I get an error window pop up saying "basler_camera.exe has stopped working". 1294*964 is the camera's max resolution so that is correct. I believe the problem is from copying from `pImageBuffer` to `img`, but can't figure out how to do it properly. – chocobo_ff Oct 12 '11 at 18:25

2 Answers2

7

You are creating the cv images to use the camera's memory - rather than the images owning their own memory. The problem may be that the camera is locking that pointer - or perhaps expects to reallocate and move it on each new image

Try creating the images without the last parameter and then copy the pixel data from the camera to the image using 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);
 }
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Hi, would you be able to provide an example of what you mean? Thanks – chocobo_ff Oct 12 '11 at 21:46
  • Thanks for the code. Unfortunately that does not seem to work, as the image is not copied. At the moment I have copied the image pixel by pixel by `for (int i=0; i(i,j) = (uint32_t) pImageBuffer[i*basler_width+j];`, which isn't the best way to do it but seems to work, while still trying to find a solution to this problem... – chocobo_ff Oct 13 '11 at 00:20
  • 1
    You have the `memcpy` arguments the wrong way around. It should be `memcpy(img.ptr(), Result.Buffer(), basler_width*basler_height)`. The function definition is `memcpy(destination, source, length`). – mpenkov Oct 13 '11 at 01:17
0

C++ code to get a Mat frame from a Pylon cam

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());
Ibrahim
  • 320
  • 2
  • 7