01-10-2011 04:32 PM - edited 01-10-2011 04:33 PM
I'm writing a program to acquire data from an IMAQ device to a ring buffer, and operate on the data from there. I'm extracting a PixelValue2D, and I'm curious about how it works.
I want to access the data as a short[,], so I write:
PixelValue2D pixVal = _session.Acquisition.Extract(bufferNumber, out bufferNumber).ToPixelArray();
short[,] imgData = pixVal.I16;
Does the pixVal.I16 return a reference to the data, or a new copy of the data? This information will be very helpful for keeping my program as efficient as possible.
Thanks!
01-11-2011 12:43 PM
Hi middletongard,
Could you tell me which language you are working in so that I may be of better assistance? I have not been able to find a reference to this function.
Lynn
01-11-2011 01:04 PM
C#
Thanks
01-11-2011 01:20 PM
I found information for PixelValue2D.I16 here within the Visual Studio 2008 help:
ms-help://MS.VSCC.v90/MS.VSIPCC.v90/NI.MeasurementStudio.2008/NINETVision/html/NationalInstruments.Vision.PixelValue2D.I16.html
Gets the pixel values for images of type I16.
[Visual Basic]
Public Property ReadOnly I16 As Short(,)
[C#]
public short[,] I16 {get;}
The pixel values for images of type I16.
PixelValue2D Class | PixelValue2D Members | NationalInstruments.Vision Namespace
01-11-2011 01:38 PM
Hey!
Ah yep, I found that right after you. Well I'm glad you've got a solution. Best of luck with your application!
Regards,
Lynn
01-11-2011 01:50 PM
Ah, I don't have the solution quite yet - the information does not tell me whether a copy of the data is made, or a reference to the data is returned.
If this information is implied in the definition, I haven't caught it. Could you please find out and let me know explicitly whether a new copy of the data is made and returned, or it's simply a reference to the data in PixelData2D (no copy) that is returned?
Thanks
01-12-2011 06:54 PM
Hi middletongard,
It appears as though the PixelValue2D is ImaqBuffer which a a zero-copy operation.
Lynn
05-03-2011 08:40 AM
Similar to middletongard, I'm trying to acquire IMAQ data in C# and extract the data into a short array for further processing. From the last post I see that extracting PixelValue2D from ImaqBuffer is a zero-copy operation, but I still wonder whether new memory is being allocated?
The reason I ask is that my application crashes with an OutOfMemoryException after running for a couple seconds.
This is the line of code that generates the exception:
short[,] data = mSession.Acquisition.Extract(BufferNumber, out CurrentBufferNumber).ToPixelArray().I16;
And this is the relevant part of the stack trace:
Exception Info: System.OutOfMemoryException
Stack:
at NationalInstruments.Vision.Internal.Utilities.ConvertIntPtrFlatTo2DArrayInt16(IntPtr, Int32, Int32, Boolean)
at NationalInstruments.Vision.VisionImage.ImageToArray(NationalInstruments.Vision.RectangleContour)
at NationalInstruments.Vision.Acquisition.Imaq.Internal.ImaqVisionImageBuffer.ToPixelArray()
at NationalInstruments.Vision.Acquisition.Imaq.ImaqBuffer.ToPixelArray()
Note that the exception is thrown from ToPixelArray(), not getting the I16 property.
I would appreciate any help I can get!
05-03-2011 09:23 AM
Accessing raw pixel data as an array out of a Vision image is always a copy operation. Otherwise there is no way to properly synchronize access between the Vision image's access to its internal data and the user's access via the array.
Eric
05-03-2011 10:14 AM
Thanks for the quick response Eric, that definitely makes sense to me. But my issue is with the memory allocation rather than the copying. I would like to reuse memory instead of repeatedly allocating and freeing.
A desireable solution would be if I could pass in the destination array when extracting the data, i.e.:
//During initialization
short[,] data = new short[xSize, ySize];
//Later, during acquisition
mSession.Acquisition.Extract(...).ToPixelArray(out data);
I know that call doesn't exist, but I wonder if there is a workaround for it.
My application can't afford to run the garbage collector during acquisition, so the goal is to allocate buffers before the start of acquisition and then reuse them.