12-13-2010 11:49 AM - edited 12-13-2010 11:50 AM
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.
12-14-2010 10:53 AM
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.
12-15-2010 11:47 AM
I have a thorlabs camera, it does not seem to have an IMAQ adpater. Is it possible to write my own?
12-15-2010 12:13 PM - edited 12-15-2010 12:14 PM
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)?
12-15-2010 12:23 PM
Is this similar to what you were coding in the past? \
12-15-2010 02:08 PM
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.
12-15-2010 02:10 PM
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.
12-16-2010 01:32 PM - edited 12-16-2010 01:32 PM
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>
12-16-2010 02:22 PM
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 "
<Joel Khan | Applications Engineering | National Instruments | Rice University BSEE>
12-17-2010 11:41 AM
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,