Ask Your Question
0

Problem getting Mat from GigE camera (Sapera SDK)

asked 2016-12-28 10:37:49 -0500

PiMac gravatar image

updated 2016-12-28 10:43:36 -0500

Hi,

I am trying to get Sapera SDK SapBuffer object (Genie NANO GIgE camera) as a cv::Mat. From documentation for this sdk I know that "The SapBuffer Class includes the functionality to manipulate an array of buffer resources."

From SDK I know that in "SapBuffer* Buffers" there it is 1024x1280 image type: 32 Depth: 8. I am not sure if I am correctly acquiring Mat object (rest of the code is from example for this sdk):

SapLocation loc(serverName,0);
    Acq = new SapAcquisition(loc, FALSE); //ETHERNET came doesnt work with this?
    AcqDevice = new SapAcqDevice(loc, FALSE);
    Buffers = new SapBufferWithTrash(2, AcqDevice);
    View = new SapView(Buffers, SapHwndAutomatic);
    Xfer = new SapAcqDeviceToBuf(AcqDevice, Buffers, AcqCallback, View);

    // Create acquisition object
    if (AcqDevice && !*AcqDevice && !AcqDevice->Create())
        goto FreeHandles;

}

// Create buffer object
if (Buffers && !*Buffers && !Buffers->Create())
    goto FreeHandles;

// Create transfer object
if (Xfer && !*Xfer && !Xfer->Create())
    goto FreeHandles;

// Create view object
if (View && !*View && !View->Create())
    goto FreeHandles;


// Start continous grab
Xfer->Grab();
src1 = new Mat(1024, 1280, CV_8U, Buffers);
std::cout << "Total(): " << src1->total() << std::endl;

//Buffers->GetAddress(pData);

imwrite("E:\OpenCV\Gray_Image.jpg",*src1);
//delete mat;
delete src1;


printf("Press any key to stop grab\n");

CorGetch();

// Stop grab
Xfer->Freeze();
if (!Xfer->Wait(5000))
    printf("Grab could not stop properly.\n");

Its part of an example and my code is only Mat *src1 = NULL; and OpenCv part. After running it shows "The program stopped running".

Please help.

edit retag flag offensive close merge delete

Comments

1

1024x1280 and type 32 depth 8 shouldn't be src1 = new Mat(1024, 1280, CV_8UC(4), Buffers); please don't use pointer for image you can do like this

Mat src1(1024, 1280, CV_8UC(4), Buffers)

if you are sure that it is 8 bits depth

Mat src1(1024, 1280, CV_8UC1, Buffers)
LBerger gravatar imageLBerger ( 2016-12-28 10:43:25 -0500 )edit

some thoughts on this:

  • goto statement considered harmful (dear, that happenend probably years before you even were born ..)
  • never use a pointer to cv::Mat , or new, even. you'll only shoot your own foot, thrashing internal refcounts
  • i assume, all this code is called in some callback function. now, your cv::Mat constructor, there is using a borrowed pointer (only the pointer is copied, not the actual data), so once your "Buffers" go out of scope, you're left with an invalid data pointer
berak gravatar imageberak ( 2016-12-28 10:58:11 -0500 )edit

Thanks. I will bare it in mind but I get an error C2362 that initialization was skipped due to "gorto FreeHandles" (part that deletes all the pointers after closing the stream). After putting the code just before deleting Buffers by FreeHandlesThe src1.empty() gives me 0 src1.total()=1310720, but imwrite() makes the program stopping to work.

PiMac gravatar imagePiMac ( 2016-12-28 10:59:17 -0500 )edit

Ok i see that even printing src1 to command line stops the program eventually. I am guessing that I need to look more into the API and create my own code.

PiMac gravatar imagePiMac ( 2016-12-28 15:58:12 -0500 )edit
1

You should explicitly copy Buffer's data:

src1 = Mat(1024, 1280, CV_8U4, Buffers).clone();
pi-null-mezon gravatar imagepi-null-mezon ( 2016-12-29 02:45:59 -0500 )edit

Thanks, but it did not help much. I have studied the code a little bit more and I know that after Xfer->Freeze(); is called (stops Grabbing new frames) I can use APIs own Buffers->Save("image3.bmp", "-format bmp", -1, 0) to save the image from camera. After reading it into OpenCV i find that it is 3 channel type 16 with depth =0 - CV_8UC3 if I am not mistaken. That said I am still not able to get data from "Buffer" into the Mat. I am confused. Should I look for some operation like: BOOL Read(UINT64 offset, int numElements, void* pData); that I can perform on "Buffers" to be able to read image into Mat?

PiMac gravatar imagePiMac ( 2016-12-29 10:50:05 -0500 )edit

Have you got a doc link?

LBerger gravatar imageLBerger ( 2016-12-29 11:07:58 -0500 )edit

