\documentclass[10pt]{beamer}
% \mode<presentation>{\usetheme{Warsaw}}%Boadilla Antibes Singapore Hannover Madrid
\usetheme{Warsaw}
\usepackage{amsmath,amssymb,latexsym,enumerate}
\usepackage{longtable}
\title{Solution to Attribute-Based Assignment Problems}
\subtitle{A Primer to the University Timetabling Problem}
\author{\textbf{Folarin, Wasiu Jr.}\\ MTH/2014/014}
\institute{\textbf{Dr. B. S. Ogundare}\\ \textit{Supervisor}}
\date{\today}
\logo{\includegraphics[height=0.5cm]{figures/oau.png}}
\begin{document}
	\begin{frame}
		\titlepage
	\end{frame}

	\begin{frame}
		\frametitle{Outline}
		\tableofcontents
	\end{frame}

	\section{Introduction}
		\subsection{Objective}
			\begin{frame}
				\frametitle{Introduction}
				\begin{block}{Claim}
					Given any set of objects $U = \{u_1, u_2,...,u_n\}$ each possessing certain attributes, and a set of constraining conditions for assignment, we can:
					\begin{enumerate}
						\item Construct functions describing those constraints
						\item Assign each object to a class of best fit
					\end{enumerate}
				\end{block}
			\end{frame}

		\subsection{Core Concepts}
			\begin{frame}
				\frametitle{The Nature of Attributes}
				\begin{definition}
					An Attribute is any characteristic of a group of objects that can serve as a basis for classification
				\end{definition}
				\begin{example}
					\begin{itemize}
						\item Age
						\item State of Origin
						\item Courses offered in a semester
						\item Body mass
						\item O'Level Results
						\item etc...
					\end{itemize}
				\end{example}
			\end{frame}
			\begin{frame}
				\frametitle{Partitions}
				\begin{definition}
					A Partition, is a classification of objects based on an \underline{ideal value} of one or more \texttt{attributes}
				\end{definition}
				\begin{example}
					\begin{itemize}
						\item Teens, Young Adults,... (based on the Age attribute of objects)
						\item Hausa, Igbo, Yoruba,... (based on the State of Origin attribute)
						\item etc...
					\end{itemize}
				\end{example}
			\end{frame}
			\begin{frame}
				\frametitle{Constraints}
				\vfill
				\begin{definition}<1->
					A Constraint function, $\mu$, matches the \underline{Ideal value} of a partition, $p_i$, to the \texttt{attribute} value of an object, $u_j$, and assigns a membership value viz:
					\begin{align}
						\mu(p_i,u_j) &\mapsto [0,1] \textit{\ \ \  i,j $\in \mathbf{Z}$ }\notag
					\end{align}

				\end{definition}
				\vfill
			\end{frame}

			\begin{frame}
				\frametitle{Classes of Constraints}
				\vfill
				\begin{definition}<1->
					\begin{itemize}
						\item \textbf{Binary Constraints} assign a membership value $v \in \{0,1\}$ to each object
						\item \textbf{Continuous Constraints} assign a membership value $v \in [0,1]$ to each object
					\end{itemize}
				\end{definition}
				\begin{definition}<1->
					\begin{itemize}
						\item \textbf{Inclusion Constraints} admit objects based on proximity to the \texttt{ideal value}
						\item \textbf{Exclusion Constraints} admit objects based on distance from the \texttt{ideal value}
					\end{itemize}
				\end{definition}
			\end{frame}

	\section{A Sample Problem: NYSC Posting}
		\subsection{Problem Statement}
			\begin{frame}
				\frametitle{The NYSC Posting Problem}
				\begin{block}{Problem Statement}
					Given a number of graduates, we seek to post them to Service States under the following constraints:
					\begin{enumerate}
						\item No student should be posted to their State of origin
						\item No student should be posted to their State of study
						\item The maximum capacity of each state must not be exceeded%\footnote{This algorithm innately caters to capacity constraints}
					\end{enumerate}
				\end{block}
			\end{frame}

			\begin{frame}
				\frametitle{The States - Partitions}
				\begin{center}
					\begin{tabular}{|c|c|c|c|c|}
						\hline
						\textbf{$\Delta$s} & \textbf{State} & \textbf{Capacity} \\
						\hline
						1 & Osun State & 3\\
						\hline
						2 & Kwara State & 2\\
						\hline
						3 & Enugu State & 1\\
						\hline
						4 & Akwa-Ibom State & 5\\
						\hline
						5 & Kano State & 10\\
						\hline
					\end{tabular}
				\end{center}
			\end{frame}
			\begin{frame}
				\frametitle{The Graduates - Objects}
				\begin{center}
					\begin{tabular}{|c|c|c|c|}
						\hline
						\textbf{Graduate} & \textbf{Name} & \textbf{State of Origin} & \textbf{University}\\
						\hline
						$u_{1}$ & GR01 & Kwara(2) & OAU(1)\\
						\hline
						$u_{2}$ & GR02 & Kwara(2) & BUK(5)\\
						\hline
						$u_{3}$ & GR03 & Kwara(2) & NSUKKA(3)\\
						\hline
						$u_{4}$ & GR04 & Kwara(2) & UNILORIN(2)\\
						\hline
						$u_{5}$ & GR05 & Akwa-Ibom(4) & OAU(1)\\
						\hline
						$u_{6}$ & GR06 & Akwa-Ibom(4) & BUK(5)\\
						\hline
						$u_{7}$ & GR07 & Akwa-Ibom(4) & NSUKKA(3)\\
						\hline
						$\vdots $ & $\vdots $ & $\vdots $ & $\vdots $ \\
						\hline
						$u_{16}$ & GR16 & Kano(5) & AKSU(4)\\
						\hline
						$\vdots $ & $\vdots $ & $\vdots $ & $\vdots $ \\
						\hline
						$u_{20}$ & GR20 & Enugu(3) & AKSU(4)\\
						\hline
					\end{tabular}
				\end{center}
			\end{frame}
			\subsection{The Constraints}
			\begin{frame}
				\frametitle{Constraint A, $\mu_A\colon (p_i,u_j)\mapsto [0,1]$}
				Constraint A, $\mu_A$: No student should be posted to their State of Origin
				\begin{block}{Illustration}
					\begin{equation}
						\mu_{A_j}(u_i) = \frac{\left(j-s_A(u_i)\right)^2}{1 + \left(j-s_A(u_i)\right)^2} \notag
					\end{equation}
				\end{block}
				\begin{example}
					\begin{align}
						\mu_{A_1}(u_1) &= \frac{\left(1-s_A(u_1)\right)^2}{1 + \left(1-s_A(u_1)\right)^2} \notag\\
						&= \frac{\left(1-2\right)^2}{1 + \left(1-2\right)^2} \notag \\
						&= 0.5 \notag \\
						&\vdots \notag
					\end{align}
				\end{example}
			\end{frame}
			\begin{frame}
				\frametitle{Constraint B, $\mu_B\colon (p_i,u_j)\mapsto [0,1]$}
				Constraint B, $\mu_B$: No student should be posted to their State of studies
				\begin{block}{Illustration}
					\begin{equation}
						\mu_{B_j}(u_i) = \frac{\left(j-s_B(u_i)\right)^2}{1 + \left(j-s_B(u_i)\right)^2} \notag
					\end{equation}
				\end{block}
				\begin{example}
					\begin{align}
						\mu_{B_1}(u_1) &= \frac{\left(1-s_B(u_1)\right)^2}{1 + \left(1-s_B(u_1)\right)^2}\notag\\
						&= \frac{\left(1-1\right)^2}{1 + \left(1-1\right)^2} \notag \\
						&= 0 \notag \\
						&\vdots \notag
					\end{align}
				\end{example}
			\end{frame}

			\subsection{Assignment Schedule}
			\begin{frame}
				\frametitle{The Solution}
				\begin{center}
					\begin{tabular}{|c|c|c|c|c|}
						\hline
							\textbf{Name} & \textbf{S. of Origin} & \textbf{University} & \textbf{Posting} & \textbf{Membership} \\
							\hline
							GR06 & Akwa-Ibom & BUK, Kano & Osun & 85\% \\
							\hline
							GR16 & Kano & AKSU, Akwa-Ibom & Osun & 84\% \\
							\hline
							GR04 & Kwara & UNILORIN, Kwara & Akwa-Ibom & 64\% \\
							\hline
							GR01 & Kwara & OAU, Osun & Akwa-Ibom & 45\% \\
							\hline
							GR03 & Kwara & NSUKKA, Enugu & Kano & 88\% \\
							\hline
							GR05 & Akwa-Ibom & OAU, Osun & Kano & 47\% \\
							\hline
							GR07 & Akwa-Ibom & NSUKKA, Enugu & Kano & 45\% \\
							\hline
							GR20 & Enugu & AKSU, Akwa-Ibom & Kano & 40\% \\
							\hline
							$\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ \\
							\hline
					\end{tabular}
				\end{center}
			\end{frame}

			\section{End}
			\begin{frame}
				\frametitle{The Presentation}
				\begin{center}
					\begin{quote}
						\centering \textbf{Thank You!}
					\end{quote}
				\end{center}
			\end{frame}

		% \begin{frame}
		% 	\frametitle{List}
		% 	\begin{itemize}
		% 		\item Point A
		% 		\item Point B
		% 		\begin{itemize}
		% 			\item part 1
		% 			\item part 2
		% 		\end{itemize}
		% 		\item Point C
		% 		\item Point D
		% 	\end{itemize}
		% \end{frame}

		% \begin{frame}
		% 	\frametitle{Using Columns}
		% 	\begin{columns}
		% 		\column{0.5\textwidth}
		% 			<text>
		% 		\column{0.5\textwidth}
		% 			\centering
		% 			\begin{figure}[!htb]
		% 				\center{\includegraphics[width=\textwidth]
		% 				{figures/fig1.png}}
		% 			\caption{\label{fig:fig1} My figure.  An example of a cool figure}
		% 		\end{figure}
		% 	\end{columns}
		% \end{frame}

		% \begin{frame}
		% 	\frametitle{Listing}
		% 	\begin{description}
		% 		\label{terms}
		% 		\item[API] Application Programming Interface
		% 		\item[LAN] Local Area Network
		% 		\item[ASCII] American Standard Code for Information Interchange
		% 	\end{description}
		% 	\begin{block}{Block Title}
		% 		Lorem ipsum dolor sit amet, consectetur adipisicing elit,
		% 		sed do eiusmod tempor incididunt ut labore et
		% 		dolore magna aliqua.
		% 	\end{block}
		% \end{frame}
		% \begin{frame}
		% 	\begin{definition}
		% 		A prime number is a number that...
		% 	\end{definition}
		% 	\begin{example}
		% 		A prime number is a number that...
		% 	\end{example}
		% 	\begin{theorem}[Pythagoras]
		% 		$ a^2 + b^2 = c^2$
		% 	\end{theorem}
		% 	\begin{corollary}
		% 		$ x + y = y + x  $
		% 	\end{corollary}
		% 	\begin{proof}
		% 		$\omega +\phi = \epsilon $
		% 	\end{proof}
		% 	\hyperlink{terms}{\beamergotobutton{go to terms page}}
		% \end{frame}

		% \begin{frame}
			% \frametitle{List}
			% \begin{itemize}
			% \pause
			% \item Point A
			% \pause
			% \item Point B
			% \begin{itemize}
			% \pause
			% \item part 1
			% \pause
			% \item part 2
			% \end{itemize}
			% \pause
			% \item Point C
			% \pause
			% \item Point D
			% \end{itemize}
		% \end{frame}
		% \begin{frame}
		% 	\frametitle{More Lists}
		% 	\begin{enumerate}[(I)]
		% 	\item<-2,4-5,7> Point A
		% 	\item<2-> Point B
		% 	\begin{itemize}
		% 	\item<3-> part 1
		% 	\item<4-> part 2
		% 	\end{itemize}
		% 	\item<5-> Point C
		% 	\item<6-> Point D
		% 	\item<7> Point D
		% 	\end{enumerate}
		% 	\textbf<2>{Example Text}
		% 	\textit<2>{Example Text}
		% 	\textsl<2>{Example Text}
		% 	\textrm<2>{Example Text}
		% 	\textsf<2>{Example Text}
		% 	\textcolor<2>{orange}{Example Text}
		% 	\alert<2>{Example Text}
		% 	\structure<2>{Example Text}
		% \end{frame}
\end{document}


% !TEX root=/home/tavant/these/manuscript/src/manuscript.tex

