




from typing import SupportsIndex

import numpy as np
from scipy.ndimage import convolve


def 							__SCREAMING_SNAKE_CASE  (      snake_case_     ,   snake_case_     ,   snake_case_						):

						'''simple docstring'''


						_UpperCAmelCase													=					np.stack((horizontal_flow, vertical_flow)     ,   2						)

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

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

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

						# Set pixels at invalid locations to 0
						_UpperCAmelCase													=					0

						return warped


def 							__SCREAMING_SNAKE_CASE  (      snake_case_     ,   snake_case_     ,   snake_case_     ,   snake_case_ = None     ,   ):

						'''simple docstring'''


						if alpha is None:
												_UpperCAmelCase													=					0.1

						# Initialize flow
						_UpperCAmelCase													=					np.zeros_like(snake_case_						)
						_UpperCAmelCase													=					np.zeros_like(snake_case_						)

						# Prepare kernels for the calculation of the derivatives and the average velocity
						_UpperCAmelCase													=					np.array([[-1, 1], [-1, 1]]						) * 0.25
						_UpperCAmelCase													=					np.array([[-1, -1], [1, 1]]						) * 0.25
						_UpperCAmelCase													=					np.array([[1, 1], [1, 1]]						) * 0.25
						_UpperCAmelCase													=					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(snake_case_						):
												_UpperCAmelCase													=					warp(snake_case_     ,   snake_case_     ,   snake_case_						)
												_UpperCAmelCase													=					convolve(snake_case_     ,   snake_case_						) + convolve(snake_case_     ,   snake_case_						)
												_UpperCAmelCase													=					convolve(snake_case_     ,   snake_case_						) + convolve(snake_case_     ,   snake_case_						)
												_UpperCAmelCase													=					convolve(snake_case_     ,   snake_case_						) + convolve(snake_case_     ,   -kernel_t						)

												_UpperCAmelCase													=					convolve(snake_case_     ,   snake_case_						)
												_UpperCAmelCase													=					convolve(snake_case_     ,   snake_case_						)

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

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

						return horizontal_flow, vertical_flow


if __name__ == "__main__":
				import doctest

				doctest.testmod()










from __future__ import annotations


def 							__SCREAMING_SNAKE_CASE  (      snake_case_						):

						'''simple docstring'''


						if len(snake_case_						) == 0:
												raise ValueError("find_max() arg is an empty sequence"						)
						_UpperCAmelCase													=					nums[0]
						for x in nums:
												if x > max_num:
																		_UpperCAmelCase													=					x
						return max_num


if __name__ == "__main__":
				import doctest

				doctest.testmod(verbose=True)




