public class PIV_analyser extends Object implements ij.plugin.filter.PlugInFilter
See the book Raffael, M.; Willert, C. & Kompenhans, J. (2007), Particle Image Velocimetry: A Practical Guide (2nd ed.), Berlin: Springer-Verlag, ISBN 978-3-540-72307-3
PIV analysis is based on inferring in what direction and in what amount a part of an image has moved between two successive instant. In the aforementioned domains, a flow is visualized by seeding it with light-reflecting particle (smoke in air, bubbles, glass beads in water, ...) and imaged at two very close instant. The cross-correlation between parts of the two images where pattern generated by particles can be seen is then used to compute the velocity field.
The PIV algorithm is made of the following steps:
Typically, on a MacBook (grey model, 2009), for an 8-bit stack with a window size of 8x8, the plugin, the plugin can process a stack of 200x200 in approximatively 2 seconds. I recommend downsampling the images, this would diminish the density of results, but make this plugin affordable.
PIV is based on a very simple pattern matching algorithm. This means that, to be effective, there must be some patterns in your image. Typically, the dotty structures of aggregate in a epi-fluorescence movie or the granularity that can be see on a brightfield image will do. As a rule of thumb if you can see something moving by eye, the PIV might be able to get it quantitatively; otherwise not of course.
Also keep in mind that (so far) it works only for a 2D plane. With optical sections, the algorithm might become puzzled by the appearance of grains moving in the Z direction. Also with thick specimen imaged in brightfield: the image of a dot deforms while moving in Z, which may lead to irrelevant values.
Let us suppose that one one image, some structure can be found in the shape of 'grains' whose size is about 10-15 pixels. To always get at least a full one, a window of 32x32 pixels would be relevant.
One can recommend to filter temporally, that is: for every vector in the field, replace its value by the moving average from a few frames before until a few frames after. If your movie is oversampled temporally, that might be effective in averaging outliers.
The peak height is just the value of the correlation peak for each pixels. This can be used to mask irrelevant part of the result image. The algorithm will be typically puzzled where there is no structure to correlate. In these parts of the image, the peak height will be typically low; one can then threshold the peak height image, and use it to mask the result image.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifier and Type | Class and Description |
---|---|
protected class |
PIV_analyser.PairingParam
Utility class used to store parameters specifying how to pair images
for PIV analysis.
|
protected class |
PIV_analyser.PIVresult
Utility class used to store flow vector at each point.
|
static class |
PIV_analyser.WINDOW_SIZE
Enumeration constant that stores all possible window size for this plugin.
|
CONVERT_TO_FLOAT, DOES_16, DOES_32, DOES_8C, DOES_8G, DOES_ALL, DOES_RGB, DOES_STACKS, DONE, FINAL_PROCESSING, KEEP_THRESHOLD, NO_CHANGES, NO_IMAGE_REQUIRED, NO_UNDO, NO_UNDO_RESET, PARALLELIZE_IMAGES, PARALLELIZE_STACKS, ROI_REQUIRED, SNAPSHOT, STACK_REQUIRED, SUPPORTS_MASKING
Constructor and Description |
---|
PIV_analyser() |
Modifier and Type | Method and Description |
---|---|
static void |
colorCircle(ij.process.ColorProcessor ip)
Generate a color circle that shows the mapping between color and
orientation, to use in conjunction with
colorVector(float, float, float) . |
protected static int |
colorVector(float xs,
float ys,
float maxDistance)
Returns an int that encodes for a color describing the orientation of the
vector whose coordinates are given in argument.
|
static void |
displayColorCircle(float maxDisplacement) |
ij.ImagePlus[] |
exec(boolean show_calculation)
Executes the calculation for the value passed to this plugin's fields.
|
PIV_analyser.PIVresult |
findMax(ij.process.FHT pcm,
boolean interpolate)
Finds the maximum location in a correlation matrix.
|
int[][] |
getImagePairs() |
boolean |
getInterpolation() |
static float |
getMax(float[][] arr) |
int[] |
getWinsize() |
void |
run(ij.process.ImageProcessor ip)
Generate a generic dialog for the user to parameterize this plugin.
|
void |
setImagePairs(int[][] image_pairs)
Specifies on what pair of images to do the analysis.
|
void |
setInterpolation(boolean doit)
If set to true, the vector flow will be interpolated to get a sub-pixel
accuracy, using a Taylor expansion on a 3x3 neighborhood around the
maximum position.
|
int |
setup(String arg,
ij.ImagePlus imp)
Sets the ImagePlus that this plugin should analyze.
|
void |
setWinsize(PIV_analyser.WINDOW_SIZE ws)
Sets the size of the interrogation window for the analysis.
|
static void |
startAndJoin(Thread[] threads)
Start all given threads and wait on each of them until all are done.
|
public int setup(String arg, ij.ImagePlus imp)
setup
in interface ij.plugin.filter.PlugInFilter
arg
- Ignoredimp
- The ImagePlus to analyzepublic void run(ij.process.ImageProcessor ip)
run
in interface ij.plugin.filter.PlugInFilter
public final ij.ImagePlus[] exec(boolean show_calculation)
show_calculation
- If true, results will be displayed during calculationsetup
,
setImagePairs
,
setWinsize
,
setInterpolation
public final PIV_analyser.PIVresult findMax(ij.process.FHT pcm, boolean interpolate)
If the flag interpolate is set to true, the maximum location will be interpolated (to get sub-pixel accuracy) using a Taylor expansion over a 3x3 neighborhood around the maxima. The peak value (non-interpolated) is returned for futher filtering purpose. So far, there is no estimation of the signal/noise ratio calculated.
pcm
- The correlation matrixinterpolate
- Boolean flagFHT
,
PIV_analyser.PIVresult
protected static final int colorVector(float xs, float ys, float maxDistance)
Taken from Stephan Saalfeld Optic_Flow.java plugin.
xs
- The X coordinate of the vectorys
- The Y coordinate of the vectormaxDistance
- The max expected length of a vectorpublic static final void colorCircle(ij.process.ColorProcessor ip)
colorVector(float, float, float)
.
Taken and modified from Stephan Saalfeld Optic_Flow.java plugin.
ip
- The ImageProcessor to draw the color circle inpublic static final void displayColorCircle(float maxDisplacement)
public static void startAndJoin(Thread[] threads)
public static final float getMax(float[][] arr)
public void setImagePairs(int[][] image_pairs)
image_pairs
- The nx2 array of int specifying the image pairs.public int[][] getImagePairs()
public void setWinsize(PIV_analyser.WINDOW_SIZE ws)
ws
- The window size, specified by an enumpublic int[] getWinsize()
public void setInterpolation(boolean doit)
doit
- The boolean flagpublic boolean getInterpolation()
Copyright © 2015–2021 Fiji. All rights reserved.