\section{Study of electron cross field transport with a 2D radial-azimuthal PIC simulation}
  \label{sec-transport}

  A key topic of my PhD work is to study the impact of surface processes on the plasma discharge and in particular on the electron mobility.
  The electron mobility in the axial direction $\mobe$ is defined as the ratio between the mean velocity $u$ and the electric field
  \begin{equation} \label{eq-mudef}
    \mobe = \frac{u_{e,z}}{E_z}
  \end{equation}
  with $u_{e,z}=<v_{e,z}>$ the electron mean velocity.
  \nomenclature[Q]{\ensuremath{ u_{e,z}}}{Electron mean velocity in the axial direction\string: $u_{e,z} = < v_{e,z}>$}
  In the \ac{PIC} simulations, \cref{eq-mudef} can be used directly to compute $\mobpic$.
  As introduced before, in the \ac{PIC} simulation the velocity is shifted by half a time step compared to the position.
  Thus, a special care is needed to compute $\mobpic$.

  In the classical drift diffusion theory of the electron mobility transverse to a magnetic field presented in \cref{ch-concepts}  (\cref{eq-mobility}), the mobility is due to collisions is
  \begin{equation} \label{eq-mobclas}
    \mobcla = \frac{e}{m_e} \frac{\nu_m}{\nu_m^2 + \oce^2}
  \end{equation}
  with $\oce=\frac{e B}{m_e}$ the electron cyclotron frequency and $\nu_m$ the electron-neutral momentum transfer collision frequency.
  In order to evaluate \cref{eq-mobclas},  $\nu_m$ is calculated in the \ac{PIC} simulations at every cell.
  The mobility induced by the instability when neglecting the collisions, as introduced in \cref{ch-concepts} (\cref{eq-mobeffsimple}), is
  \begin{equation} \label{eq-eq_mobeffsimple_two}
      \mobeff = \frac{< \dne \dEt >_{\theta} }{n_0 E_z}   \frac{1}{B_r}
  \end{equation}
  The correlation term $< \dne \dEt >_{\theta}$ can be computed in the \ac{PIC} simulation at each radial position.
  Using its radial profile, we will be able to determine where the instability enhances the most the electron mobility.

  In  \citet{lafleur2016}, the authors present the instability effect as an electron-ion friction force $\Rei = - e < \dne \dEt >_{\theta}$.
  Under the assumption that the saturation of the instability is mainly due to ion trapping, the electron-ion friction force can be simplified in the \ac{2D} geometry of the simulation to
  \begin{equation} \label{eq-rei-sat}
    \Rei^{sat} = \frac{e \norm{\grad \cdot (n_e \Te \vect{v_i})}}{4 \sqrt{6} c_s} \simeq \frac{e n_e \Te \viout}{4 \sqrt 6 c_s L_z}
  \end{equation}
  \nomenclature[Q]{\ensuremath{ \vect{v_e}, \vect{v_i}}}{  Electron and ion velocity vectors}
  \nomenclature[Q]{\ensuremath{ c_s}}{ Ion sound speed $c_s=(e \Te/m_i)^{1/2}$ }
  where $\vect{v_i}$ is the ion velocity, $c_s=(e \Te/m_i)^{1/2}$  is the ion sound speed, and the spatial derivative has been approximated across the axial simulation direction, with $\viout$ the ion outlet velocity
  \begin{equation} \label{eq-viz}
    \viout = \sqrt{\frac{2 e U_z}{m_i}},
  \end{equation}
  with $U_z = E_z L_z$ the total potential difference in the axial direction.
  \nomenclature[Q]{\ensuremath{ U_z}}{   Total potential difference in the axial direction $U_z = E_z L_z$}
  \nomenclature[Q]{\ensuremath{ U_d}}{   Discharge voltage}

  Using \cref{eq-rei-sat} in \cref{eq-mobeffsimple}, we obtain the simplified expression of the effective mobility at saturation
  \begin{equation} \label{eq-mobeffsat}
    \mobeffsat = \frac{\sqrt{\frac{\Te}{U_z}}}{4\sqrt{3}B_r}.
  \end{equation}

  \Cref{eq-mobeffsat} shows that for the radial and azimuthal \ac{2D} geometry being used here, the enhanced mobility due to \ac{ECDI} scales as the square-root of the electron temperature $\Te$ if the simulation parameters are constant.
  However, it is not the case in general, as the saturation of the instability can be also be due to convection, and there are axial gradients in the electron temperature and plasma density as well.

  We can note that $\mobpic, \mobeff$ and $\mobcla$ are defined at every position of the simulation, but that $\mobeffsat$ can only be globally calculated.


\chapter{Implementation III:  Disequality Constraints}\label{diseqimplchapter}

In this chapter we implement the \mbox{\scheme|=/=|} disequality
constraint operator described in Chapter~\ref{diseqchapter}.  We
implement disequality constraints using unification, which results in
remarkably concise and elegant code.  The mathematics of this approach
were described by \citeauthor{Comon91disunification:a} in the
1980's\footnote{See \citet{Comon91disunification:a} and
\citet{ComonEquational1989}.}---to our knowledge, our implementation
is the first to use this technique, for which triangular
substitutions (section~\ref{mkunif}) are a perfect match.  We also
present a sophisticated reifier that removes irrelevant and redundant
constraints.

This chapter is organized as follows.  In section~\ref{diseqrep} we
describe our representation of the constraint store, which is passed
to every goal as part of a \emph{package} that also contains the
substitution.  Section~\ref{solvediseq} presents the constraint
solving algorithm, which is based on unification, while
section~\ref{neverequaloimplsection} defines the \scheme|=/=| and
\scheme|==| operators and related helpers.  Finally in
section~\ref{diseqreify} we present a sophisticated reifier that
produces human-friendly representations of constraints.

\section{Constraints, Constraint Lists, and Packages}\label{diseqrep}

We represent a constraint \scheme|c| as a list of pairs associating variables with terms.
For example, the constraint \mbox{\scheme|(=/= 5 x)|} would be represented as
\mbox{\scheme|`((,x . 5))|}, while the constraint \mbox{\scheme|(=/= `(5 6) `(,y ,z))|}
would be represented as \mbox{\scheme|`((,y . 5) (,z . 6))|}.  In fact, our representation
of disequality constraints is identical to our representation of substitutions---indeed, a
constraint can be viewed as a mini-substitution that indicates which simultaneous variable
associations would violate the constraint.

% Point out that a
% constraint looks exactly like a substitution, and possesses the same
% properties (for example, each variable appears on the lhs at most
% once).

% [constraint store \scheme|c*| is a list of constraints (a list of substitutions)]

A program can introduce many constraints, which requires that we
introduce the notion of a \emph{constraint store} that will be passed to
every goal, along with the substitution.  We represent our constraint
store \scheme|c*| as a list of constraints (that is, a list of
substitutions).  For example, after running the goal

\wspace

\noindent
\mbox{\scheme|(exist (x y z) (=/= 5 x) (=/= `(5 6) `(,y ,z)))|}

\wspace

\noindent
the constraint store would be \mbox{\scheme|`(((,y . 5) (,z . 6)) ((,x . 5)))|}.

We define \scheme|empty-c*| to be the empty list: \mbox{\scheme|(define empty-c* '())|}.
 We extend \scheme|c*| using \scheme|cons|.

We must pass the constraint store to every goal.  We could add an
extra \scheme|c*| argument to each goal, but instead we pass around
the substitution and constraint store as a single value, which we call
a \emph{package}.  Most goal constructors just pass around the
substitution---their definitions need not change.  We only need to
modify goal constructors that extend or inspect the substitution (such
as \scheme|==|).
(We will use the package abstraction whenever we need to pass around
constraint information, such as the freshness constraints of nominal
logic in Chapter~\ref{akimplchapter}.)

Here are our package constructors and deconstructors\footnote{The
\scheme|s-of| deconstructor, which returns a package's substitution,
is all we need to update our definition of the impure operator
\scheme|project|.
\begin{schemedisplay}
(define-syntax project
  (syntax-rules ()
    ((_ (x ...) g g* ...)
     (lambdag@ (a)
       (let ((s (s-of a)))
         (let ((x (walk* x s)) ...)
           ((exist () g g* ...) a)))))))
\end{schemedisplay}}.

\wspace

\begin{schemedisplay}
(define make-a (lambda (s c*) (cons s c*)))
(define s-of (lambda (a) (car a)))
(define c*-of (lambda (a) (cdr a)))
(define empty-a (make-a empty-s empty-c*))
\end{schemedisplay}

\section{Solving Disequality Constraints}\label{solvediseq}

In this section we will use unification in a clever way to solve
disequality constraints after a call to \scheme|=/=| or \scheme|==|,
and to keep these constraints in simplified form.  First, observe that
unifying terms \scheme|t1| and \scheme|t2| in a substitution
\scheme|s| has three possible outcomes:

\begin{enumerate}
\item unification can fail, indicating there is no extension to
  \scheme|s| that will make \scheme|t1| and \scheme|t2| equal;
\item unification can succeed {\em without} extending
  \scheme|s|---this implies that \scheme|t1| and \scheme|t2| are
  already equal;
\item unification can succeed, returning an extended substitution
  containing new associations---in this case, the
  ``mini-substitution'' \scheme|s^| containing only these new
  associations represents the most general substitution that makes
  \scheme|t1| and \scheme|t2| equal\footnote{The technical term for
    this substitution is the \scheme{most general unifier} or
    \emph{mgu}.}.
\end{enumerate}

Now let us consider disequality constraints: instead of determining if
\scheme|t1| and \scheme|t2| can be made equal, we wish to determine if
\scheme|t1| and \scheme|t2| can be made \emph{disequal} with respect
to \scheme|s|.  Fortunately, this requires only a slight change in
perspective.  We unify \scheme|t1| and \scheme|t2| with respect to
\scheme|s|, but we interpret result of the unification differently:

\begin{enumerate}
\item if unification fails, \scheme|t1| and \scheme|t2| can never be
  made equal, and the disequality constraint can never be
  violated---therefore, we can throw the constraint away;
\item if unification succeeds {\em without} extending \scheme|s|, then
  \scheme|t1| and \scheme|t2| are already equal---the disequality
  constraint has been violated;
\item if unification succeeds and returns an extended substitution
  containing new associations, then the constraint has not been
  violated, but could still be violated through future calls to
  \scheme|==|---in this case, the ``mini-substitution'' \scheme|s^|
  that contains the new associations represents the updated
  disequality constraint in simplified form.
\end{enumerate}

A few examples should clarify how unification can be used to solve
disequality constraints.

\begin{enumerate}
\item Running the goal \mbox{\scheme|(=/= 5 6)|} corresponds to the
  first case above: \scheme|5| and \scheme|6| fail to unify in any
  substitution, which means the constraint can never be violated.
  Therefore \mbox{\scheme|(=/= 5 6)|} succeeds, without extending the
  constraint store.

\item The goal \mbox{\scheme|(=/= 5 5)|} corresponds to the second
  case above: \scheme|5| unifies with itself, without extending the
  current substitution, which means the disequality constraint has
  been violated.  Therefore \mbox{\scheme|(=/= 5 5)|} fails.

\item The goal \mbox{\scheme|(=/= `(5 6) `(,x ,y))|} corresponds to
  the third case above: \mbox{\scheme|`(5 6)|} and \mbox{\scheme|`(,x ,y)|}
  unify in the empty substitution (let's say), resulting in a
  substitution extended with the associations \mbox{\scheme|`(,x . 5)|}
  and \mbox{\scheme|`(,y . 6)|}.  This means the
  constraint was not violated, but could be violated in the future (if
  \scheme|x| is unified with \scheme|5| and \scheme|y| with \scheme|6|).
  Therefore \mbox{\scheme|(=/= `(5 6) `(,x ,y))|} succeeds, extending the
  constraint store with the simplified constraint \mbox{\scheme|`((,x . 5) (,y . 6))|}.
\end{enumerate}

Let us consider a final, more complicated example that uses both
\scheme|=/=| and \scheme|==|.

\schemedisplayspace
\begin{schemedisplay}
(exist (p x y)
  (=/= `(5 6) p)
  (== `(,x ,y) p)
  (== 5 x)
  (== 7 y))
\end{schemedisplay}

\noindent Let us assume that we run this goal in the empty package, containing
the empty substitution \mbox{\scheme|s = `()|} and the empty constraint
store \mbox{\scheme|c* = `()|}.  First we run the goal \mbox{\scheme|(=/= `(5 6) p)|};
\mbox{\scheme|p|} unifies with
\mbox{\scheme|`(5 6)|} in the empty substitution, extending the substitution with the association
\mbox{\scheme|`((,p . (5 6)))|}.  Therefore \mbox{\scheme|(=/= `(5 6) p)|} succeeds, returning a
package with \mbox{\scheme|s = ()|} and \mbox{\scheme|c* =  `(((,p . (5 6))))|}.

Next we run \mbox{\scheme|(== `(,x ,y) p)|};
\mbox{\scheme|p|} unifies with \mbox{\scheme|`(,x ,y)|} in the empty substitution,
returning the extended substitution
\mbox{\scheme|s = `((,p . (,x ,y)))|}.  But after the successful unification we must verify
all of the constraints in the constraint store.  We have only the single constraint
\mbox{\scheme|`((,p . (5 6)))|}, which we verify by unifying \mbox{\scheme|p|} and
\mbox{\scheme|`(5 6)|} in the new substitution
\mbox{\scheme|`((,p . (,x ,y)))|}.  This unification succeeds, extending the substitution with the
associations \mbox{\scheme|`(,x . 5)|} and \mbox{\scheme|`(,y . 6)|}.  Therefore
\mbox{\scheme|(== `(,x ,y) p)|} succeeds, returning
a new package with \mbox{\scheme|s = `((,p . (,x ,y)))|} and
\mbox{\scheme|c* = `(((,x . 5) (,y . 6)))|}.

