Skip to content

Commit

Permalink
Merge pull request #309 from alexlib/master
Browse files Browse the repository at this point in the history
tested simple_multipass
  • Loading branch information
alexlib authored Mar 7, 2024
2 parents 61a67dd + 66270e3 commit a0aac93
Show file tree
Hide file tree
Showing 5 changed files with 338 additions and 189 deletions.
48 changes: 25 additions & 23 deletions openpiv/test/test_process.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""" Testing basic PIV processes """
import numpy as np
import matplotlib.pyplot as plt
from skimage.util import random_noise
from skimage import img_as_ubyte
from scipy.ndimage import shift as shift_img
Expand All @@ -8,9 +8,11 @@
from openpiv.pyprocess import extended_search_area_piv as piv
from openpiv.pyprocess import fft_correlate_images, \
correlation_to_displacement
from openpiv import tools


threshold = 0.25

THRESHOLD = 0.25

# define "PIV" shift, i.e. creating u,v values that we want to get
# -5.5 pixels to the left and 3.2 pixels upwards
Expand All @@ -19,18 +21,18 @@
# the second value is 1 pixel positive to the right
# shifted_digit_image=shift(some_digit_image,[2,1])
# so we expect to get later
# shift(image, [-1*shift_v, shift_u])
# shift(image, [-1*SHIFT_V, SHIFT_U])


# <------
shift_u = -3.5 # shift to the left, should be placed in columns, axis=1
SHIFT_U = -3.5 # shift to the left, should be placed in columns, axis=1
# ^
# |
# |
shift_v = 2.5 # shift upwards, should be placed in rows, axis=0
SHIFT_V = 2.5 # shift upwards, should be placed in rows, axis=0


def create_pair(image_size=32, u=shift_u, v=shift_v):
def create_pair(image_size=32, u=SHIFT_U, v=SHIFT_V):
""" creates a pair of images with a roll/shift """
frame_a = np.zeros((image_size, image_size))
frame_a = random_noise(frame_a)
Expand Down Expand Up @@ -60,16 +62,16 @@ def test_piv():
# extended_search_area_piv returns image based coordinate system
u, v, _ = piv(frame_a, frame_b, window_size=32)
print(u, v)
assert np.allclose(u, shift_u, atol=threshold)
assert np.allclose(v, shift_v, atol=threshold)
assert np.allclose(u, SHIFT_U, atol=THRESHOLD)
assert np.allclose(v, SHIFT_V, atol=THRESHOLD)


def test_piv_smaller_window():
""" test of the search area larger than the window """
frame_a, frame_b = create_pair(image_size=32, u=-3.5, v=-2.1)
u, v, _ = piv(frame_a, frame_b, window_size=16, search_area_size=32)
assert np.allclose(u, -3.5, atol=threshold)
assert np.allclose(v, -2.1, atol=threshold)
assert np.allclose(u, -3.5, atol=THRESHOLD)
assert np.allclose(v, -2.1, atol=THRESHOLD)


def test_extended_search_area():
Expand All @@ -80,10 +82,10 @@ def test_extended_search_area():
search_area_size=32,
overlap=0)

assert np.allclose(u, -3.5, atol=threshold)
assert np.allclose(v, -2.1, atol=threshold)
# assert dist(u, shift_u) < threshold
# assert dist(v, shift_v) < threshold
assert np.allclose(u, -3.5, atol=THRESHOLD)
assert np.allclose(v, -2.1, atol=THRESHOLD)
# assert dist(u, SHIFT_U) < THRESHOLD
# assert dist(v, SHIFT_V) < THRESHOLD


def test_extended_search_area_overlap():
Expand All @@ -94,8 +96,8 @@ def test_extended_search_area_overlap():
search_area_size=32,
overlap=8)
print(f"\n u={u}\n v={v}\n")
assert np.allclose(u, shift_u, atol=threshold)
assert np.allclose(v, shift_v, atol=threshold)
assert np.allclose(u, SHIFT_U, atol=THRESHOLD)
assert np.allclose(v, SHIFT_V, atol=THRESHOLD)


