Skip to content

Commit 882793b

Browse files
committed
docs: add example of custom provided fields for DISCorrel
1 parent 1e7ac91 commit 882793b

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# coding: utf-8
2+
3+
"""
4+
This example demonstrates the use of the DISCorrel Block with user-provided
5+
fields. It does not require any hardware to run, but necessitates the
6+
opencv-python, matplotlib and Pillow modules to be installed.
7+
8+
This Block computes several fields on acquired images by performing dense
9+
inverse search on a given patch. It outputs the averages of the computed
10+
fields over the entire patch. The fields can be automatically generated, or
11+
provided by the user.
12+
13+
In this example, a fake strain is generated on a static image of a sample with
14+
a speckle. The level of strain is controlled by a Generator Block, and applied
15+
to the images by the DISCorrel Block. This same DISCorrel Block then calculates
16+
the strain on the images, based on both automatically-generated and
17+
user-provided fields, and outputs it to a Grapher Block for display.
18+
19+
After starting this script, the patch appears in the configuration window. Do
20+
not re-select a patch in the configuration window ! Instead, close the
21+
configuration window to start the test, and watch the strain be calculated in
22+
real time. This demo normally ends automatically after 2 minutes. You can also
23+
hit CTRL+C to stop it earlier, but it is not a clean way to stop Crappy.
24+
"""
25+
26+
import crappy
27+
import numpy as np
28+
29+
if __name__ == '__main__':
30+
31+
# Loading the example image of a speckle used for performing the image
32+
# correlation. This image is distributed with Crappy
33+
img = crappy.resources.speckle
34+
35+
# Building the custom fields to use for the correlation, as numpy arrays of
36+
# shape (patch_height, patch_width, 2)
37+
# Here, for the sake of demonstration, they correspond to the 'exx' and 'eyy'
38+
# fields that can be automatically generated by Crappy
39+
width = 128
40+
height = 128
41+
exx = np.stack((np.tile(np.linspace(-width / 200, width / 200, width,
42+
dtype=np.float32), (height, 1)),
43+
np.zeros((height, width), dtype=np.float32)), axis=2)
44+
eyy = np.stack((np.zeros((height, width), dtype=np.float32),
45+
np.swapaxes(np.tile(np.linspace(-height / 200, height / 200,
46+
height, dtype=np.float32),
47+
(width, 1)), 1, 0)), axis=2)
48+
49+
# The Generator Block that drives the fake strain on the image
50+
# It applies a cyclic strain that makes the image stretch in the x direction
51+
gen = crappy.blocks.Generator(
52+
# Using a CyclicRamp Path to generate cyclic linear stretching
53+
({'type': 'CyclicRamp',
54+
'speed1': 1, # Stretching at 1%/s
55+
'speed2': -1, # Relaxing at 1%/s
56+
'condition1': 'Exx(%)>20', # Stretching until 20% strain
57+
'condition2': 'Exx(%)<0', # Relaxing until 0% strain
58+
'cycles': 3, # The test stops after 3 cycles
59+
'init_value': 0},), # Mandatory to give as it's the first Path
60+
freq=50, # Lowering the default frequency because it's just a demo
61+
cmd_label='Exx(%)', # The generated signal corresponds to a strain
62+
63+
# Sticking to default for the other arguments
64+
)
65+
66+
# This DISCorrel Block calculates the strain of the image by performing dense
67+
# inverse search on the given patch
68+
# This Block is actually also the one that generates the fake strain on the
69+
# image, but that wouldn't be the case in real life
70+
# It takes the target strain as an input, and outputs the computed strain
71+
# Some fields to use are user-provided, but correspond to what would be
72+
# automatically generated by providing the value ('x', 'exx', 'eyy')
73+
disco = crappy.blocks.DISCorrel(
74+
'', # The name of Camera to open is ignored because image_generator is
75+
# given
76+
config=True, # Displaying the configuration window before starting,
77+
# mandatory if the patches to track ar not given as arguments
78+
display_images=True, # The displayer window will allow to follow the
79+
# patches on the speckle image
80+
freq=50, # Lowering the default frequency because it's just a demo
81+
save_images=False, # We don't want images to be recorded in this demo
82+
image_generator=crappy.tool.ApplyStrainToImage(img), # This argument
83+
# makes the Block generate fake strain on the given image, only useful
84+
# for demos
85+
patch=(193, 193, height, width), # Providing here the patch to follow
86+
fields=('x', 'y', exx, eyy), # The fields to compute on the acquired
87+
# images, some provided by the user as numpy arrays, some generated
88+
# automatically from strings
89+
# The labels for sending the calculated strain to downstream Blocks
90+
labels=('t(s)', 'meta', 'disp_x', 'disp_y', 'Exx(%)', 'Eyy(%)'),
91+
92+
# Sticking to default for the other arguments
93+
)
94+
95+
# This Grapher displays the extension as computed by the DISCorrel Block
96+
graph = crappy.blocks.Grapher(('t(s)', 'Exx(%)'))
97+
98+
# Linking the Blocks together so that each one sends and received the correct
99+
# information
100+
# The Generator drives the DISCorrel, but also takes decision based on its
101+
# feedback
102+
crappy.link(gen, disco)
103+
crappy.link(disco, gen)
104+
crappy.link(disco, graph)
105+
106+
# Mandatory line for starting the test, this call is blocking
107+
crappy.start()

0 commit comments

Comments
 (0)