Next we run \mbox{\scheme|(== 5 x)|}; \mbox{\scheme|x|} unifies with \mbox{\scheme|5|}
in the substitution \mbox{\scheme|`((,p . (,x ,y)))|},
returning the extended substitution \mbox{\scheme|s = `((,x . 5) (,p . (,x ,y)))|}.
Since the unification
was successful, we must verify our constraints.
We still have only a single constraint, \mbox{\scheme|`((,x . 5) (,y . 6))|}, which we verify by
simultaneously unifying \mbox{\scheme|x|} with \mbox{\scheme|5|} and
\mbox{\scheme|y|} with \mbox{\scheme|6|} in the new substitution
\mbox{\scheme|s = `((,x . 5) (,p . (,x ,y)))|}. This unification succeeds, extending
\mbox{\scheme|s|} with the association
\mbox{\scheme|`(,y . 6)|}.  Therefore \mbox{\scheme|(== 5 x)|} succeeds,
returning a new package with
\mbox{\scheme|s = `((,x . 5) (,p . (,x ,y)))|} and \mbox{\scheme|c* = `(((,y . 6)))|}.

Finally we run \mbox{\scheme|(== 7 y)|}; \mbox{\scheme|y|} unifies with \mbox{\scheme|7|}
in the substitution \mbox{\scheme|`((,x . 5) (,p . (,x ,y)))|},
returning the extended substitution \mbox{\scheme|s = `((,y . 7) (,x . 5) (,p . (,x ,y)))|}.
We then check the constraint \mbox{\scheme|`((,y . 6))|} by unifying \mbox{\scheme|y|} and
\mbox{\scheme|6|} in the new substitution; this unification fails,
indicating that the constraint can never be violated, and can therefore be discarded.
The goal \mbox{\scheme|(== 7 y)|} succeeds, as does the entire \mbox{\scheme|exist|},
returning the package
\mbox{\scheme|s = `((,y . 7) (,x . 5) (,p . (,x ,y)))|} and \mbox{\scheme|c* = ()|}.

Had we replaced the final goal \mbox{\scheme|(== 7 y)|}
with \mbox{\scheme|(== 6 y)|}, \mbox{\scheme|y|} and \mbox{\scheme|6|}
would have succeeded without extending the substitution; the constraint
would therefore have been violated, and the entire \scheme|exist| would fail.

\section{Implementing $\neq$ and $\equiv$}\label{neverequaloimplsection}

Now that we understand how to solve disequality constraints using
unification, we are ready to define \scheme|=/=|.
\scheme|=/=| just unifies its arguments in the current
substitution, then passes the result of the unification, along with
original package, to \scheme|=/=-verify|.

\schemedisplayspace
\begin{schemedisplay}
(define-syntax =/=
  (syntax-rules ()
    ((_ u v)
     (lambdag@ (a)
       (=/=-verify (unify u v (s-of a)) a)))))
\end{schemedisplay}

\scheme|=/=-verify| performs a case analysis on the result of the
unification, \scheme|s^|, as described in section~\ref{solvediseq}.
If unification failed, the constraint cannot be violated; therefore
\scheme|=/=| succeeds, and just returns the package passed to it.
Since we are using triangular substitutions, we can use a single
\scheme|eq?| test to determine if unification succeeded without
extending the substitution (the second \scheme|cond| clause); if so,
the constraint has been violated, and \scheme|=/=| returns \scheme|(mzero)|
to indicate failure.  Otherwise, unification returned an extended
substitution.  We therefore call the \scheme|prefix-s| helper (below),
which returns a mini-substitution \scheme|c| containing only the new
associations added during unification.  We then construct a new
package containing both the extended substitution \scheme|s^| and the
simplified constraint \scheme|c|.

\schemedisplayspace
\begin{schemedisplay}
(define =/=-verify
  (lambda (s^ a)
    (cond
      ((not s^) (unit a))
      ((eq? (s-of a) s^) (mzero))
      (else (let ((c (prefix-s s^ (s-of a))))
              (unit (make-a (s-of a) (cons c (c*-of a)))))))))
\end{schemedisplay}

Here is \scheme|prefix-s|, which returns the new associations in
\scheme|s| that do not occur in the older substitution \scheme|<s|.
Our use of triangular substitutions makes it trivial to define
\scheme|prefix-s|, since the new substitutions always form a prefix of
\scheme|s|.

\schemedisplayspace
\begin{schemedisplay}
(define prefix-s
  (lambda (s <s)
    (cond
      ((eq? s <s) empty-s)
      (else (cons (car s) (prefix-s (cdr s) <s))))))
\end{schemedisplay}

We can now define \scheme|==|, which must check every constraint in
the constraint store after a successful unification.  Constraint
checking also ensures the constraints are kept in simplified form,
making future constraint checking more efficient.  This simplified
form also simplifies reification\footnote{We keep each individual
  constraint in simplified form.  However, the constraint store itself
  is not simplified, and may contain redundant constraints.
  Determining if a constraint subsumes another is expensive, so we
  only remove redundant constraints at reification time.}.

\schemedisplayspace
\begin{schemedisplay}
(define-syntax ==
  (syntax-rules ()
    ((_ u v)
     (lambdag@ (a)
       (==-verify (unify u v (s-of a)) a)))))
\end{schemedisplay}

\scheme|==-verify| is similar to, but slightly more complicated than
\scheme|=/=-verify|, since upon successful unification we need to
verify all the constraints in \scheme|c*|.

\newpage

%\schemedisplayspace
\begin{schemedisplay}
(define ==-verify
  (lambda (s^ a)
    (cond
      ((not s^) (mzero))
      ((eq? (s-of a) s^) (unit a))
      ((verify-c* (c*-of a) empty-c* s^)
       => (lambda (c*) (unit (make-a s^ c*))))
      (else (mzero)))))
\end{schemedisplay}

\scheme|verify-c*| verifies all the constraints in \scheme|c*| with
respect to the current substitution \scheme|s|, accumulating the
verified (and simplified) constraints in \scheme|c*^|.
\scheme|verify-c*| uses \scheme|unify*| (below) to simultaneously
unify the left- and right-hand-sides of all the associations within a
given constraint.

\schemedisplayspace
\begin{schemedisplay}
(define verify-c*
  (lambda (c* c*^ s)
    (cond
      ((null? c*) c*^)
      ((unify* (car c*) s)
       => (lambda (s^)
            (cond
              ((eq? s s^) #f)
              (else (let ((c (prefix-s s^ s)))
                      (verify-c* (cdr c*) (cons c c*^) s))))))
      (else (verify-c* (cdr c*) c*^ s)))))

(define unify*
  (lambda (p* s)
    (cond
      ((null? p*) s)
      ((unify (lhs (car p*)) (rhs (car p*)) s)
       => (lambda (s) (unify* (cdr p*) s)))
      (else #f))))
\end{schemedisplay}

\enlargethispage{1em}

For completeness, here is \scheme|==-no-check|\footnote{We can also
define \scheme|=/=-no-check|, which performs \emph{unsound disunification},
allowing circular constraints such as \mbox{\scheme|`((,x . (,x)))|}.
\begin{schemedisplay}
(define-syntax =/=-no-check
  (syntax-rules ()
    ((_ u v)
     (lambdag@ (a)
       (=/=-verify (unify-no-check u v (s-of a)) a)))))
\end{schemedisplay}
Reifying a circular constraint introduced by \scheme|=/=-no-check| can result in divergence.}.
\schemedisplayspace
\begin{schemedisplay}
(define-syntax ==-no-check
  (syntax-rules ()
    ((_ u v)
     (lambdag@ (a)
       (==-verify (unify-no-check u v (s-of a)) a)))))
\end{schemedisplay}

\section{Reification}\label{diseqreify}

We want our reified constraints to be as concise and readable as possible;
we therefore eliminate \emph{irrelevant}
constraints, which contain one or more variables
that are not themselves reified (see section~\ref{diseqsection}).  We
also remove redundant constraints that are subsumed by other reified
constraints.  Our subsumption check uses unification and is
potentially expensive, so we perform this check only during
reification.

A relevant constraint contains no unreified variables.
\scheme|purify| takes the constraint store \scheme|c*| and the reified
name substitution \scheme|r| (section~\ref{mkreification}), and
returns a constraint store containing only relevant constraints.

\schemedisplayspace
\begin{schemedisplay}
(define purify
  (lambda (c* r)
    (cond
      ((null? c*) empty-c*)
      ((anyvar? (car c*) r)
       (purify (cdr c*) r))
      (else (cons (car c*)
              (purify (cdr c*) r))))))
\end{schemedisplay}

\scheme|purify| calls \scheme|anyvar?| on each constraint, which
returns \scheme|#t| if the constraint contains a variable that is
unassociated in the reified name substitution.
(The constraint store is \scheme|walk*|ed in the package's normal
substitution before purification, so that variables associated with
ground terms do not affect purification.)

