LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Convert image to one dimensional radial array

Solved!
Go to solution

Hey everyone,

 

Thansk for taking the time to look at this. 

 

Here is the issue, the code I am running is working, but I think it could be made to run faster I am just not sure how to rewrite the algorithm to do so. I am taking an image (seen in screen shot, left panel top figure) that is symmetric about the center point. What I am trying to do is collapse all of the data in this image into a one dimensional array that is a radial representation of that image (screen shot, right panel top figure). The code I am currently using is seen in the bottom figure. One subtly that might be confusing is the multiple by 4 factor in the middle of the code, this was there when I started programming and I am assuming it is a scaling factor that is used to sort of spread the data over more array elements in the subsequence one dimensional array. As you can see the code is effectively working, but on average this operation is working on a 56x56 px image, so the code has to run 3136 times and I don't feel this is the most effiencient way possible, the code takes around 1 ms to run for a 56x56 px image on our machine. Please let me know if you have any suggestions on how to speed things up, this is half the bottle neck for our realtime analysis!

 

Thanks,

Joe

0 Kudos
Message 1 of 16
(5,126 Views)

Hi!

I tried to rearrange your loop by simplifying certain passages.

Try to see if it works, but I am not sure how faster it can run.

 

In the VI you also put a "Set up loop parallelism" label; since you are updating the same arrays through the shift registers the loop parallelism should not work.

MikeNuke, PhD

Politecnico di Milano
Department of Energy, Nuclear Engineering Division
0 Kudos
Message 2 of 16
(5,073 Views)

Maybe I'm missing the point, but if your Image is radially symmetric (which the example shown seems to be, until you get out a ways and other circles start appearing) and you know where the center (symmetry point) is located, all you have to do is simply take the values along the X axis from the Center to the Edge (outer radial distance you want to go) and you are done!  Being radially symmetric means it doesn't matter which radius you use, so why not use the most convenient one, the row that goes through the center of Symmetry?  This should take a microsecond or two, at most ...

 

Bob Schor

0 Kudos
Message 3 of 16
(5,068 Views)

Hi Mike,

 

Thanks for taking a look at my code, I actually can't see what changes you made though because I am still running labview 8.6. Would it be possible for you to post a reverted version or screenshot?

 

Hi Bob,

 

You got the right idea, that would give us a version of the radial representation. The problem is that if you only use this single row of pixels, you are throwing away almost all of your image data. The resultant radial profile will be extremely noisy in comparison to the case when you use all of the image data to generate the radial representation.

 

 

The reason I wrote loop parallelism in my code is because I was imagining that there is a way to rewrite the algorithm to run in a parallel loop, but that would require modifying how you save the radial value so you can get rid of the shift register.

 

Thanks for your help guys, I have a feeling that there is a way to rewrite the algorithm (entirely) to make this thing run much faster than it already is, but I am just at a loss on how to do that.

 

Best,

Joe 

0 Kudos
Message 4 of 16
(5,051 Views)
Solution
Accepted by topic author jowparks

 


jowparks wrote:

Hi Bob,

 

You got the right idea, that would give us a version of the radial representation. The problem is that if you only use this single row of pixels, you are throwing away almost all of your image data. The resultant radial profile will be extremely noisy in comparison to the case when you use all of the image data to generate the radial representation.

 

Thanks for your help guys, I have a feeling that there is a way to rewrite the algorithm (entirely) to make this thing run much faster than it already is, but I am just at a loss on how to do that. 


 


Joe,

 

     Good point.  So here's how to Have Your Pixels and Eat Them, Too.  Am I correct that you know the coordinates of the center of the Image?  For convenience, I'm going to call these coordinates O (for "origin").  I will also say you want the radial representation for distance R (in pixels).  Note that the coordinates of O do not necessarily need to be integers -- it can fall "between pixels".

 

     Here's what I would do.  I'm guessing this would be about as fast and as accurate/precise as is possible.  You basically want to use all the Pixels to come up with an R+1 Array of "average intensity" (instead of using the X-Axis sample as I suggested).  What you want to do is get the average of all Pixels distance 1 from the Origin, average of all Pixels distance 2, etc.  What a pain!

 

     So invert the problem.  Take all Pixels and compute their (rounded) distance from O and include them in computing that Average.  Oooh, how to do that?  What I'd do is to create an array of R+1 Queues to hold the Pixel values.  When you are examining Pixel-x-y, at distance r from O, enqueue the Pixel value into the Queue at index r (you skip the Pixel if r>R, of course).

 

     When you've processed all the Pixels within R of O, you'll have R+1 Queues with intensities from Pixels at distance r from O.  Simply replace the Array of Queues with an Array of Averages of each Queue.  The quick way to form the Average of a Queue is to Flush the Queue and retain its content (in an Array), then average the Array.  You now have (a) used every point in the Image, (b) taken into account its distance from O, and (c) computed averages to improve S/N, and you've done it pretty efficiently.

 

 

     This should be easy to code, and quick to run (I'll wager a dime it will beat any other algorithm suggested in the next 24 hours ...).

 

Bob Schor

Message 5 of 16
(5,042 Views)

This sounds like it is very close to what I have posted, except you use queues to save the values rather than a shift register. I think is exactly what I am looking for because it would allow me to use loop paralellism correct? Only problem is I have no idea how to use queues haha. I will try and do some reading, but is there a simple way to swap out my replace array subset function and shift registers with queues?

 

Thanks Bob, I think we on are the right track!

 

Joe

0 Kudos
Message 6 of 16
(5,026 Views)

I don't know how many radial lines you need, but I cooked up a quick example that ran in about 40us on my machine (closer to 100us when I added the graph). A better benchmark would be to run it many times with the front panel closed, but I'll "leave that exercise for the reader" as they say.

 

Average Radial Lines.png

0 Kudos
Message 7 of 16
(5,016 Views)
0 Kudos
Message 8 of 16
(5,008 Views)

Thanks for the detailed example greg. I should have made myself clear though, actually have to use the entire square image, and I have to use all the pixels within that square. Radius R was just meant to show the radial array that the pixels are meant to be binned to.

0 Kudos
Message 9 of 16
(4,998 Views)
Solution
Accepted by topic author jowparks

I tried coding up Bob's suggestion (correct me if I misinterpreted) and it was taking right around 1ms when I used a max radius of 25 pixels in a 56 x 56 array. I know jowparks is using LV 8.6 so he will still get the benefit of having to recreate this code if he wants to use it.  Smiley Very Happy

 

Average with Queues.png

Message 10 of 16
(4,984 Views)