01-28-2010 11:50 AM
Andrey
many thanks for reminding me the alignment gap. I will look carefully. attached is the user code from my colleague that I built the dll.
cheeers
Xiaofeng
01-28-2010 12:16 PM - edited 01-28-2010 12:22 PM
BlueCheese wrote:A better discussion would be to identify what shortcomings you see in the current IMAQ Centroid (in terms of options, functionality, precision, performance, etc) and which ones you consistently find yourself rolling your own implementation of. If these are common, there is no reason why we couldn't add them to a future version of Vision Development Module.
Well, IMAQ functions are pretty optimal, its true. What I missing for IMAQ Centroid there are two enhancement points:
- optimization for multiple cores (not all IMAQ functions are optimized for multi core. Especially centroid - not optimized yet)
- support for U16. This is missing. U8, I16, SGL are only supported.
- (optional) support thresholding inside of centroid - this may be useful.
Well, now back to our discussion.
For my implementation I have prepared pretty simple and straight forward code:
This function called in LabVIEW in that way:
Simple benchmarking and comparison with IMAQ Centroid:
And the results:
So, I've got the same result, but a little bit slow in comparison with NI. But 5-6 ms is not so bad for such image.
Here one core was used by both implementations. If you will run this example with lot of iterations, then you will se CPU load 50% on dual core PC
Now I'll try to add some steroids to my implementation.
I will rewrite function in that way:
Nothing special, - just input added for choosing upper half or bottom half of the image.
SubVI modified like this:
Two DLL calls will be performed in two threads, so both cores will be used (thanks, NI for this!).
An additional, I will calculate centroid outside of DLL based on accumulated values from two parts of the image.
Benchmark:
Who is winner? Now IMAQ Centroid needed roughly 6 ms for given image, and my VI - only 3,5. Nearby twice faster. It should be true also for other types U8/SGL.
Full sources and image in attachment. CVI was used for DLL, so you may need to install CVI 2009 Run-Time. Intel Compiler was used over CVI.
Also take a note, that "non-standard" method for passing image to DLL was used. Documented way is described two postings above.
with best regards,
Andrey.
PS
Ah,why I am not NI employee? 🙂
01-28-2010 12:29 PM
xgatc wrote:Andrey
many thanks for reminding me the alignment gap. I will look carefully. attached is the user code from my colleague that I built the dll.
cheeers
Xiaofeng
Welcome!
I see that your code nearby the same with my. Just add alignment (line width) correction and all will be OK.
Theoretically this algorithm can be speeded up for 16 bit images with moving from floating point to integer arithmetic, but this could be not very easy.
Andrey.
01-29-2010 06:50 AM
Andrey
thanks for your code. it is very helpful. I have not used NIVision.h and Image-datatype-to-Cluster.vi.
cheers
Xiaofeng
01-29-2010 10:47 AM
Andrey
Sorry to bother you again. I may send this twice, not sure if the last one went.
I was trying to rebuild my code , to have the similar arguments like in your MyCentroid.
but compiling my modified code failed after I included <nivision.h>. see the attached. Including <cvidef.h> still gave similar error. I don't have LabWindows/CVI, just use MinGW as I did before.
I wonder if you can point me to where :
Image_struct, CalibrationUnit, ImageType are defined in nivision.h.
what I like to test here is to copy
typedef struct ImageInfo_struct {
CalibrationUnit imageUnit;
float stepX;
float stepY;
ImageType imageType;
int xRes;
int yRes;
int xOffset;
int yOffset;
int border;
int pixelsPerLine;
void* reserved0;
void* reserved1;
void* imageStart;
} ImageInfo;
in my code and rebuild the dll with gcc.
I read one of your old post related to this, but still could not find the definition
Image_struct, CalibrationUnit, ImageType
cheers
Xiaofeng
01-29-2010 11:04 AM
It looks like NIVision.h included twice and all things redeclarated. Otherwise I can't help with MinGW. I have never used it.
cvidef.h is not necessary, nothing was used from CVI. The only NIVision.h is needed.
What you can do is following: stay away from passing image cluster to DLL and do it in "official" way: obtain pointer and linewidth with IMAQGetImagePixelPtr VI and pass these parameters to DLL as described above in message #9. Then NIVision.h will be not necessary for you.
Andrey.