\schemedisplayspace
\begin{schemedisplay}
(define anyvar?
  (lambda (v r)
    (cond
      ((var? v) (var? (walk v r)))
      ((pair? v) (or (anyvar? (car v) r) (anyvar? (cdr v) r)))
      (else #f))))
\end{schemedisplay}

In addition to removing irrelevant constraints, we also want to remove
any constraint that is subsumed by another reified constraint.  For example,
after running the goal \mbox{\scheme|(exist (x y) (=/= `(5 6) `(,x ,y)) (=/= 5 x))|}
the constraint store will be \mbox{\scheme|`(((,x . 5)) ((,x . 5) (,y . 6)))|}.
Although the individual constraints are simplified, the constraint \mbox{\scheme|`((,x . 5))|}
subsumes the constraint \mbox{\scheme|`((,x . 5) (,y . 6))|}
(since it is not possible to violate the latter constraint without
also violating the former).

We can determine if a constraint \scheme|c| is subsumed by another
constraint \scheme|c^| through yet another clever use of unification.
We use \scheme|unify*| to perform simultaneous unification of the left-
and right-hand-sides of all the associations in \scheme|c^|, with
respect to the ``substitution'' \scheme|c| (see section~\ref{neverequaloimplsection});
if \scheme|unify*|
succeeds without extending the substitution, then \scheme|c| is
subsumed by \scheme|c^|.  For example, to determine if the constraint
\mbox{\scheme|c = `((,x . 5) (,y . 6))|} is subsumed by
\mbox{\scheme|c^ = `((,x . 5))|}, we unify \scheme|x| and \scheme|5|
in the substitution \mbox{\scheme|`((,x . 5) (,y . 6))|}.  This
unification succeeds without extending \scheme|c|: therefore,
\mbox{\scheme|`((,x . 5) (,y . 6))|} is subsumed by
\mbox{\scheme|`((,x . 5))|}, and can be discarded.

The \scheme|subsumed?| predicate returns \scheme|#t| if the constraint
\scheme|c| is subsumed by any constraint in \scheme|c*|.

\schemedisplayspace
\begin{schemedisplay}
(define subsumed?
  (lambda (c c*)
    (and (not (null? c*))
         (or (eq? (unify* (car c*) c) c)
             (subsumed? c (cdr c*))))))
\end{schemedisplay}

\scheme|rem-subsumed| takes a list of \emph{unseen} constraints
\scheme|c*| and previously seen constraints \scheme|c*^| (initially
empty), and returns a new constraint store containing independent
constraints, none of which are subsumed by any other.  As
\scheme|rem-subsumed| cdrs down \scheme|c*|, it checks if the car of \scheme|c*| is
subsumed by any of the other constraints, either in the rest of the
unseen constraints in \scheme|c*|, or the already seen constraints accumulated
in \scheme|c*^|.  If so, the car of \scheme|c*| is thrown away;
otherwise, it is added to the list of already seen constraints.

\schemedisplayspace
\begin{schemedisplay}
(define rem-subsumed
  (lambda (c* c*^)
    (cond
      ((null? c*) c*^)
      ((or (subsumed? (car c*) c*^) (subsumed? (car c*) (cdr c*)))
       (rem-subsumed (cdr c*) c*^))
      (else (rem-subsumed (cdr c*) (cons (car c*) c*^))))))
\end{schemedisplay}

Here is the updated definition of \scheme|reify|, which
\scheme|walk*|s the constraint store in the package's substitution
before calling \scheme|purify| and \scheme|rem-subsumed|.
\scheme|reify| returns only the reified value if there are no relevant
constraints; otherwise, \scheme|reify| returns a list containing the
reified value, followed by a tagged list of relevant, and independent,
reified constraints.

\schemedisplayspace
\begin{schemedisplay}
(define reify
  (lambda (v a)
    (let ((s (s-of a)))
      (let ((v (walk* v s))
            (c* (walk* (c*-of a) s)))
        (let ((r (reify-s v empty-s)))
          (let ((v (walk* v r))
                (c* (walk* (rem-subsumed (purify c* r) empty-c*) r)))
            (cond
              ((null? c*) v)
              (else `(,v : (never-equal . ,c*))))))))))
\end{schemedisplay}

%[unification based-implementation, showing advantage of triangular substitutions]

%[need to reference H. Comon paper]

%[I discovered algorithm independently, in the context of term equality
%for our initial, clumsier implementation of disequality constraints]

%[explain algorithm using case analysis and examples]

%[code taken from /iu/c311/2008\_II/infer/mkneverequalo.scm]

%[relies on standard definitions of conde, etc.]

%[reification]

%[only reify "relevant" constraints]


\section{CorsNet: 3D Point Cloud Registration by Deep Neural
Network}\label{header-n534}

\emph{IEEE ROBOTICS AND AUTOMATION LETTERS, VOL. 5, NO. 3, JULY 2020}
{[}12{]}

\subsection{Introduction}\label{header-n536}

In computer vision, pattern recognition, and robotics, \emph{point set
registration}, also known as \emph{point cloud registration}, is the
process of finding a spatial transformation (\emph{e.g.,} scaling,
rotation and translation) that aligns two point clouds. The 3D point
cloud is a recently popular data format. The most popular and classic
method for point cloud registration is the iterative closest point (ICP)
algorithm {[}13{]}. ICP calculates the rigid motion based on a fixed
correspondence between one point cloud and another, updating the
correspondence to minimize the point-to-point distances. Although ICP
can achieve highly accurate registration, the registration often fails
by falling into the local minimum. In other words, the registration
accuracy of ICP depends strongly on its initial perturbation. Despite
this, the inherent lack of structure has caused difficulties when
adopting point clouds as direct input in deep learning architecture.
PointNet {[}14{]}, overcomes these difficulties, providing a mechanism
to extract the feature related to the point clouds. PointNet is a
general representation of an unstructured point cloud that allows object
detection, segmentation, and so on. PointNetLK {[}15{]} is the latest
deep learning-based registration techniques using PointNet {[}2{]}.
PointNetLK directly optimizes the distance of aggregated features using
the gradient method. This approach overcomes computational speed and
local minimum problems. In this paper, ``DirectNet" is proposed as a
baseline method as it is a simplistic approach. However, the authors
think that PointNetLK and DirectNet do not consider local features,
falling to fully utilize the point cloud information. In this work,
CorrespondenceNet (CorsNet) is proposed. It is a novel point cloud
registration method based on deep learning is proposed. This method
feeds global features from PointNet to per-point local features to make
effective use of point cloud information. The end-to-end network
architecture consists of the main three parts: (1) extracting global
features of point clouds with PointNet, (2) concatenating global
features with local features of the source point cloud and outputting
the correspondences of each point via fully connected layers and (3)
estimating a rigid transform with singular value decomposition (SVD).
The SVD part is also included in the end-to-end network architecture.
The singular value decomposition is a factorization of a matrix
$m \times n$. Given the matrix here $\mathbf {M}_{m\times n}$,
$\mathbf{M} = \mathbf{U}\mathbf{\Sigma}\mathbf{V}$. If $\mathbf {M}$ is used
in a geometrical operation, the same result can be obtained applying
these three matrices in succession. In particular,
$\mathbf {U}_{m\times n}$ is an orthogonal matrix that applies a
rotation, $\mathbf{\Sigma}_{n\times n}$ is a diagonal matrix that scales only
the axes and $\mathbf {V}_{n\times q}$ is another orthogonal matrix
that applies another rotation.
\newpage
\begin{figure}[h!]
\centering
\includegraphics[width=0.7\linewidth]{images/singolarvaluedec.png}
\caption{Singular value decomposition}
\end{figure}

\subsection{Proposed method (CorsNet)}\label{header-n539}

A point cloud is represented as a set of 3D points
$\{P : P_i|i = 1, . . ., n\} \subset \R_3$ whose each point $P_i$ is
a vector of its $(x, y, z)$ coordinate. The following figure shows the
CorstNet architecture.

\begin{figure}[h!]
\centering
\includegraphics[width=0.8\linewidth]{images/corsnetarch.png}
\caption{CorsNet architecture}
\end{figure}

The red $\boldsymbol{P}_S$ and blue $\boldsymbol{P}_T$ point clouds
represent the \emph{source} and \emph{template} point clouds,
respectively. We find the rigid transform $\boldsymbol{G} \in SE$,
which includes the alignment between $\boldsymbol{P}_S$ and
$\boldsymbol{P}_T$. The model mainly consists of three components:

\begin{itemize}
\item
  \textbf{Global feature extraction:} this first module extract the
  point cloud's features. These features must include three factors:
  invariance in order, acquisition of local feature, and invariance in
  rotation. PointNet is used to absolve this goal. It satisfying these
  three requirements and it has achieved high accuracy and low
  computational complexity in various benchmarks. The PointNet output is
  a $1 \times 1024$ vector obtained by a max-pooling of two MLP (multi-layer
  perceptron). The features are extracted both for the source and
  template point clouds.
\item
  \textbf{Correspondence estimation:} after computing the global
  features of the source and template point cloud, this module finds the
  point local features by concatenating the global feature with each of
  the point features. The network output is t
  $\Delta\boldsymbol{P}_S$, a $n \times 3$ matrix. By adding this
  $\Delta\boldsymbol{P}_S$ to $\boldsymbol{P}_S$, the tentative
  transform destination can be calculated as follow:

  $ \hat{\boldsymbol {P}_T} = \boldsymbol {P}_S + \Delta \boldsymbol {P}_S $

  This method regresses correspondences $\Delta\boldsymbol{P}_S$ and
  estimates a rigid transform based on the estimated correspondences
  using SVD

  $ \boldsymbol {G}\cdot \boldsymbol {P}_S= \boldsymbol {P}_T$
\item
  \textbf{SVD:} the source point cloud is now aligned with the template
  point cloud and the following is the approach for calculating a rigid
  transformation using SVD as follows.

  Define the centroids of $\boldsymbol{P}_S$ and
  $\hat{\boldsymbol{P}_T}$ as:

  $\overline{\boldsymbol {P}_S} = \frac{1}{n}\sum ^{n}_{i=1}\boldsymbol {P}_S \;\;\; \text{and} \;\;\; \overline{\hat{\boldsymbol {P}_T}} = \frac{1}{n}\sum ^{n}_{i=1}\hat{\boldsymbol {P}_T}$

  and calculate the cross-covariance matrix H:

  $ \boldsymbol {H}= \sum ^{N}_{i=1}\left(\hat{\boldsymbol {P}_T}-\overline{\hat{\boldsymbol {P}_T}}\right)\left(\boldsymbol {P}_S-\overline{\boldsymbol {P}_S}\right)^{T}.$

  Then, use SVD to decompose $\boldsymbol{H}$ to
  $\boldsymbol{U},\boldsymbol{V} \in SO$

  $  [\boldsymbol {U}, \boldsymbol {S}, \boldsymbol {V}]= SVD (\boldsymbol {H}).$

  and, using this decomposition, extract the rigid transform elements,
  estimated rotation, $\boldsymbol{R}_{est}\in SO$ and translation,
  $\boldsymbol{t}_{est} \in \R^3$

  $ \boldsymbol {R}_{est} = \boldsymbol {V}\boldsymbol {U}^{T}.\\\boldsymbol {t}_{est} = - \boldsymbol {R}\cdot \overline{\hat{\boldsymbol {P}_T}} + \overline{\boldsymbol {P}_S}. $

  Now, it is possible to calculate the estimated rigid transform
  $\mathbf{G}_{est}$ and the twist parameters
  $\mathbf{\xi}_{est} \in \R^{6}$ as follow:

  $ \boldsymbol {G}_{est} = \left(\begin{array}{cc}\boldsymbol {R}_{est} & \boldsymbol {t}_{est} \\ \boldsymbol {0} & 1 \end{array} \right). \\ \boldsymbol {\xi }_{est} = \phi \left(\boldsymbol {G}_{est} \right). $
\end{itemize}

\newpage
The dataset used to test the proposed method is called ModelNet40
{[}16{]}. From this, the source point clouds ($\boldsymbol{P}_S$) are
extracted and the ground-truth estimated rigid transform
($\boldsymbol{G}_{gt}$) can be defined as:\newline\
$ \boldsymbol {P}_{T} = \boldsymbol {G}_{gt}\cdot \boldsymbol {P}_{S}.$\newline
Now, we call $\boldsymbol{Cors}$ the correspondence between two point
clouds, in particular: \newline
$\boldsymbol {Cors}_{gt} = \boldsymbol {P}_{T} - \boldsymbol {P}_{S}.  \\  \boldsymbol {Cors}_{est} = \hat{\boldsymbol {P}_{T}} - \boldsymbol {P}_{S}.$
\newline
Subsequently, we define three kinds of loss elements using previously
values:
\newline
$ \boldsymbol {loss}_{1} = ||(\boldsymbol {G}_{est})^{-1}\cdot \boldsymbol {G}_{gt} - \boldsymbol {I}_{4}||_{F}. \\ \boldsymbol {loss}_{2} = ||\boldsymbol {\xi }_{gt}-\boldsymbol {\xi }_{est}||^{2}. \\ \boldsymbol {loss}_{3} = ||\boldsymbol {Cors}_{gt} - \boldsymbol {Cors}_{est}||^{2}. $
\newline
From them, four loss functions are defined as follow:
\newline
$ \boldsymbol {Loss}_{v1} = \boldsymbol {loss}_{1}. \\ \boldsymbol {Loss}_{v2} = \boldsymbol {loss}_{2}. \\ \boldsymbol {Loss}_{v3} = \boldsymbol {loss}_{1} + \boldsymbol {loss}_{3}.\\ \boldsymbol {Loss}_{v4} = \boldsymbol {loss}_{2} + \boldsymbol {loss}_{3}.  $
\newline
The authors verified the effectiveness of each loss function in the
experiments.

\subsection{Proposed method (DirectNet)}\label{header-n572}

The authors proposed a novel method which directly regresses the pose,
including rotation $\boldsymbol{R}_{euler} \in \R^3 $ (Euler angle) and
translation $\boldsymbol{t} \in \R^3$, as shown in the following figure.

\begin{figure}[h!]
\centering
\includegraphics[width=0.95\linewidth]{images/directnet.png}
\caption{DirectNet architecture}
\end{figure}

DirectNet consists of two parts: the global feature extraction module,
which is identical to CorsNet (that is PointNet), and the global
estimation part. The $\boldsymbol{P}_S$ and $\boldsymbol{P}_T$
global features extracted with PointNet are concatenated and converted
to $1 \times 6$ vector. The output $1 \times 6$ vectors is
$[x_{euler}, y_{euler}, z_{euler}, x_{t}, y_{t}, z_{t}]^T$. The first
half of this vector is represented as
$\boldsymbol{R_{euler}} = [x_{euler}, y_{euler}, z_{euler}]^T$ . This
$\boldsymbol{R_{euler}}$ is converted into
$\boldsymbol{R_{est}} \in SO $ as follows:
\newline
$ \boldsymbol {x}_{mat} = \left(\begin{array}{ccc}1 & 0 & 0 \\ 0 & \cos x_{euler} & -\sin x_{euler} \\ 0 & \sin x_{euler} & \cos x_{euler} \end{array} \right), \\ \boldsymbol {y}_{mat} = \left(\begin{array}{ccc}\cos y_{euler} & 0 & \sin y_{euler} \\ 0 & 1 & 0 \\ -\sin y_{euler} & 0 & \cos y_{euler} \end{array} \right), \\ \boldsymbol {z}_{mat} = \left(\begin{array}{ccc}\cos z_{euler} & -\sin z_{euler} & 0 \\ \sin z_{euler} & \cos z_{euler} & 0 \\ 0 & 0 & 1 \end{array} \right), \\ \boldsymbol {R}_{est} = \boldsymbol {x}_{mat} \cdot \boldsymbol {y}_{mat} \cdot \boldsymbol {z}_{mat} $
\newline
The last part, instead, define the translation vector
$\boldsymbol{t_{est}}$ as
\newline
$ \boldsymbol {t}_{est} = [x_{t}, y_{t}, z_{t}]^{T}.$
\newline
Using $\boldsymbol {R}_{est}$ and $\boldsymbol {t}_{est}$ is
possible to determine $\boldsymbol {G}_{est}$ and
$\boldsymbol {\xi}_{est}$ as done for CorsNet. For DirectNet two loss
functions are formulated:
\newline
$ \boldsymbol {Loss}_{v1} = ||(\boldsymbol {G}_{est})^{-1}\cdot \boldsymbol {G}_{gt} - \boldsymbol {I}_{4}||_{F}. \\ \boldsymbol {Loss}_{v2} = ||\boldsymbol {\xi }_{gt}-\boldsymbol {\xi }_{est}||^{2}.$

\subsection{Experiments}\label{header-n581}

The proposed method CorsNet is compared with ICP and PointNetLK,
DirectNet (described in this work). The figure below shows graphical examples of pointcloud registration, each of them is executed with a different approach.

\begin{figure}[h!]
\centering
\includegraphics[width=0.4\linewidth]{images/pointcloudreg.png}
\caption{Point cloud registration. \emph{Green}: source, \emph{Blue}: template, \emph{Red}: transformed point cloud. Only the proposed method achieves accurate registration regardless of the initial perturbations.}
\end{figure}

The dataset used is ModelNet40, which includes various point clouds with
40 categories. The point clouds' coordinates are normalized to be in the
$[0, 1]^3$ interval and the points of each model's surface are
sampling to be exactly 1024. The authors measure the root mean square
error (RMSE) of rotation $\boldsymbol{R}$ and translation
$\boldsymbol{t}$ for each experimental setting. The first experiment
consists into evaluate the models using the same categories. 20
categories from the dataset were chosen and they are used for both
training and testing of all networks. CorsNet and DirectNet were trained
using all the losses reported in the sections above. The authors chose a
ground-truth transformation ($\boldsymbol{G}_{gt}$) randomly by an
interval of $[0, 45]$ degrees for rotation and $[0, 0.8]$ for
translation. The following table shows the evaluation results of all
models, using all possible loss functions.

\begin{longtable}[]{@{}lll@{}}
\toprule
\textbf{Method (loss type)} & \textbf{RMSE ($\boldsymbol{R}$)} &
\textbf{RMSE ($\boldsymbol{t}$)}\tabularnewline
\midrule
\endhead
ICP & 46.4628 & 0.26144\tabularnewline
DirectNet $\boldsymbol{Loss}_{v1}$ & 19.4791 & 0.01218\tabularnewline
DirectNet $\boldsymbol{Loss}_{v2}$ & 20.9916 & 0.01690\tabularnewline
PointNetLK & \textbf{14.9746} & 0.01690\tabularnewline
CorsNet $\boldsymbol{Loss}_{v1}$ & 18.6482 & 0.01574\tabularnewline
CorsNet $\boldsymbol{Loss}_{v2}$ & 17.9941 & 0.00725\tabularnewline
CorsNet $\boldsymbol{Loss}_{v3}$ & 18.8303 &
\textbf{0.00632}\tabularnewline
CorsNet $\boldsymbol{Loss}_{v4}$ & 16.2356 & 0.00693\tabularnewline
\bottomrule
\caption{Comparison results on same categories}
\end{longtable}

The results show that the proposed CorsNet, whose loss function is
$\boldsymbol{Loss}_{v3}$, achieved the highest accuracy in terms of
translation. The following figure shows (on its left part) the ratio
between the root mean square error with respect to perturbation both for
rotation and translation. To verify the robustness of the categories,
the authors evaluated the proposed network architecture using different
categories for training and testing. This is the second experiment. The
table below reports the performance evaluation results for the proposed
and related methods.

\begin{longtable}[]{@{}lll@{}}
\toprule
\textbf{Method (loss type)} & \textbf{RMSE ($\boldsymbol{R}$)} &
\textbf{RMSE ($\boldsymbol{t}$)}\tabularnewline
\midrule
\endhead
ICP & 45.8016 & 0.28369\tabularnewline
DirectNet $\boldsymbol{Loss}_{v1}$ & 20.8310 & 0.01983\tabularnewline
DirectNet $\boldsymbol{Loss}_{v2}$ & 22.0024 & 0.01712\tabularnewline
PointNetLK & 21.0866 & 0.03525\tabularnewline
CorsNet $\boldsymbol{Loss}_{v1}$ & 20.2198 & 0.02401\tabularnewline
CorsNet $\boldsymbol{Loss}_{v2}$ & 20.3712 & 0.02396\tabularnewline
CorsNet $\boldsymbol{Loss}_{v3}$ & 19.4610 & 0.02288\tabularnewline
CorsNet $\boldsymbol{Loss}_{v4}$ & \textbf{16.7927} &
\textbf{0.01398}\tabularnewline
\bottomrule
\caption{Comparison results on different categories}
\end{longtable}

Rotation and translation are estimated most accurately by CorsNet, whose
loss function is $\boldsymbol{Loss}_{v4}$. The following figure shows
(on its right part) the ratio between the root mean square error with
respect to perturbation both for rotation and translation.

\begin{figure}[h!]
\centering
\includegraphics[width=0.95\linewidth]{images/mod.png}
\caption{Each graph shows the transition of a root mean square error with respect to the initial perturbation (rotation and translation). The left part refers to the experiments on the same category while the right part refers different categories' experiments}
\end{figure}

\subsection{Conclusions}\label{header-n662}

The superiority of the proposed method has been proven qualitatively and
quantitatively. CorsNet $\boldsymbol{Loss}_{v3}$ and CorsNet
$\boldsymbol{Loss}_{v4}$ ware appreciably more accurate thanCorsNet
$\boldsymbol{Loss}_{v1}$ and CorsNet $\boldsymbol{Loss}_{v2}$,
depending on whether the correspondence loss is included in the loss
function. The following two figure shows the registration results for
the methods tested. Only the proposed method (CorsNet) successfully
aligns the point clouds without falling into the local minimum,
especially where the input point clouds include the repeating
structures.

\begin{figure}[h!]
\centering
\includegraphics[width=0.95\linewidth]{images/registrationres.png}
\caption{Comparison with DirectNet, PointNetLK, and ICP (green: source, blue: template, red: transformed)}
\end{figure}

The authors suppose that this is because only the proposed method links
the local features to the global features, making the most of the local
and global point cloud information.


\subsection{Box topology}


\section{Motion Analysis and Object Tracking}

\ifCPy

\cvCPyFunc{CalcGlobalOrientation}
Calculates the global motion orientation of some selected region.

\cvdefC{
double cvCalcGlobalOrientation( \par const CvArr* orientation,\par const CvArr* mask,\par const CvArr* mhi,\par double timestamp,\par double duration );
}\cvdefPy{CalcGlobalOrientation(orientation,mask,mhi,timestamp,duration)-> float}

\begin{description}
\cvarg{orientation}{Motion gradient orientation image; calculated by the function \cvCPyCross{CalcMotionGradient}}
\cvarg{mask}{Mask image. It may be a conjunction of a valid gradient mask, obtained with \cvCPyCross{CalcMotionGradient} and the mask of the region, whose direction needs to be calculated}
\cvarg{mhi}{Motion history image}
\cvarg{timestamp}{Current time in milliseconds or other units, it is better to store time passed to \cvCPyCross{UpdateMotionHistory} before and reuse it here, because running \cvCPyCross{UpdateMotionHistory} and \cvCPyCross{CalcMotionGradient} on large images may take some time}
\cvarg{duration}{Maximal duration of motion track in milliseconds, the same as \cvCPyCross{UpdateMotionHistory}}
\end{description}

The function calculates the general
motion direction in the selected region and returns the angle between
0 degrees  and 360 degrees . At first the function builds the orientation histogram
and finds the basic orientation as a coordinate of the histogram
maximum. After that the function calculates the shift relative to the
basic orientation as a weighted sum of all of the orientation vectors: the more
recent the motion, the greater the weight. The resultant angle is
a circular sum of the basic orientation and the shift.

\cvCPyFunc{CalcMotionGradient}
Calculates the gradient orientation of a motion history image.

\cvdefC{
void cvCalcMotionGradient( \par const CvArr* mhi,\par CvArr* mask,\par CvArr* orientation,\par double delta1,\par double delta2,\par int apertureSize=3 );
}\cvdefPy{CalcMotionGradient(mhi,mask,orientation,delta1,delta2,apertureSize=3)-> None}

\begin{description}
\cvarg{mhi}{Motion history image}
\cvarg{mask}{Mask image; marks pixels where the motion gradient data is correct; output parameter}
\cvarg{orientation}{Motion gradient orientation image; contains angles from 0 to ~360 degrees }
\cvarg{delta1}{See below}
\cvarg{delta2}{See below}
\cvarg{apertureSize}{Aperture size of derivative operators used by the function: CV\_SCHARR, 1, 3, 5 or 7 (see \cvCPyCross{Sobel})}
\end{description}

The function calculates the derivatives $Dx$ and $Dy$ of \texttt{mhi} and then calculates gradient orientation as:

\[
\texttt{orientation}(x,y)=\arctan{\frac{Dy(x,y)}{Dx(x,y)}}
\]

where both $Dx(x,y)$ and $Dy(x,y)$ signs are taken into account (as in the \cvCPyCross{CartToPolar} function). After that \texttt{mask} is filled to indicate where the orientation is valid (see the \texttt{delta1} and \texttt{delta2} description).

The function finds the minimum ($m(x,y)$) and maximum ($M(x,y)$) mhi values over each pixel $(x,y)$ neighborhood and assumes the gradient is valid only if
\[
\min(\texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max(\texttt{delta1} ,\texttt{delta2} ).
\]

\cvCPyFunc{CalcOpticalFlowBM}
Calculates the optical flow for two images by using the block matching method.

\cvdefC{
void cvCalcOpticalFlowBM( \par const CvArr* prev,\par const CvArr* curr,\par CvSize blockSize,\par CvSize shiftSize,\par CvSize max\_range,\par int usePrevious,\par CvArr* velx,\par CvArr* vely );
}\cvdefPy{CalcOpticalFlowBM(prev,curr,blockSize,shiftSize,max\_range,usePrevious,velx,vely)-> None}

\begin{description}
\cvarg{prev}{First image, 8-bit, single-channel}
\cvarg{curr}{Second image, 8-bit, single-channel}
\cvarg{blockSize}{Size of basic blocks that are compared}
\cvarg{shiftSize}{Block coordinate increments}
\cvarg{max\_range}{Size of the scanned neighborhood in pixels around the block}
\cvarg{usePrevious}{Uses the previous (input) velocity field}
\cvarg{velx}{Horizontal component of the optical flow of
\[
\left\lfloor \frac{\texttt{prev->width} - \texttt{blockSize.width}}{\texttt{shiftSize.width}} \right\rfloor
\times
\left\lfloor \frac{\texttt{prev->height} - \texttt{blockSize.height}}{\texttt{shiftSize.height}} \right\rfloor
\]
size, 32-bit floating-point, single-channel}
\cvarg{vely}{Vertical component of the optical flow of the same size \texttt{velx}, 32-bit floating-point, single-channel}
\end{description}

The function calculates the optical
flow for overlapped blocks $\texttt{blockSize.width} \times \texttt{blockSize.height}$ pixels each, thus the velocity
fields are smaller than the original images. For every block in \texttt{prev} the functions tries to find a similar block in
\texttt{curr} in some neighborhood of the original block or shifted by (velx(x0,y0),vely(x0,y0)) block as has been calculated by previous
function call (if \texttt{usePrevious=1})

\cvCPyFunc{CalcOpticalFlowHS}
Calculates the optical flow for two images.

\cvdefC{
void cvCalcOpticalFlowHS( \par const CvArr* prev,\par const CvArr* curr,\par int usePrevious,\par CvArr* velx,\par CvArr* vely,\par double lambda,\par CvTermCriteria criteria );
}\cvdefPy{CalcOpticalFlowHS(prev,curr,usePrevious,velx,vely,lambda,criteria)-> None}

\begin{description}
\cvarg{prev}{First image, 8-bit, single-channel}
\cvarg{curr}{Second image, 8-bit, single-channel}
\cvarg{usePrevious}{Uses the previous (input) velocity field}
\cvarg{velx}{Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
\cvarg{vely}{Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
\cvarg{lambda}{Lagrangian multiplier}
\cvarg{criteria}{Criteria of termination of velocity computing}
\end{description}

The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm
\cite{Horn81}.

\cvCPyFunc{CalcOpticalFlowLK}
Calculates the optical flow for two images.

\cvdefC{
void cvCalcOpticalFlowLK( \par const CvArr* prev,\par const CvArr* curr,\par CvSize winSize,\par CvArr* velx,\par CvArr* vely );
}\cvdefPy{CalcOpticalFlowLK(prev,curr,winSize,velx,vely)-> None}
\begin{description}

\cvarg{prev}{First image, 8-bit, single-channel}
\cvarg{curr}{Second image, 8-bit, single-channel}
\cvarg{winSize}{Size of the averaging window used for grouping pixels}
\cvarg{velx}{Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
\cvarg{vely}{Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
\end{description}

The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm
\cite{Lucas81}.

\cvCPyFunc{CalcOpticalFlowPyrLK}
Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids.

\cvdefC{
void cvCalcOpticalFlowPyrLK( \par const CvArr* prev,\par const CvArr* curr,\par CvArr* prevPyr,\par CvArr* currPyr,\par const CvPoint2D32f* prevFeatures,\par CvPoint2D32f* currFeatures,\par int count,\par CvSize winSize,\par int level,\par char* status,\par float* track\_error,\par CvTermCriteria criteria,\par int flags );
}
\cvdefPy{CalcOpticalFlowPyrLK(  prev, curr, prevPyr, currPyr, prevFeatures, winSize, level, criteria, flags, guesses = None) -> (currFeatures, status, track\_error)}

\begin{description}
\cvarg{prev}{First frame, at time \texttt{t}}
\cvarg{curr}{Second frame, at time \texttt{t + dt} }
\cvarg{prevPyr}{Buffer for the pyramid for the first frame. If the pointer is not \texttt{NULL} , the buffer must have a sufficient size to store the pyramid from level \texttt{1} to level \texttt{level} ; the total size of \texttt{(image\_width+8)*image\_height/3} bytes is sufficient}
\cvarg{currPyr}{Similar to \texttt{prevPyr}, used for the second frame}
\cvarg{prevFeatures}{Array of points for which the flow needs to be found}
\cvarg{currFeatures}{Array of 2D points containing the calculated new positions of the input features in the second image}
\ifC
\cvarg{count}{Number of feature points}
\fi
\cvarg{winSize}{Size of the search window of each pyramid level}
\cvarg{level}{Maximal pyramid level number. If \texttt{0} , pyramids are not used (single level), if \texttt{1} , two levels are used, etc}
\cvarg{status}{Array. Every element of the array is set to \texttt{1} if the flow for the corresponding feature has been found, \texttt{0} otherwise}
\cvarg{track\_error}{Array of double numbers containing the difference between patches around the original and moved points. Optional parameter; can be \texttt{NULL}}
\cvarg{criteria}{Specifies when the iteration process of finding the flow for each point on each pyramid level should be stopped}
\cvarg{flags}{Miscellaneous flags:
\begin{description}
  \cvarg{CV\_LKFLOWPyr\_A\_READY}{pyramid for the first frame is precalculated before the call}
  \cvarg{CV\_LKFLOWPyr\_B\_READY}{ pyramid for the second frame is precalculated before the call}
  \cvC{\cvarg{CV\_LKFLOW\_INITIAL\_GUESSES}{array B contains initial coordinates of features before the function call}}
\end{description}}
\cvPy{\cvarg{guesses}{optional array of estimated coordinates of features in second frame, with same length as \texttt{prevFeatures}}}
\end{description}

The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids
\cite{Bouguet00}
. It calculates the coordinates of the feature points on the current video
frame given their coordinates on the previous frame. The function finds
the coordinates with sub-pixel accuracy.

Both parameters \texttt{prevPyr} and \texttt{currPyr} comply with the
following rules: if the image pointer is 0, the function allocates the
buffer internally, calculates the pyramid, and releases the buffer after
processing. Otherwise, the function calculates the pyramid and stores
it in the buffer unless the flag \texttt{CV\_LKFLOWPyr\_A[B]\_READY}
is set. The image should be large enough to fit the Gaussian pyramid
data. After the function call both pyramids are calculated and the
readiness flag for the corresponding image can be set in the next call
(i.e., typically, for all the image pairs except the very first one
\texttt{CV\_LKFLOWPyr\_A\_READY} is set).

\cvCPyFunc{CamShift}
Finds the object center, size, and orientation.

\cvdefC{
int cvCamShift( \par const CvArr* prob\_image,\par CvRect window,\par CvTermCriteria criteria,\par CvConnectedComp* comp,\par CvBox2D* box=NULL );
}
\cvdefPy{CamShift(prob\_image,window,criteria)-> (int, comp, box)}

\begin{description}
\cvarg{prob\_image}{Back projection of object histogram (see \cvCPyCross{CalcBackProject})}
\cvarg{window}{Initial search window}
\cvarg{criteria}{Criteria applied to determine when the window search should be finished}
\cvarg{comp}{Resultant structure that contains the converged search window coordinates (\texttt{comp->rect} field) and the sum of all of the pixels inside the window (\texttt{comp->area} field)}
\ifC % {
\cvarg{box}{Circumscribed box for the object. If not \texttt{NULL}, it contains object size and orientation}
\else % }{
\cvarg{box}{Circumscribed box for the object.}
\fi % }
\end{description}

The function implements the CAMSHIFT object tracking algrorithm
\cite{Bradski98}.
First, it finds an object center using \cvCPyCross{MeanShift} and, after that, calculates the object size and orientation. The function returns number of iterations made within \cvCPyCross{MeanShift}.

The \texttt{CamShiftTracker} class declared in cv.hpp implements the color object tracker that uses the function.

\ifC % {
\subsection{CvConDensation}
ConDenstation state.

\begin{lstlisting}
    typedef struct CvConDensation
    {
        int MP;     //Dimension of measurement vector
        int DP;     // Dimension of state vector
        float* DynamMatr;       // Matrix of the linear Dynamics system
        float* State;           // Vector of State
        int SamplesNum;         // Number of the Samples
        float** flSamples;      // array of the Sample Vectors
        float** flNewSamples;   // temporary array of the Sample Vectors
        float* flConfidence;    // Confidence for each Sample
        float* flCumulative;    // Cumulative confidence
        float* Temp;            // Temporary vector
        float* RandomSample;    // RandomVector to update sample set
        CvRandState* RandS;     // Array of structures to generate random vectors
    } CvConDensation;

\end{lstlisting}
The structure \texttt{CvConDensation} stores the CONditional DENSity propagATION tracker state. The information about the algorithm can be found at \url{http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/ISARD1/condensation.html}.

\cvCPyFunc{CreateConDensation}
Allocates the ConDensation filter structure.

\cvdefC{
CvConDensation* cvCreateConDensation( \par int dynam\_params,\par int measure\_params,\par int sample\_count );
}

\begin{description}
\cvarg{dynam\_params}{Dimension of the state vector}
\cvarg{measure\_params}{Dimension of the measurement vector}
\cvarg{sample\_count}{Number of samples}
\end{description}

The function creates a \texttt{CvConDensation} structure and returns a pointer to the structure.

\cvCPyFunc{ConDensInitSampleSet}
Initializes the sample set for the ConDensation algorithm.

\cvdefC{
void cvConDensInitSampleSet( CvConDensation* condens, \par CvMat* lower\_bound, \par CvMat* upper\_bound );
}

\begin{description}
\cvarg{condens}{Pointer to a structure to be initialized}
\cvarg{lower\_bound}{Vector of the lower boundary for each dimension}
\cvarg{upper\_bound}{Vector of the upper boundary for each dimension}
\end{description}

The function fills the samples arrays in the structure \texttt{condens} with values within the specified ranges.
\fi

\cvclass{CvKalman}\label{CvKalman}
Kalman filter state.

\ifC
\begin{lstlisting}
typedef struct CvKalman
{
    int MP;                     /* number of measurement vector dimensions */
    int DP;                     /* number of state vector dimensions */
    int CP;                     /* number of control vector dimensions */

    /* backward compatibility fields */
#if 1
    float* PosterState;         /* =state_pre->data.fl */
    float* PriorState;          /* =state_post->data.fl */
    float* DynamMatr;           /* =transition_matrix->data.fl */
    float* MeasurementMatr;     /* =measurement_matrix->data.fl */
    float* MNCovariance;        /* =measurement_noise_cov->data.fl */
    float* PNCovariance;        /* =process_noise_cov->data.fl */
    float* KalmGainMatr;        /* =gain->data.fl */
    float* PriorErrorCovariance;/* =error_cov_pre->data.fl */
    float* PosterErrorCovariance;/* =error_cov_post->data.fl */
    float* Temp1;               /* temp1->data.fl */
    float* Temp2;               /* temp2->data.fl */
#endif

    CvMat* state_pre;           /* predicted state (x'(k)):
                                    x(k)=A*x(k-1)+B*u(k) */
    CvMat* state_post;          /* corrected state (x(k)):
                                    x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */
    CvMat* transition_matrix;   /* state transition matrix (A) */
    CvMat* control_matrix;      /* control matrix (B)
                                   (it is not used if there is no control)*/
    CvMat* measurement_matrix;  /* measurement matrix (H) */
    CvMat* process_noise_cov;   /* process noise covariance matrix (Q) */
    CvMat* measurement_noise_cov; /* measurement noise covariance matrix (R) */
    CvMat* error_cov_pre;       /* priori error estimate covariance matrix (P'(k)):
                                    P'(k)=A*P(k-1)*At + Q*/
    CvMat* gain;                /* Kalman gain matrix (K(k)):
                                    K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/
    CvMat* error_cov_post;      /* posteriori error estimate covariance matrix (P(k)):
                                    P(k)=(I-K(k)*H)*P'(k) */
    CvMat* temp1;               /* temporary matrices */
    CvMat* temp2;
    CvMat* temp3;
    CvMat* temp4;
    CvMat* temp5;
}
CvKalman;
\end{lstlisting}
\else
\begin{description}
\cvarg{MP}{number of measurement vector dimensions}
\cvarg{DP}{number of state vector dimensions}
\cvarg{CP}{number of control vector dimensions}
\cvarg{state\_pre}{predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k)}
\cvarg{state\_post}{corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))}
\cvarg{transition\_matrix}{state transition matrix (A)}
\cvarg{control\_matrix}{control matrix (B) (it is not used if there is no control)}
\cvarg{measurement\_matrix}{measurement matrix (H)}
\cvarg{process\_noise\_cov}{process noise covariance matrix (Q)}
\cvarg{measurement\_noise\_cov}{measurement noise covariance matrix (R)}
\cvarg{error\_cov\_pre}{priori error estimate covariance matrix (P'(k)):  P'(k)=A*P(k-1)*At + Q}
\cvarg{gain}{Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)}
\cvarg{error\_cov\_post}{posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k)}
\end{description}
\fi

The structure \texttt{CvKalman} is used to keep the Kalman filter
state. It is created by the \cvCPyCross{CreateKalman} function, updated
by the \cvCPyCross{KalmanPredict} and \cvCPyCross{KalmanCorrect} functions
\ifC
and released by the \cvCPyCross{ReleaseKalman} function
\fi
. Normally, the
structure is used for the standard Kalman filter (notation and the
formulas below are borrowed from the excellent Kalman tutorial
\cite{Welch95})

\[
\begin{array}{l}
x_k=A \cdot x_{k-1}+B \cdot u_k+w_k\\
z_k=H \cdot x_k+v_k
\end{array}
\]

where:

\[
\begin{array}{l l}
x_k\;(x_{k-1})& \text{state of the system at the moment \emph{k} (\emph{k-1})}\\
z_k & \text{measurement of the system state at the moment \emph{k}}\\
u_k & \text{external control applied at the moment \emph{k}}
\end{array}
\]

$w_k$ and $v_k$ are normally-distributed process and measurement noise, respectively:

\[
\begin{array}{l}
p(w) \sim N(0,Q)\\
p(v) \sim N(0,R)
\end{array}
\]

that is,

$Q$ process noise covariance matrix, constant or variable,

$R$ measurement noise covariance matrix, constant or variable

In the case of the standard Kalman filter, all of the matrices: A, B, H, Q and R are initialized once after the \cvCPyCross{CvKalman} structure is allocated via \cvCPyCross{CreateKalman}. However, the same structure and the same functions may be used to simulate the extended Kalman filter by linearizing the extended Kalman filter equation in the current system state neighborhood, in this case A, B, H (and, probably, Q and R) should be updated on every step.

\cvCPyFunc{CreateKalman}
Allocates the Kalman filter structure.

\cvdefC{
CvKalman* cvCreateKalman( \par int dynam\_params,\par int measure\_params,\par int control\_params=0 );
}

\cvdefPy{CreateKalman(dynam\_params, measure\_params, control\_params=0) -> CvKalman}

\begin{description}
\cvarg{dynam\_params}{dimensionality of the state vector}
\cvarg{measure\_params}{dimensionality of the measurement vector}
\cvarg{control\_params}{dimensionality of the control vector}
\end{description}

The function allocates \cvCPyCross{CvKalman} and all its matrices and initializes them somehow.

\cvCPyFunc{KalmanCorrect}
Adjusts the model state.

\cvdefC{const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement );}
\cvdefPy{KalmanCorrect(kalman, measurement) -> cvmat}

\begin{description}
\ifC
\cvarg{kalman}{Pointer to the structure to be updated}
\else
\cvarg{kalman}{Kalman filter object returned by \cvCPyCross{CreateKalman}}
\fi
\cvarg{measurement}{CvMat containing the measurement vector}
\end{description}

The function adjusts the stochastic model state on the basis of the given measurement of the model state:

\[
\begin{array}{l}
K_k=P'_k \cdot H^T \cdot (H \cdot P'_k \cdot H^T+R)^{-1}\\
x_k=x'_k+K_k \cdot (z_k-H \cdot x'_k)\\
P_k=(I-K_k \cdot H) \cdot P'_k
\end{array}
\]

where

\begin{tabular}{l p{4 in}}
\hline
$z_k$ & given measurement (\texttt{mesurement} parameter)\\ \hline
$K_k$ & Kalman "gain" matrix.\\ \hline
\end{tabular}

The function stores the adjusted state at \texttt{kalman->state\_post} and returns it on output.

\ifC
Example. Using Kalman filter to track a rotating point
\begin{lstlisting}
#include "cv.h"
#include "highgui.h"
#include <math.h>

int main(int argc, char** argv)
{
    /* A matrix data */
    const float A[] = { 1, 1, 0, 1 };

    IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 );
    CvKalman* kalman = cvCreateKalman( 2, 1, 0 );
    /* state is (phi, delta_phi) - angle and angle increment */
    CvMat* state = cvCreateMat( 2, 1, CV_32FC1 );
    CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 );
    /* only phi (angle) is measured */
    CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 );
    CvRandState rng;
    int code = -1;

    cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );

    cvZero( measurement );
    cvNamedWindow( "Kalman", 1 );

    for(;;)
    {
        cvRandSetRange( &rng, 0, 0.1, 0 );
        rng.disttype = CV_RAND_NORMAL;

        cvRand( &rng, state );

        memcpy( kalman->transition_matrix->data.fl, A, sizeof(A));
        cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );
        cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) );
        cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) );
        cvSetIdentity( kalman->error_cov_post, cvRealScalar(1));
        /* choose random initial state */
        cvRand( &rng, kalman->state_post );

        rng.disttype = CV_RAND_NORMAL;

        for(;;)
        {
            #define calc_point(angle)                                      \
                cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)),  \
                         cvRound(img->height/2 - img->width/3*sin(angle)))

            float state_angle = state->data.fl[0];
            CvPoint state_pt = calc_point(state_angle);

            /* predict point position */
            const CvMat* prediction = cvKalmanPredict( kalman, 0 );
            float predict_angle = prediction->data.fl[0];
            CvPoint predict_pt = calc_point(predict_angle);
            float measurement_angle;
            CvPoint measurement_pt;

            cvRandSetRange( &rng,
                            0,
                            sqrt(kalman->measurement_noise_cov->data.fl[0]),
                            0 );
            cvRand( &rng, measurement );

            /* generate measurement */
            cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement );

            measurement_angle = measurement->data.fl[0];
            measurement_pt = calc_point(measurement_angle);

            /* plot points */
            #define draw_cross( center, color, d )                        \
                cvLine( img, cvPoint( center.x - d, center.y - d ),       \
                             cvPoint( center.x + d, center.y + d ),       \
                             color, 1, 0 );                               \
                cvLine( img, cvPoint( center.x + d, center.y - d ),       \
                             cvPoint( center.x - d, center.y + d ),       \
                             color, 1, 0 )

            cvZero( img );
            draw_cross( state_pt, CV_RGB(255,255,255), 3 );
            draw_cross( measurement_pt, CV_RGB(255,0,0), 3 );
            draw_cross( predict_pt, CV_RGB(0,255,0), 3 );
            cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 );

            /* adjust Kalman filter state */
            cvKalmanCorrect( kalman, measurement );

            cvRandSetRange( &rng,
                            0,
                            sqrt(kalman->process_noise_cov->data.fl[0]),
                            0 );
            cvRand( &rng, process_noise );
            cvMatMulAdd( kalman->transition_matrix,
                         state,
                         process_noise,
                         state );

            cvShowImage( "Kalman", img );
            code = cvWaitKey( 100 );

            if( code > 0 ) /* break current simulation by pressing a key */
                break;
        }
        if( code == 27 ) /* exit by ESCAPE */
            break;
    }

    return 0;
}
\end{lstlisting}
\fi

\cvCPyFunc{KalmanPredict}
Estimates the subsequent model state.

\cvdefC{const CvMat* cvKalmanPredict( \par CvKalman* kalman, \par const CvMat* control=NULL);}
\cvdefPy{KalmanPredict(kalman, control=None) -> cvmat}

\begin{description}
\ifC
\cvarg{kalman}{Kalman filter state}
\else
\cvarg{kalman}{Kalman filter object returned by \cvCPyCross{CreateKalman}}
\fi
\cvarg{control}{Control vector $u_k$, should be NULL iff there is no external control (\texttt{control\_params} =0)}
\end{description}

The function estimates the subsequent stochastic model state by its current state and stores it at \texttt{kalman->state\_pre}:

\[
\begin{array}{l}
x'_k=A x_{k-1} + B u_k\\
P'_k=A P_{k-1} A^T + Q
\end{array}
\]

where

\begin{tabular}{l p{5 in}}
\hline
$x'_k$ & is predicted state \texttt{kalman->state\_pre},\\ \hline
$x_{k-1}$ & is corrected state on the previous step \texttt{kalman->state\_post}
                (should be initialized somehow in the beginning, zero vector by default),\\ \hline
$u_k$ & is external control (\texttt{control} parameter),\\ \hline
$P'_k$ & is priori error covariance matrix \texttt{kalman->error\_cov\_pre}\\ \hline
$P_{k-1}$ & is posteriori error covariance matrix on the previous step \texttt{kalman->error\_cov\_post}
                (should be initialized somehow in the beginning, identity matrix by default),
\end{tabular}

The function returns the estimated state.

\subsection{KalmanUpdateByMeasurement}

Synonym for \cross{KalmanCorrect}

\subsection{KalmanUpdateByTime}

Synonym for \cross{KalmanPredict}

\cvCPyFunc{MeanShift}
Finds the object center on back projection.

\cvdefC{
int cvMeanShift( \par const CvArr* prob\_image,\par CvRect window,\par CvTermCriteria criteria,\par CvConnectedComp* comp );
}\cvdefPy{MeanShift(prob\_image,window,criteria)-> comp}

\begin{description}
\cvarg{prob\_image}{Back projection of the object histogram (see \cvCPyCross{CalcBackProject})}
\cvarg{window}{Initial search window}
\cvarg{criteria}{Criteria applied to determine when the window search should be finished}
\cvarg{comp}{Resultant structure that contains the converged search window coordinates (\texttt{comp->rect} field) and the sum of all of the pixels inside the window (\texttt{comp->area} field)}
\end{description}

The function iterates to find the object center
given its back projection and initial position of search window. The
iterations are made until the search window center moves by less than
the given value and/or until the function has done the maximum number
of iterations. The function returns the number of iterations made.

\ifC % {
\cvCPyFunc{ReleaseConDensation}
Deallocates the ConDensation filter structure.

\cvdefC{
void cvReleaseConDensation( CvConDensation** condens );

}
\begin{description}
\cvarg{condens}{Pointer to the pointer to the structure to be released}
\end{description}

The function releases the structure \texttt{condens}) and frees all memory previously allocated for the structure.

\fi % }

\ifC % {

\cvCPyFunc{ReleaseKalman}
Deallocates the Kalman filter structure.

\cvdefC{
void cvReleaseKalman( \par CvKalman** kalman );
}

\begin{description}
\cvarg{kalman}{double pointer to the Kalman filter structure}
\end{description}

The function releases the structure \cvCPyCross{CvKalman} and all of the underlying matrices.

\fi % }

\cvCPyFunc{SegmentMotion}
Segments a whole motion into separate moving parts.

\cvdefC{
CvSeq* cvSegmentMotion( \par const CvArr* mhi,\par CvArr* seg\_mask,\par CvMemStorage* storage,\par double timestamp,\par double seg\_thresh );
}\cvdefPy{SegmentMotion(mhi,seg\_mask,storage,timestamp,seg\_thresh)-> None}

\begin{description}
\cvarg{mhi}{Motion history image}
\cvarg{seg\_mask}{Image where the mask found should be stored, single-channel, 32-bit floating-point}
\cvarg{storage}{Memory storage that will contain a sequence of motion connected components}
\cvarg{timestamp}{Current time in milliseconds or other units}
\cvarg{seg\_thresh}{Segmentation threshold; recommended to be equal to the interval between motion history "steps" or greater}
\end{description}

The function finds all of the motion segments and
marks them in \texttt{seg\_mask} with individual values (1,2,...). It
also returns a sequence of \cvCPyCross{CvConnectedComp}
structures, one for each motion component. After that the
motion direction for every component can be calculated with
\cvCPyCross{CalcGlobalOrientation} using the extracted mask of the particular
component \cvCPyCross{Cmp}.

\cvCPyFunc{SnakeImage}
Changes the contour position to minimize its energy.

\cvdefC{
void cvSnakeImage( \par const IplImage* image,\par CvPoint* points,\par int length,\par float* alpha,\par float* beta,\par float* gamma,\par int coeff\_usage,\par CvSize win,\par CvTermCriteria criteria,\par int calc\_gradient=1 );
}

\cvdefPy{SnakeImage(image,points,alpha,beta,gamma,win,criteria,calc\_gradient=1)-> new\_points}

\begin{description}
\cvarg{image}{The source image or external energy field}
\cvarg{points}{Contour points (snake)}
\ifC
\cvarg{length}{Number of points in the contour}
\cvarg{alpha}{Weight[s] of continuity energy, single float or
array of \texttt{length} floats, one for each contour point}
\else
\cvarg{alpha}{Weight[s] of continuity energy, single float or
a list of floats, one for each contour point}
\fi
\cvarg{beta}{Weight[s] of curvature energy, similar to \texttt{alpha}}
\cvarg{gamma}{Weight[s] of image energy, similar to \texttt{alpha}}
\ifC
\cvarg{coeff\_usage}{Different uses of the previous three parameters:
\begin{description}
  \cvarg{CV\_VALUE}{indicates that each of \texttt{alpha, beta, gamma} is a pointer to a single value to be used for all points;}
  \cvarg{CV\_ARRAY}{indicates that each of \texttt{alpha, beta, gamma} is a pointer to an array of coefficients different for all the points of the snake. All the arrays must have the size equal to the contour size.}
\end{description}}
\fi
\cvarg{win}{Size of neighborhood of every point used to search the minimum, both \texttt{win.width} and \texttt{win.height} must be odd}
\cvarg{criteria}{Termination criteria}
\cvarg{calc\_gradient}{Gradient flag; if not 0, the function calculates the gradient magnitude for every image pixel and consideres it as the energy field, otherwise the input image itself is considered}
\end{description}

The function updates the snake in order to minimize its
total energy that is a sum of internal energy that depends on the contour
shape (the smoother contour is, the smaller internal energy is) and
external energy that depends on the energy field and reaches minimum at
the local energy extremums that correspond to the image edges in the case
of using an image gradient.

The parameter \texttt{criteria.epsilon} is used to define the minimal
number of points that must be moved during any iteration to keep the
iteration process running.

If at some iteration the number of moved points is less
than \texttt{criteria.epsilon} or the function performed
\texttt{criteria.max\_iter} iterations, the function terminates.

\ifPy
The function returns the updated list of points.
\fi

\cvCPyFunc{UpdateMotionHistory}
Updates the motion history image by a moving silhouette.

\cvdefC{
void cvUpdateMotionHistory( \par const CvArr* silhouette,\par CvArr* mhi,\par double timestamp,\par double duration );
}\cvdefPy{UpdateMotionHistory(silhouette,mhi,timestamp,duration)-> None}

\begin{description}
\cvarg{silhouette}{Silhouette mask that has non-zero pixels where the motion occurs}
\cvarg{mhi}{Motion history image, that is updated by the function (single-channel, 32-bit floating-point)}
\cvarg{timestamp}{Current time in milliseconds or other units}
\cvarg{duration}{Maximal duration of the motion track in the same units as \texttt{timestamp}}
\end{description}

The function updates the motion history image as following:

\[
\texttt{mhi}(x,y)=\forkthree
{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}
{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}
{\texttt{mhi}(x,y)}{otherwise}
\]
That is, MHI pixels where motion occurs are set to the current timestamp, while the pixels where motion happened far ago are cleared.

\fi

\ifCpp

\cvCppFunc{calcOpticalFlowPyrLK}
Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids

\cvdefCpp{void calcOpticalFlowPyrLK( const Mat\& prevImg, const Mat\& nextImg,\par
        const vector<Point2f>\& prevPts, vector<Point2f>\& nextPts,\par
        vector<uchar>\& status, vector<float>\& err, \par
        Size winSize=Size(15,15), int maxLevel=3,\par
        TermCriteria criteria=TermCriteria(\par
            TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),\par
        double derivLambda=0.5, int flags=0 );}
\begin{description}
\cvarg{prevImg}{The first 8-bit single-channel or 3-channel input image}
\cvarg{nextImg}{The second input image of the same size and the same type as \texttt{prevImg}}
\cvarg{prevPts}{Vector of points for which the flow needs to be found}
\cvarg{nextPts}{The output vector of points containing the calculated new positions of the input features in the second image}
\cvarg{status}{The output status vector. Each element of the vector is set to 1 if the flow for the corresponding features has been found, 0 otherwise}
\cvarg{err}{The output vector that will contain the difference between patches around the original and moved points}
\cvarg{winSize}{Size of the search window at each pyramid level}
\cvarg{maxLevel}{0-based maximal pyramid level number. If 0, pyramids are not used (single level), if 1, two levels are used etc.}
\cvarg{criteria}{Specifies the termination criteria of the iterative search algorithm (after the specified maximum number of iterations \texttt{criteria.maxCount} or when the search window moves by less than \texttt{criteria.epsilon}}
\cvarg{derivLambda}{The relative weight of the spatial image derivatives impact to the optical flow estimation. If \texttt{derivLambda=0}, only the image intensity is used, if \texttt{derivLambda=1}, only derivatives are used. Any other values between 0 and 1 means that both derivatives and the image intensity are used (in the corresponding proportions).}
\cvarg{flags}{The operation flags:
\begin{description}
  \cvarg{OPTFLOW\_USE\_INITIAL\_FLOW}{use initial estimations stored in \texttt{nextPts}. If the flag is not set, then initially $\texttt{nextPts}\leftarrow\texttt{prevPts}$}
\end{description}}
\end{description}

The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids, see \cite{Bouguet00}.

\cvCppFunc{calcOpticalFlowFarneback}
Computes dense optical flow using Gunnar Farneback's algorithm

\cvdefCpp{void calcOpticalFlowFarneback( const Mat\& prevImg, const Mat\& nextImg,\par
                               Mat\& flow, double pyrScale, int levels, int winsize,\par
                               int iterations, int polyN, double polySigma, int flags );}
\begin{description}
\cvarg{prevImg}{The first 8-bit single-channel input image}
\cvarg{nextImg}{The second input image of the same size and the same type as \texttt{prevImg}}
\cvarg{flow}{The computed flow image; will have the same size as \texttt{prevImg} and type \texttt{CV\_32FC2}}
\cvarg{pyrScale}{Specifies the image scale (<1) to build the pyramids for each image. \texttt{pyrScale=0.5} means the classical pyramid, where each next layer is twice smaller than the previous}
\cvarg{levels}{The number of pyramid layers, including the initial image. \texttt{levels=1} means that no extra layers are created and only the original images are used}
\cvarg{winsize}{The averaging window size; The larger values increase the algorithm robustness to image noise and give more chances for fast motion detection, but yield more blurred motion field}
\cvarg{iterations}{The number of iterations the algorithm does at each pyramid level}
\cvarg{polyN}{Size of the pixel neighborhood used to find polynomial expansion in each pixel. The larger values mean that the image will be approximated with smoother surfaces, yielding more robust algorithm and more blurred  motion field. Typically, \texttt{polyN}=5 or 7}
\cvarg{polySigma}{Standard deviation of the Gaussian that is used to smooth derivatives that are used as a basis for the polynomial expansion. For \texttt{polyN=5} you can set \texttt{polySigma=1.1}, for \texttt{polyN=7} a good value would be \texttt{polySigma=1.5}}
\cvarg{flags}{The operation flags; can be a combination of the following:
\begin{description}
    \cvarg{OPTFLOW\_USE\_INITIAL\_FLOW}{Use the input \texttt{flow} as the initial flow approximation}
    \cvarg{OPTFLOW\_FARNEBACK\_GAUSSIAN}{Use a Gaussian $\texttt{winsize}\times\texttt{winsize}$ filter instead of box filter of the same size for optical flow estimation. Usually, this option gives more accurate flow than with a box filter, at the cost of lower speed (and normally \texttt{winsize} for a Gaussian window should be set to a larger value to achieve the same level of robustness)}
\end{description}}
\end{description}

The function finds optical flow for each \texttt{prevImg} pixel using the alorithm so that

\[\texttt{prevImg}(x,y) \sim \texttt{nextImg}(\texttt{flow}(x,y)[0], \texttt{flow}(x,y)[1])\]

\cvCppFunc{updateMotionHistory}
Updates the motion history image by a moving silhouette.

\cvdefCpp{void updateMotionHistory( const Mat\& silhouette, Mat\& mhi,\par
                          double timestamp, double duration );}
\begin{description}
\cvarg{silhouette}{Silhouette mask that has non-zero pixels where the motion occurs}
\cvarg{mhi}{Motion history image, that is updated by the function (single-channel, 32-bit floating-point)}
\cvarg{timestamp}{Current time in milliseconds or other units}
\cvarg{duration}{Maximal duration of the motion track in the same units as \texttt{timestamp}}
\end{description}

The function updates the motion history image as following:

\[
\texttt{mhi}(x,y)=\forkthree
{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}
{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}
{\texttt{mhi}(x,y)}{otherwise}
\]
That is, MHI pixels where motion occurs are set to the current \texttt{timestamp}, while the pixels where motion happened last time a long time ago are cleared.

The function, together with \cvCppCross{calcMotionGradient} and \cvCppCross{calcGlobalOrientation}, implements the motion templates technique, described in \cite{Davis97} and \cite{Bradski00}.
See also the OpenCV sample \texttt{motempl.c} that demonstrates the use of all the motion template functions.

\cvCppFunc{calcMotionGradient}
Calculates the gradient orientation of a motion history image.

\cvdefCpp{void calcMotionGradient( const Mat\& mhi, Mat\& mask,\par
                         Mat\& orientation,\par
                         double delta1, double delta2,\par
                         int apertureSize=3 );}
\begin{description}
\cvarg{mhi}{Motion history single-channel floating-point image}
\cvarg{mask}{The output mask image; will have the type \texttt{CV\_8UC1} and the same size as \texttt{mhi}. Its non-zero elements will mark pixels where the motion gradient data is correct}
\cvarg{orientation}{The output motion gradient orientation image; will have the same type and the same size as \texttt{mhi}. Each pixel of it will the motion orientation in degrees, from 0 to 360.}
\cvarg{delta1, delta2}{The minimal and maximal allowed difference between \texttt{mhi} values within a pixel neighorhood. That is, the function finds the minimum ($m(x,y)$) and maximum ($M(x,y)$) \texttt{mhi} values over $3 \times 3$ neighborhood of each pixel and marks the motion orientation at $(x, y)$ as valid only if
\[
\min(\texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max(\texttt{delta1} ,\texttt{delta2}).
\]}
\cvarg{apertureSize}{The aperture size of \cvCppCross{Sobel} operator}
\end{description}

The function calculates the gradient orientation at each pixel $(x, y)$ as:

\[
\texttt{orientation}(x,y)=\arctan{\frac{d\texttt{mhi}/dy}{d\texttt{mhi}/dx}}
\]

(in fact, \cvCppCross{fastArctan} and \cvCppCross{phase} are used, so that the computed angle is measured in degrees and covers the full range 0..360). Also, the \texttt{mask} is filled to indicate pixels where the computed angle is valid.

\cvCppFunc{calcGlobalOrientation}
Calculates the global motion orientation in some selected region.

\cvdefCpp{double calcGlobalOrientation( const Mat\& orientation, const Mat\& mask,\par
                              const Mat\& mhi, double timestamp,\par
                              double duration );}
\begin{description}
\cvarg{orientation}{Motion gradient orientation image, calculated by the function \cvCppCross{calcMotionGradient}}
\cvarg{mask}{Mask image. It may be a conjunction of a valid gradient mask, also calculated by \cvCppCross{calcMotionGradient}, and the mask of the region, whose direction needs to be calculated}
\cvarg{mhi}{The motion history image, calculated by \cvCppCross{updateMotionHistory}}
\cvarg{timestamp}{The timestamp passed to \cvCppCross{updateMotionHistory}}
\cvarg{duration}{Maximal duration of motion track in milliseconds, passed to \cvCppCross{updateMotionHistory}}
\end{description}

The function calculates the average
motion direction in the selected region and returns the angle between
0 degrees  and 360 degrees. The average direction is computed from
the weighted orientation histogram, where a recent motion has larger
weight and the motion occurred in the past has smaller weight, as recorded in \texttt{mhi}.

\cvCppFunc{CamShift}
Finds the object center, size, and orientation

\cvdefCpp{RotatedRect CamShift( const Mat\& probImage, Rect\& window,\par
                      TermCriteria criteria );}
\begin{description}
\cvarg{probImage}{Back projection of the object histogram; see \cvCppCross{calcBackProject}}
\cvarg{window}{Initial search window}
\cvarg{criteria}{Stop criteria for the underlying \cvCppCross{meanShift}}
\end{description}

The function implements the CAMSHIFT object tracking algrorithm
\cite{Bradski98}.
First, it finds an object center using \cvCppCross{meanShift} and then adjust the window size and finds the optimal rotation. The function returns the rotated rectangle structure that includes the object position, size and the orientation. The next position of the search window can be obtained with \texttt{RotatedRect::boundingRect()}.

See the OpenCV sample \texttt{camshiftdemo.c} that tracks colored objects.

\cvCppFunc{meanShift}
Finds the object on a back projection image.

\cvdefCpp{int meanShift( const Mat\& probImage, Rect\& window,\par
               TermCriteria criteria );}
\begin{description}
\cvarg{probImage}{Back projection of the object histogram; see \cvCppCross{calcBackProject}}
\cvarg{window}{Initial search window}
\cvarg{criteria}{The stop criteria for the iterative search algorithm}
\end{description}

The function implements iterative object search algorithm. It takes the object back projection on input and the initial position. The mass center in \texttt{window} of the back projection image is computed and the search window center shifts to the mass center. The procedure is repeated until the specified number of iterations \texttt{criteria.maxCount} is done or until the window center shifts by less than \texttt{criteria.epsilon}. The algorithm is used inside \cvCppCross{CamShift} and, unlike \cvCppCross{CamShift}, the search window size or orientation do not change during the search. You can simply pass the output of \cvCppCross{calcBackProject} to this function, but better results can be obtained if you pre-filter the back projection and remove the noise (e.g. by retrieving connected components with \cvCppCross{findContours}, throwing away contours with small area (\cvCppCross{contourArea}) and rendering the  remaining contours with \cvCppCross{drawContours})

\cvclass{KalmanFilter}
Kalman filter class

\begin{lstlisting}
class KalmanFilter
{
public:
    KalmanFilter();
    KalmanFilter(int dynamParams, int measureParams, int controlParams=0);
    void init(int dynamParams, int measureParams, int controlParams=0);
    // predicts statePre from statePost
    const Mat& predict(const Mat& control=Mat());
    // corrects statePre based on the input measurement vector
    // and stores the result to statePost.
    const Mat& correct(const Mat& measurement);

    Mat statePre;           // predicted state (x'(k)):
                            //    x(k)=A*x(k-1)+B*u(k)
    Mat statePost;          // corrected state (x(k)):
                            //    x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
    Mat transitionMatrix;   // state transition matrix (A)
    Mat controlMatrix;      // control matrix (B)
                            //   (it is not used if there is no control)
    Mat measurementMatrix;  // measurement matrix (H)
    Mat processNoiseCov;    // process noise covariance matrix (Q)
    Mat measurementNoiseCov;// measurement noise covariance matrix (R)
    Mat errorCovPre;        // priori error estimate covariance matrix (P'(k)):
                            //    P'(k)=A*P(k-1)*At + Q)*/
    Mat gain;               // Kalman gain matrix (K(k)):
                            //    K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
    Mat errorCovPost;       // posteriori error estimate covariance matrix (P(k)):
                            //    P(k)=(I-K(k)*H)*P'(k)
    ...
};
\end{lstlisting}

The class implements standard Kalman filter \url{http://en.wikipedia.org/wiki/Kalman_filter}. However, you can modify \texttt{transitionMatrix}, \texttt{controlMatrix} and \texttt{measurementMatrix} to get the extended Kalman filter functionality. See the OpenCV sample \texttt{kalman.c}

\fi