Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

How can the ArrayToImage function be speeded up?

Hello,

 

I'm copying a video stream at 30Hz from a non-NI acquisition device to a CWIMAQViewer.  Every new frame triggers the ImageAvailable event and is available from the framegrabber either as a .NET Bitmap or a pointer to a byte[].  It appears that the fastest way to copy the frames to the viewer is via the ArrayToImage function.  If there is a better way, please let me know.

 

Please see the following post for more details:

http://forums.ni.com/ni/board/message?board.id=200&thread.id=23850

 

The challenge is that the ArrayToImage function takes 30-50ms to process the data which means that there is a substantial video lag when running at 30Hz.  I noticed that if I set Viewer.NonTearingDisplay to false that the time drops to about 12ms.  However, I really need to leave this option set to true because the display quality is unacceptable (lots of "tears") without it enabled.

 

What can be done (now or in future releases of the VDM) to improve the speed of the ArrayToImage function? 

 

Thanks,

Neville 

0 Kudos
Message 1 of 8
(4,787 Views)

Hi,

 

Are you sure that you lost most time in MainBufferImage.ArrayToImage(ImageBuffer2D);

 and not in Buffer.BlockCopy(ImageBuffer1D, 0, ImageBuffer2D, 0, ImageBuffer1D.Length * sizeof(byte));?

 

How big your image?

 

Andrey.

 

0 Kudos
Message 2 of 8
(4,782 Views)

Hi Neville ,

 

What is your application? What is your image size? Can you extract (and shrink) the data in other words can extracting only the needed area reduce your time further? Do you need the entire image?

0 Kudos
Message 3 of 8
(4,758 Views)

Hello Andrey and muks,

 

Andrey,  I'm sure it's not in the BlockCopy.  The BlockCopy takes about 0.5ms.

 

muks: I need to display full screen live video for an imaging application (moving a camera on a stage with a joystick).  The image size is 1024x768, but we're about to upgrade to a 3MP camera (2048x1536), which will make it all even worse, I'm sure.

 

Hopefully there's a way to speed it up. 

 

Neville 

0 Kudos
Message 4 of 8
(4,744 Views)

Hi,

 

If your BlockCopy so fast and IMAQArrayToImage so slow, then you can avoid such conversion: Get pointer to the memory where pixels located with IMAQ GetImagePixelPtr function and perform BlockCopy directly to the IMAQ Image.

IMPORTANT: your image should be created without Border! (Border=0). And this will work for images where line width the same with image width (as in your case for 1024 pixels).

 

Andrey.

 

Message 5 of 8
(4,741 Views)

Hello Andrey,

 

Very clever!  I'll look into it.  For the part where you talk about line width, I didn't fully understand what you were getting at.  Do you mean that the zoom factor should be 1:1 with my screen resolution (i.e., 1 image pixel to 1 screen pixel)?  Or did you mean something else?  I will need to have the ability for the user to zoom the live video stream somehow.


Thanks,

Neville 

0 Kudos
Message 6 of 8
(4,739 Views)

No, I mean if you will using direct access to the pixels, you shouls understand, how IMAQ Image placed in memory:

 

IMAQMem.png 

 

So, if you have width=1024 and Border=0, then LineWidth equal to Image width. Otherwise (for example image width = 1024, but border = 3, then you will get boder and gap between lines). Gap is necessary for alignment.

 

Andrey.

0 Kudos
Message 7 of 8
(4,734 Views)

Hi Andrey,


Thanks so much for explaining and for the image.  It was really helpful.  I have the border set to 0, so I think I'm good.

 

 

I tried finding IMAQ GetImagePixelPtr, but I couldn't find it. Can you please provide the full .NET funciton name?  What NI dlls do I need to include as references?

 

Thanks,

Neville 

0 Kudos
Message 8 of 8
(4,730 Views)