05-10-2016 02:30 PM
I would like to filter out erronous values from a "large (slightly more than 2000*2000) 2D array. These value emerge from a CCD sensor wich can produce very values on a single pixel.
It is easy to detect. My goal here is to replace these values by the average of the surrounding 4 pixels if the value is larger than a specified value (most of the time, the CCD is saturared so it would be the maximum of an N bit integer).
I am trying to run a 2 nested for loops, scanning every value of the array, testing and if required, replacing. I have a very low performance after a few iterations. I am most certainly doing something wrong but I never worked with large arrays before, so I'm probably not using the correct tools.
I am using Labview 2015.
Solved! Go to Solution.
05-10-2016 03:15 PM
Don't use the parallelism on your FOR loops. Use Shift Registers on your FOR loops. This way you are working with the array in place.
Other comments:
No need for the timeout. Delete it.
Make an event case for the Stop button's value change and put the stop button inside of it. That way you can properly stop the loop without polling.
05-10-2016 03:20 PM
Are you getting the output that you expect?
05-10-2016 03:36 PM
Does this vi work and really replace values? It looks like its output is always last iteration - bottom right corner of the picture. Where would result of inner iterations go?
Strange that labVIEW does not recognise this and executes all iterations, not only the last one.
It generates a number of loop instances (each one needs a copy of the array - here where all your time goes) then replaces one element in this array (or leaves it as it is) and discards the result.
As crossrulz said, remove parallelism, use shift register for main array.
May be it will be better to put comparison into the loop to avoid generating the same size boolean array.
You know your algorithm has troubles for bad points on the border and adjacent ones?
05-10-2016 03:38 PM - edited 05-10-2016 04:14 PM
In addition to what tim said:
05-10-2016 04:07 PM - edited 05-10-2016 04:45 PM
Since you need to create a new 2D array to use only unchanged, original pixels for the avaraging, I would just autoindex. See if this is any faster.
Do you have an example file?
(Code not tested, so make sure it works correctly...)
(EDIT: Sorry, I had the indices swapped incorrectly. I now attached a corrected version)
05-10-2016 04:18 PM - edited 05-10-2016 04:19 PM
Indeed the operation is done in 2-3 seconds on my desktop computer using shift registers.
Thanks for you help here.
I know the code is abolutely not optimized regarding boundary conditions, if 2 adjacent pixels are deffective and number of times I call Increment or Decrement, but it was a rapid VI I made on a test file that could not fail these tests. I will work on that but I know how do it it.
For what it's worth, here is what I have now, as a working solution.
05-10-2016 04:28 PM - edited 05-10-2016 05:23 PM
05-10-2016 05:19 PM
You solution works indeed, probably the most efficient yet. I have to try on real data but that's up to the experiment to work.
My detector gives me unsigned 16 bit values but the API from some instruments uses I32 so that's what I'm using.
05-10-2016 05:22 PM
@MF0088 wrote:You solution works indeed, probably the most efficient yet. I have to try on real data but that's up to the experiment to work.
My detector gives me unsigned 16 bit values but the API from some instruments uses I32 so that's what I'm using.
The "Out" array in your picture is I64 for some reason.