HornSchunck
Horn and Schunck variational optical flow algorithm.
Horn and Schunck variational optical flow algorithm.
Parameters
alpha : float. Defaults to 0.05.
Regularization gain.
iterations : int. Defaults to 1.
Number of iterations run to compute the optical flow.
float_precision : int. Defaults to ll.FloatPrecision.FP32.
Floating point precision used accross the algorithm. The outputs out_gray
and out_flow will be of this floating point precision.
clear_history : int. Defaults to 1.
If set to 1, the history of the optical flow is cleared before running the
algorithm on the next input image.
in_gray : ImageView
r8ui image. The input gray-scale image. It should contain valid image data before
initializing the node in order to avoid residual flow calculcations in the first
iterations of the algorithm.
Outputs
out_gray : ImageView
{r16f, r32f} image. The gray-scale image after one iteration of the algorithm.
The image format depends on the float_precision parameter.
out_flow : ImageView
{rg16f, rg32f} image. The estimated optical flow.
The image format depends on the float_precision parameter.
Examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| import lluvia as ll
import lluvia.util as ll_util
import matplotlib.pyplot as plt
# read two images as numpy arrays
frame_0 = ll_util.readRGBA('path to first image...')
frame_1 = ll_util.readRGBA('path to second image...')
# global session and memory objects
session = ll.createSession()
memory = session.createMemory(ll.MemoryPropertyFlagBits.DeviceLocal)
# this is the input of the comple pipeline
in_rgba = memory.createImageViewFromHost(frame_0)
RGBA2Gray = session.createComputeNode('lluvia/color/RGBA2Gray')
RGBA2Gray.bind('in_rgba', in_rgba)
RGBA2Gray.init()
RGBA2Gray.run() # run the node immediately in order to populate out_gray with valid values
in_gray = RGBA2Gray.getPort('out_gray')
HornSchunck = session.createContainerNode('lluvia/opticalflow/HornSchunck/HornSchunck')
HornSchunck.setParameter('alpha', ll.Parameter(0.05))
HornSchunck.setParameter('iterations', ll.Parameter(1000))
HornSchunck.setParameter('float_precision', ll.Parameter(ll.FloatPrecision.FP32.value))
HornSchunck.bind('in_gray', in_gray)
# when the node is initialized, it transfers the content of in_gray to out_gray.
HornSchunck.init()
out_gray = HornSchunck.getPort('out_gray')
out_flow = HornSchunck.getPort('out_flow')
flow2RGBA = session.createComputeNode('lluvia/viz/Flow2RGBA')
flow2RGBA.setParameter('max_flow', ll.Parameter(float(2)))
flow2RGBA.bind('in_flow', out_flow)
flow2RGBA.init()
out_flow_rgba = flow2RGBA.getPort('out_rgba')
duration = session.createDuration()
cmdBuffer = session.createCommandBuffer()
cmdBuffer.begin()
cmdBuffer.run(RGBA2Gray)
cmdBuffer.memoryBarrier()
cmdBuffer.durationStart(duration)
cmdBuffer.run(HornSchunck)
cmdBuffer.memoryBarrier()
cmdBuffer.durationEnd(duration)
cmdBuffer.run(flow2RGBA)
cmdBuffer.end()
# copy the content of the second frame to the in_rgba image before running the whole pipeline
in_rgba.fromHost(frame_1)
# run the pipeline
session.run(cmdBuffer)
# print runtime in milliseconds
print('{0:.02f} ms'.format(duration.nanoseconds / 1e6))
fig = plt.figure(figsize=(10, 6)); fig.set_tight_layout(True)
plt.subplot2grid((1,2), (0, 0)); plt.imshow(out_gray.toHost(), vmin=0, vmax=1, cmap='gray')
plt.subplot2grid((1,2), (0, 1)); plt.imshow(out_flow_rgba.toHost())
plt.show()
|