Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

How to get around extremely slow ArrayToImage call

I am trying to build a simple application to capture images from a camera and place them on the screen.  The camera is not set up to be used from IMAQ directly, so I must acquire an image as a bitmap, transform the bitmap into an array and then use ArrayToImage to convert the image to IMAQ. 

 

This is horribly slow and drops the frame rate down to 1-6 frames per second.  With very little work I determined that the ArrayToImage function is where the bottleneck is and that it cannot process the data correctly.

 

So I have two questions, 

1.  Is there a way to do a Bitmap to Imaq image conversion.  I cannot understand why this is not a function call already.

 

2.  Is it possible to bypass the slow ArrayToImage call and just copy the memory block into the IMAQ image without having to use the array functionality.  I.e. Using CopyMemory, or buffer.blockcopy.   These calls are more than fast enough to handle 80-100 fps applications. 

 

I have been digging into the c++ code for vision, but it seems that the imaqImage class is setup for the .Net applications so I am a little lost.  Thanks for any help.

0 Kudos
Message 1 of 11
(5,055 Views)

What kind of camera do you have? It would probably be easiest to set up the camera to work with IMAQ or IMAQdx than to figure out a workaround. 


0 Kudos
Message 2 of 11
(5,031 Views)

I have a thorlabs camera, it does not seem to have an IMAQ adpater.  Is it possible to write my own?

0 Kudos
Message 3 of 11
(5,017 Views)

By IMAQ adapter I am assuming you mean IMAQ camera file. Your thorlabs camera is a camera link or parallel digital camera (these use NI-IMAQ)? Or is it firewire/ gigE/ USB (these use NI-IMAQdx)? 

 

 


0 Kudos
Message 4 of 11
(5,014 Views)

Is this similar to what you were coding in the past? ArraytoImage.png\

 


0 Kudos
Message 5 of 11
(5,011 Views)

I am refering to the ArrayToImage call that is available with the COM component in Measurement studio.  The images that are acquired a very large , ~1000X1000 pixels and the ArrayToImage call just chokes on this reducing the frame rate to almost nothing. 

 

If I send the same image into ArrayToImage in labview, I can get a decent frame rate.  If I use NIVision.dll calls, I can get a really good frame rate, but the COM step is just way too slow.  I assume from indexing the variant array.  (indexing the array to send the image in is also a major hit in performance)

 

Is there any way to access the CWIMAQImage to send that data that does not involve sending the data accross a COM link in a safearray?  We would really like to be able to use the IMAQImageview in our C# application.

0 Kudos
Message 6 of 11
(5,005 Views)

The camera is a USB camera, but does not register itself as a directshow camera.  I have not found a way to get over this obstacle.  IMAQdx does not find the camera.

0 Kudos
Message 7 of 11
(5,004 Views)

Hey Ochensati,

 

I am sorry I did not understand your question from the get go. Thanks for clarifying. My knowledge on this issue is directed more towards NI Vision/ Vision Development while in LabVIEW. I am not sure why you would be seeing a difference in behavior between ArrayToImage in C# and in LabVIEW. It seems that you already have some good ideas about why this might be. I hope somebody from the community with product knowledge in C# could enlighten us. I am sorry I was not of more assistance.

 

Meanwhile, I will look into this with some of my colleagues.It would be benefitial for anybody reading this forum to see your code.

 

<Joel Khan | Applications Engineering | National Instruments | Rice University BSEE>


0 Kudos
Message 8 of 11
(4,981 Views)

Ochensati,

 

I did more research on your issue and discovered that sometimes it is necessary to install all the software for the USB camera for IMAQdx to start comunicating with a camera. If the camera is completely uncompatible with directshow then the only real way to communicate with the camera is how you have been doing it (through the .dll call). We are unsure of what you mean by COM you are refering to, this usually is in relation to serial ports so it is kind of confusing.

 

As for your question on "

Is there any way to access the CWIMAQImage to send that data that does not involve sending the data accross a COM link in a safearray? We would really like to be able to use the IMAQImageview in our C# application.  

"

It is important that you look at the Vision text based examples, the vision.net examples include one which just reads an image and displays it.

C:\Program Files\National Instruments\Vision\Examples\dotNET

   

 

<Joel Khan | Applications Engineering | National Instruments | Rice University BSEE>

 


0 Kudos
Message 9 of 11
(4,974 Views)

Hi  ochensati,

 

I ran into the same problem a couple of weeks ago. I try to stay away from the IMAQ drivers so i can access the camera from another forms and use .net controls and not activex controls; I use the directshow drivers for the camera and the camera rate is 30fps.

 

Basically the code that i have has a callback everytime that a new frame arrives. Then from that function I create a new delegate that will handle the new frame. The delegate calls another function that saves the image to the hard drive and then loads the image into the control  (for some reason copying the image to the clipboard and loading it did not work, which would be a lot faster, but ...)

 

here is the code:

 

//callback for the new frame:

private delegate void imageHandler(Image image);

void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            try
            {
                //lock (this)
                {
                    Image b;
                    b = (Image)eventArgs.Frame.Clone();
                    this.frameSize = eventArgs.Frame.Size;
                    Invoke(new imageHandler(this.Form1_imageChanged), b);
                }
            }
            catch (Exception)
            {
                //throw;
            }
       }


//function to handle the new image

 void Form1_imageChanged(Image image)
        {
            try
            {
                //Clipboard.SetImage(image);
                //image.Dispose();
                
                //bool copyOk = false;
                //this.axCWIMAQVision1.ReadImageFromClipboard(this.axCWIMAQViewer1.Image, ref copyOk, axCWIMAQViewer1.Palette);

                image.Save("C:\\temp\\temp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                image.Dispose();
                this.axCWIMAQVision1.ReadImage(this.axCWIMAQViewer1.Image, "C:\\temp\\temp.jpg", axCWIMAQViewer1.Palette);

            }
            catch (Exception)
            {
                //throw;
            }
        }


 

 

 

Hope it helps, let me know if you find a solution to copy it to and from the clipboard.

 

Regards,

 

0 Kudos
Message 10 of 11
(4,960 Views)