Sure. https://drive.google.com/open?id=0Bwc... I've put it on google disk. Hope you can open it. SapBuffer class is described on page 76..

PiMac gravatar imagePiMac ( 2016-12-29 11:17:03 -0500 )edit

have you try demo/example given to display image ?

LBerger gravatar imageLBerger ( 2016-12-29 11:45:41 -0500 )edit

Yes I have. I did not find anything useful on how to transfer data from SapBuffer object anywhere else. I am not experienced in C++ but so far I know that "Buffers" is of type SapBuffer and it is not what I can input to my Mat. I can use Buffers.GetAddress() to "Initiates direct address to buffer resource data by a pointer" (returns void* pData pointer) and GetSpaceUsed() to "Gets the number of data bytes actually stored in a buffer resource" (returns int pSpaceUsed). Is there a way to read this bytes from memory into a C++ unsigned char array and then to OpenCV Mat ?Or is it a wrong approach altogether ?

PiMac gravatar imagePiMac ( 2016-12-30 05:11:18 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
0

answered 2019-01-12 13:40:45 -0500

jjsword gravatar image

Has anyone figured out a way to transfer images to a Mat object with the Sapera SDK without using CVB? Seems this has already been answered here but determining where to place the call is also problematic. I was looking at adding a function as in GrabLUT, though I need to take stdev/mean of a 5 pixel kernel... something like this for each frame (https://stackoverflow.com/questions/1...) I can do this no problem almost in real time with my webcam frames

edit flag offensive delete link more
0

answered 2017-02-28 11:44:57 -0500

I think you can get a pointer to the SapBuffer and then create a Mat using that pointer.

That is based on some info I got from a Teledyne Salsa reseller, and I may be remembering incorrectly. I haven't tried it, yet.

edit flag offensive delete link more

Comments

Thanks but I have already solved this using CVB library that came with my camera. Common Vision Blox have a documentation on that https://www.commonvisionblox.com/medi... and than it was just passing Mat object from java to c++ and pointing it to Mat object in c++ (JNI creating DLL and importing it to JAVA). This might be very vague explanation but I will try putting it as a tutorial on youtube so anyone can try it.

PiMac gravatar imagePiMac ( 2017-07-05 03:32:14 -0500 )edit

Did you allready a tutorial on youtube? I have the same Problem. I have an Genie Nano M2050 and i my goal is it to processing the live Video Stream with OpenCV.

daniel.w gravatar imagedaniel.w ( 2017-12-15 09:32:19 -0500 )edit

Hi danielwaldhauser. I didn't do it yet but I will put up one till the end of this month. Please send me your email and I will try to help you.

PiMac gravatar imagePiMac ( 2018-01-10 02:42:55 -0500 )edit

Could you please send it also to me? That would be great. (http://soroor.t1371@gmail.com) Thank you.

srt92 gravatar imagesrt92 ( 2018-01-12 08:35:33 -0500 )edit

Hi PiMac, this would be great!!! My e-mail is daniel@waldhauser.de

daniel.w gravatar imagedaniel.w ( 2018-01-24 05:26:52 -0500 )edit

@PiMac do you have some new information for me? That would be very great!

daniel.w gravatar imagedaniel.w ( 2018-02-02 06:36:31 -0500 )edit

Sorry guys for late answer. I am currently using Common Vision Blox library and using python it is very easy https://forum.commonvisionblox.com/t/....

If you need to use c++ and transfer than you need to use: // load a sample image string path = getenv("CVB"); path.append("\Tutorial\FruitBowl.jpg"); IplImage* ocvImg = cvLoadImage(path.c_str(), CV_LOAD_IMAGE_UNCHANGED); // build CVB image from OpenCV image IMG cvbFromOcv = nullptr; cvbval_t planeOrder[] = { 2, 1, 0 }; CreateImageFromPointer(ocvImg->imageData, ocvImg->imageSize, ocvImg->width, ocvImg->height, ocvImg->nChannels, 8, ocvImg->nChannels * 1, ocvImg->widthStep, 1, planeOrder, final_release, ocvImg, cvbFromOcv);

PiMac gravatar imagePiMac ( 2018-10-08 02:43:21 -0500 )edit

Instead of loading the image you will need to access the one from your camera. You can easily transform IpLImage to Mat format - there are solutions on stack overflow. I am no expert on c++ so I cant really help you further. In my case I was also sending the resulting image to Java through JNI but having opencv for c++ and JNI header you simply create a DLL library from your header and c++ code and load the library into JAVA sending the Mat object. But since you also get errors from the camera send I strongly recommend using Python or sticking with c++.

PiMac gravatar imagePiMac ( 2018-10-08 02:49:04 -0500 )edit
Login/Signup to Answer

Question Tools

4 followers

Stats

Asked: 2016-12-28 10:37:49 -0500

Seen: 2,248 times

Last updated: Feb 28 '17