08-05-2016 02:15 PM
Hi,
I have some machine vision cameras that produce noise images due to bit errors that can be cleaned up fairly well via a lookup table. Unfortunately my implementation of this correction in labview to to slow to keep up with the required frame rates. I know the computer is fast enough to apply these corrections and keep up with the frame, because we are able to do it in C with pointers.
The camera produces a 1024x1024 image with 4 adc's with different noise characteristics each multiplexed to every 4th pixel. Such that adc 1 sees pixel 1, 5,9.... adc 2 sees pixel 2,6,10....
In C we do the following:
for(jj=0;jj<totalpixels/4;jj++) {
*resultArray++ = *(lookupTable1 + *inputImage++);
*resultArray++ = *(lookupTable2 + *inputImage++);
*resultArray++ = *(lookupTable3 + *inputImage++);
*resultArray++ = *(lookupTable4 + *inputImage++);
}
In Labview the best I have been able to come up with is the following; and it is much to slow.
Is there a smarter/faster way to do this operation in labview?
08-05-2016 02:32 PM
Are you aware of the Interleave Arrays function?
Was it also too slow?
08-05-2016 02:50 PM
I am aware of the function, but I dont see how to use to do a lookup mapping.
08-05-2016 03:33 PM
I would try something like the attached snippet. I haven't benchmarked it but I'd be surprised if it's not faster than your version. You can probably speed it up further by enabling loop parallelization on the either loop (I'd do it on the outer loop).
08-05-2016 06:12 PM
Local variables also introduce some overhead in the read, especially when they are repeatedly read. Use something like a shift register to keep dataflow and optimize execution speed.
08-06-2016 03:04 AM - edited 08-06-2016 03:25 AM
Did you check Decimate 1D Array Elements : https://zone.ni.com/reference/en-XX/help/371361M-01/glang/decimate_1d_array/
Edit: No it doesn't work. When output array is 4 it does give deciimated array2->1, 5, 9, and 13... and
decimated array 3->2, 6, 10, and 14...,but your requirement is different though.
08-06-2016 08:37 AM
Typically in LabVIEW, pure array operations are much faster than autoindexing. And fixed loop with an autoindexed input is faster than just autoindexing. If I'm understanding your C code properly, this is one possible solution:
Like me, you probably don't like the 4 different adds. A cleaner way might be to simply interleave the lookup tables together and do the add all at once:
This code is based on my interpretation of your C code. Feel free to rebuff me if I missed something.
08-06-2016 09:28 AM
ijustlovemath - sorry, but you've completely misunderstood what the C code is doing. The C code uses pointer math to do array indexing. The *resultArray++ syntax moves to the next element of resultArray. It could be rewritten as (and yes, this code really does do the identical operation):
for(jj=0;jj<totalpixels/4;jj++) { resultArray[jj*4] = lookupTable1[inputImage[jj*4]]; resultArray[jj*4+1] = lookupTable2[inputImage[jj*4+1]]; resultArray[jj*4+2] = lookupTable3[inputImage[jj*4+2]]; resultArray[jj*4+3] = lookupTable4[inputImage[jj*4+3]]; }
If you look at this alternate but equivalent code, you'll see your LabVIEW code with the decimation/interleaving is completely different and doesn't produce a useful result.
08-06-2016 09:42 AM - edited 08-06-2016 10:01 AM
Thanks for the correction. I believe this will accomplish the task then:
There may be a way to accomplish this more succinctly using a 2D array reshape, but you would still have to index out individual rows of the resulting 2D array for the interleave. I also don't think there's a better way to accomplish the building of the arrays to interleave other than the autoindexed for loop, but again I could be wrong here. This is inherently more parallel, too, so you can take advantage of a little bit of multithreading.
Here's that 2D array approach:
08-08-2016 07:41 PM
Thanks for looking at my problem. Unfortunately this still isn't as fast as the C code and more importantly not fast enough to keep up with my frame rate.