def test_extended_search_area_sig2noise():
Expand All @@ -110,8 +112,8 @@ def test_extended_search_area_sig2noise():
subpixel_method="gaussian"
)

assert np.allclose(u, -3.5, atol=threshold)
assert np.allclose(v, 2.1, atol=threshold)
assert np.allclose(u, -3.5, atol=THRESHOLD)
assert np.allclose(v, 2.1, atol=THRESHOLD)


def test_process_extended_search_area():
Expand All @@ -120,13 +122,12 @@ def test_process_extended_search_area():
u, v, _ = piv(frame_a, frame_b, window_size=16,
search_area_size=32, dt=2., overlap=0)

assert np.allclose(u, shift_u/2., atol=threshold)
assert np.allclose(v, shift_v/2., atol=threshold)
assert np.allclose(u, SHIFT_U/2., atol=THRESHOLD)
assert np.allclose(v, SHIFT_V/2., atol=THRESHOLD)


def test_sig2noise_ratio():
""" s2n ratio test """
from openpiv import tools
im1 = files('openpiv.data').joinpath('test1/exp1_001_a.bmp')
im2 = files('openpiv.data').joinpath('test1/exp1_001_b.bmp')

Expand All @@ -148,9 +149,10 @@ def test_sig2noise_ratio():


def test_fft_correlate():
""" test of the fft correlation """
frame_a, frame_b = create_pair(image_size=32)
corr = fft_correlate_images(frame_a, frame_b)
u, v = correlation_to_displacement(corr[np.newaxis, ...], 1, 1)
assert np.allclose(u, shift_u, atol=threshold)
assert np.allclose(v, shift_v, atol=threshold)
assert np.allclose(u, SHIFT_U, atol=THRESHOLD)
assert np.allclose(v, SHIFT_V, atol=THRESHOLD)

113 changes: 52 additions & 61 deletions openpiv/test/test_validation.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,56 @@
""" Testing validation functions """
from typing import Tuple
import numpy as np
from importlib_resources import files

from openpiv.pyprocess import extended_search_area_piv as piv
from openpiv.tools import imread
import pathlib

import numpy as np
from .test_process import create_pair, shift_u, shift_v, threshold
from openpiv import validation

from scipy.ndimage import generic_filter, median_filter
from scipy.signal import convolve2d

import matplotlib.pyplot as plt
from typing import List, Tuple
import numpy.typing as npt


file_a = pathlib.Path(__file__).parent / '../data/test1/exp1_001_a.bmp'
file_b = pathlib.Path(__file__).parent / '../data/test1/exp1_001_b.bmp'
file_a = files('openpiv.data').joinpath('test1/exp1_001_a.bmp')
file_b = files('openpiv.data').joinpath('test1/exp1_001_b.bmp')

frame_a = imread(file_a)
frame_b = imread(file_b)

frame_a = frame_a[:32,:32]
frame_b = frame_b[:32,:32]
frame_a = frame_a[:32, :32]
frame_b = frame_b[:32, :32]


