08-01-2013 10:55 PM
First, let me share my rants... I'm really sick of this, I have the last couple of days without finding anything, the support service is not that aware of the .NET functionalities, my comapny paid for the NI Vision license but the support is not even able to tell me how to deal properly with the .NET libraries... the documentation is to me, not clear enough... (most of the time I have to refer to LabVIEW documentation and to compare whether first if the methods are matching and secondly to adapt them correcly to .NET).
I know that NI is mostly based on C & LabVIEW... but please do not forget .NET technologies!
Anyway. the topic is how to convert a VisionImage Object to a Bitmap / Image Object from the System.Drawing assembly. Here is the situation, I have to put several selection on some pictures through the ImageViewer and get from a camera.(here is also about the ImageViewer there is some troubles and would be good to talk deeply about this into another topic, badly coded, and not really not adaptable or customizable either).
Those pictures are used then as some patterns for performing analysis in real situations, the results (given by image processing to see if pictures from real scenes match expectations from the definitions defined previously) have then to be saved and displayed into a huge DataGridView / GridControl (DevExpress Control another third party libray in my project, Im not making advertising either, just for explaining...) so I cant really use the ImageViewer (first, it's really memory consuming to display it even by using a Server Mode (means only loaded ).
Imagine even 100 rows in table showing this component..., when especailly I already have .NET components doing this job pretty well but guess what they use Image / Bitmap Objects from System.Drawing assembly...
Most of people thinks about a I/O solution (basically it means you have your ObjectA, you export / save it to a file and then you load from this file to the other type of ObjectB (let's say) you wanted to convert... Obviously it takes time, poorly efficient (yes it works but we already have Object present in memory why the f***k we have to save them into a file just to load them into another file...).
I also give a try with the Serialization of the Bitmap / Image to Byte[] and Flatten and Unflatten methods, but do not work as well... The reason comes from that serialization is performed with the whole object not only about the pixel values... so it throws exceptions in both directions.
Another proposal given by some others and actually the first test I tried was to convert from Bitmap to VisionImage and vice-versa using a double loops system (or even a single one) by getting pixel and setting pixel... guess what it is incredibly slow too! The reason is quite simple, the getter / setter (in both Object's, Bitmap, Image and even VisionImage) are super slow cause they have to lock the memory to prevent from any memory leak, overflow or unmanaged tricky things... (safe and slow again...). I also tried to use the ArrayToImage methods or ImageToArray methods provided by the VisionImage Object but it all the same old song!
Then this solution to another one, is actually to get the pixels directly from the memoy, there are a couple articles / posts about it. First I have to say that's Im still wondering WHY adding alignment in a picture values would make it faster for image processing (except for a better dealing with border
?)
Why oh the h**s you NI chose to put border + alignments within the format of the ImageVision? To try to have power of 2 and bits shifting tricky things? Please explain, cause I'm really curious about that!
Anyway considering this:
By the way, I also did some revert engineering to better understand your VisionImage Object (located using NationalInstruments.Vision assembly) guy. Thanks http://ilspy.net/ but most of the Methods are in fact make calls to Imaq Library through the NiVision.dll, purely binary based (guess this one is coded with C or C++, cause performance matters). But I could saw some hidden members that was intentionally hidden! So why...?
(basically they are hidden in any Microsoft Visual Studio but if you are using another non-MS IDE (and that does exist!) like SharpDevelop you can see the sh*t behind), like some pointers, lineWidth).
One way conversion (VisionImage to Bitmap / Image) is pretty straightforward and does not required some wordaround... some of them on the website already found solution it is really functional, it can be found here... (but you have to dig a lot for that...) see the Sources below. But the other is complicated... first you have to find out the StartPtr, secondly you have to Copy the bytes extracted from LockBits / UnlockBits methods from the pointer of Bitmap / Image pointer to a manager array and then copy back to the StartPtr with the right length...
FYI, NI is supposed to provide easy-to-use (also called, "user-friendly) solutions and not pain-in-the-a** but when it's just a little not that NI Spirit (i.e. not LabVIEW related...) seems hard.
Would it be too hard for you guy to make some efforts? I usually do not like to loose my time for complaining, but when someone / company is paying for a product it/he/she has expectations... just do better a .NET job for the coming versions, thanks!
Sources:
http://forums.ni.com/t5/LabVIEW/on-IMAQ-ArraytoImage/m-p/1021897/highlight/true#M455529
https://decibel.ni.com/content/docs/DOC-15159
https://decibel.ni.com/content/docs/DOC-13140
https://decibel.ni.com/content/docs/DOC-15165
http://forums.ni.com/t5/Machine-Vision/How-can-the-ArrayToImage-function-be-speeded-up/td-p/952119