





from typing import SupportsIndex

import numpy as np
from scipy.ndimage import convolve





def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	np.ndarray:
				lowerCamelCase									=np.stack((horizontal_flow, vertical_flow)      ,   2					)

				# Create a grid of all pixel coordinates and subtract the flow to get the
				# target pixels coordinates
				lowerCamelCase									=np.stack(
				    np.meshgrid(np.arange(0      ,   image.shape[1]					)      ,   np.arange(0      ,   image.shape[0]					)					)      ,   2					)
				lowerCamelCase									=np.round(grid - flow					).astype(np.intaa					)

				# Find the locations outside of the original image
				lowerCamelCase									=(grid < 0) | (grid >= np.array([image.shape[1], image.shape[0]]					))
				lowerCamelCase									=0

				lowerCamelCase									=image[grid[:, :, 1], grid[:, :, 0]]

				# Set pixels at invalid locations to 0
				lowerCamelCase									=0

				return warped





def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase = None      ,   )    ->	tuple[np.ndarray, np.ndarray]:





				if alpha is None:
								lowerCamelCase									=0.1

				# Initialize flow
				lowerCamelCase									=np.zeros_like(lowercase_					)
				lowerCamelCase									=np.zeros_like(lowercase_					)

				# Prepare kernels for the calculation of the derivatives and the average velocity
				lowerCamelCase									=np.array([[-1, 1], [-1, 1]]					) * 0.2_5
				lowerCamelCase									=np.array([[-1, -1], [1, 1]]					) * 0.2_5
				lowerCamelCase									=np.array([[1, 1], [1, 1]]					) * 0.2_5
				lowerCamelCase									=np.array(
				    [[1 / 12, 1 / 6, 1 / 12], [1 / 6, 0, 1 / 6], [1 / 12, 1 / 6, 1 / 12]]					)

				# Iteratively refine the flow
				for _ in range(lowercase_					):
								lowerCamelCase									=warp(lowercase_      ,   lowercase_      ,   lowercase_					)
								lowerCamelCase									=convolve(lowercase_      ,   lowercase_					) + convolve(lowercase_      ,   lowercase_					)
								lowerCamelCase									=convolve(lowercase_      ,   lowercase_					) + convolve(lowercase_      ,   lowercase_					)
								lowerCamelCase									=convolve(lowercase_      ,   lowercase_					) + convolve(lowercase_      ,   -kernel_t					)

								lowerCamelCase									=convolve(lowercase_      ,   lowercase_					)
								lowerCamelCase									=convolve(lowercase_      ,   lowercase_					)

								# This updates the flow as proposed in the paper (Step 12)
								lowerCamelCase									=(
								    derivative_x * avg_horizontal_velocity
								    + derivative_y * avg_vertical_velocity
								    + derivative_t
								)
								lowerCamelCase									=update / (alpha**2 + derivative_x**2 + derivative_y**2)

								lowerCamelCase									=avg_horizontal_velocity - derivative_x * update
								lowerCamelCase									=avg_vertical_velocity - derivative_y * update

				return horizontal_flow, vertical_flow


if __name__ == "__main__":
							import doctest

							doctest.testmod()








def   UpperCamelCase(   lowercase_				)      ->							str:





  '''simple docstring'''





  return "".join(chr(ord(lowercase_				) + 32				) if """A""" <= char <= """Z""" else char for char in word				)


if __name__ == "__main__":
    from doctest import testmod

    testmod()