def test_validation_peak2mean():
"""test of the simplest PIV run
default window_size = 32
"""
_, _, s2n = piv(frame_a, frame_b,
window_size=32,
_, _, s2n = piv(frame_a, frame_b,
window_size=32,
sig2noise_method="peak2mean")

assert np.allclose(s2n.min(),1.443882)
assert np.allclose(s2n.min(), 1.443882)


def test_validation_peak2peak():
"""test of the simplest PIV run
default window_size = 32
"""
_, _, s2n = piv(frame_a, frame_b,
window_size=32,
_, _, s2n = piv(frame_a, frame_b,
window_size=32,
sig2noise_method="peak2peak")
assert np.allclose(np.min(s2n), 1.24009)


def test_sig2noise_val():
""" tests sig2noise validation """
u = np.ones((5,5))
v = np.ones((5,5))
u = np.ones((5, 5))
v = np.ones((5, 5))
s2n_threshold = 1.05
s2n = np.ones((5,5))*s2n_threshold
s2n[2,2] -= 0.1
s2n = np.ones((5, 5))*s2n_threshold
s2n[2, 2] -= 0.1

mask = s2n < s2n_threshold

assert not mask[0,0] # should be False
assert mask[2,2]

assert not mask[0, 0] # should be False
assert mask[2, 2]


def test_local_median_validation(u_threshold=3, N=3):
Expand All @@ -66,49 +61,46 @@ def test_local_median_validation(u_threshold=3, N=3):
N (int, optional): _description_. Defaults to 3.
size (int, optional): _description_. Defaults to 1.
"""

u = np.random.rand(2*N+1, 2*N+1)
u[N,N] = np.median(u)*10


u = np.random.rand(2*N+1, 2*N+1)
u[N, N] = np.median(u)*10

# and masked array copy
u = np.ma.copy(u)
u[N+1:,N+1:-1] = np.ma.masked
u[N+1:, N+1:-1] = np.ma.masked

# now we test our function which is just a decoration
# now we test our function which is just a decoration
# of the above steps
flag = validation.local_median_val(u,u,u_threshold,u_threshold)
flag = validation.local_median_val(u, u, u_threshold, u_threshold)

assert flag[N, N]

assert flag[N,N]

def test_global_val():
""" tests global validation
"""
N: int=2
U: Tuple[int,int]=(-10,10)
N: int = 2
U: Tuple[int, int] = (-10, 10)

u = np.random.rand(2*N+1, 2*N+1)
u[N, N] = U[0]-.2
u[0,0] = U[1]+.2
u[0, 0] = U[1]+.2

u = np.ma.copy(u)
v = np.ma.copy(u)
v[N+1,N+1] = np.ma.masked
v[N+1, N+1] = np.ma.masked

mask = validation.global_val(u,u,U,U)
mask = validation.global_val(u, u, U, U)

assert mask[N,N]
assert mask[0,0]
assert mask[N, N]
assert mask[0, 0]

# masked array test

mask1 = validation.global_val(v, v, U, U)


mask1 = validation.global_val(v,v,U,U)

assert mask1[N,N]
assert mask1[0,0]
assert mask1[N, N]
assert mask1[0, 0]


def test_global_std():
Expand All @@ -126,32 +118,31 @@ def test_global_std():
# print(np.nanstd(u))

u[N, N] = 10.
u[0,0] = -10.
u[0, 0] = -10.

v = np.ma.copy(u)
v[N+1,N+1] = np.ma.masked

v[N+1, N+1] = np.ma.masked

mask = validation.global_std(u, u, 3)

assert mask[N,N]
assert mask[0,0]
assert mask[N, N]
assert mask[0, 0]

mask1 = validation.global_std(v, v, std_threshold=3)

assert mask1[N,N]
assert mask1[0,0]
assert mask1[N, N]
assert mask1[0, 0]

def test_uniform_shift_std(N: int=2):

def test_uniform_shift_std(N: int = 2):
""" test for uniform shift """
u = np.ones((2*N+1, 2*N+1))
v = np.ma.copy(u)
v[N+1,N+1] = np.ma.masked
v[N+1, N+1] = np.ma.masked

mask = validation.global_std(u, u, std_threshold=3)

assert ~mask[N,N]

assert ~mask[N, N]

# print(f'v.data \n {v.data}')
# print(f'v before \n {v}')
Expand All @@ -160,5 +151,5 @@ def test_uniform_shift_std(N: int=2):

v[mask1] = np.ma.masked

assert v.data[N,N] == 1.0
assert v.mask[N+1,N+1]
assert v.data[N, N] == 1.0
assert v.mask[N+1, N+1]
Loading

0 comments on commit a0aac93

Please sign in to comment.