\documentclass[a4paper,11pt]{article}%,twocolumn
\input{settings/packages}
\input{settings/page}
\input{settings/jupyter}
\usepackage{fontawesome}
\usepackage{subfigure}

\begin{document}

	\begin{center}
		{\large \textbf{Assignment A05: Object Counting on a Convey Belt}}\\
		Thalagala B.P.\hspace{0.5cm} 180631J
	\end{center}
	\hrule

\section{Introduction}
In this assignment, we will be counting and tracking the hexagonal nuts
on a moving convey belt.

\hypertarget{lets-first-import-required-libraries}{%
\subsection{Import required libraries}\label{lets-first-import-required-libraries}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{1}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k+kn}{import} \PY{n+nn}{cv2} \PY{k}{as} \PY{n+nn}{cv}
\PY{k+kn}{import} \PY{n+nn}{numpy} \PY{k}{as} \PY{n+nn}{np}
\PY{k+kn}{import} \PY{n+nn}{matplotlib}\PY{n+nn}{.}\PY{n+nn}{pyplot} \PY{k}{as} \PY{n+nn}{plt}
\PY{c+c1}{\PYZsh{} magic commands}
\PY{o}{\PYZpc{}}\PY{k}{config} IPCompleter.greedy=True
\PY{o}{\PYZpc{}}\PY{k}{config} Completer.use\PYZus{}jedi = False
\PY{o}{\PYZpc{}}\PY{k}{matplotlib} inline
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{lets-load-and-visualize-the-template-image-and-the-convey-belt-snapshot-at-a-given-time.}{%
\subsection{Load and visualize the template image and the
convey belt snapshot at a given
time}\label{lets-load-and-visualize-the-template-image-and-the-convey-belt-snapshot-at-a-given-time.}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{2}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{template\PYZus{}im} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{imread}\PY{p}{(}\PY{l+s+sa}{r}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{template.png}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{IMREAD\PYZus{}GRAYSCALE}\PY{p}{)}
\PY{n}{belt\PYZus{}im} \PY{o}{=}  \PY{n}{cv}\PY{o}{.}\PY{n}{imread}\PY{p}{(}\PY{l+s+sa}{r}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{belt.png}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{IMREAD\PYZus{}GRAYSCALE}\PY{p}{)}

\PY{n}{fig}\PY{p}{,} \PY{n}{ax} \PY{o}{=} \PY{n}{plt}\PY{o}{.}\PY{n}{subplots}\PY{p}{(}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+m+mi}{2}\PY{p}{,}\PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{10}\PY{p}{,}\PY{l+m+mi}{10}\PY{p}{)}\PY{p}{)}
\PY{n}{ax}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{template\PYZus{}im}\PY{p}{,} \PY{n}{cmap}\PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{gray}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
\PY{n}{ax}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{belt\PYZus{}im}\PY{p}{,} \PY{n}{cmap}\PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{gray}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.5]{figures/output_3_0.png}
    \end{figure}

\section{Part - I}

\hypertarget{otsus-thresholding}{%
\subsection{Otsu's thresholding}\label{otsus-thresholding}}

 Otsu's method avoids having to choose a value and determines an
  optimal global threshold value from the image histogram automatically.
  It is returned as the first output.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{3}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{th\PYZus{}t}\PY{p}{,} \PY{n}{img\PYZus{}t} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{threshold}\PY{p}{(}\PY{n}{template\PYZus{}im}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{255}\PY{p}{,}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}BINARY\PYZus{}INV}\PY{o}{+}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}OTSU}\PY{p}{)}
\PY{n}{th\PYZus{}b}\PY{p}{,} \PY{n}{img\PYZus{}b} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{threshold}\PY{p}{(}\PY{n}{belt\PYZus{}im}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{255}\PY{p}{,}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}BINARY\PYZus{}INV}\PY{o}{+}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}OTSU}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{morphological-closing}{%
\subsection{Morphological closing}\label{morphological-closing}}

Carrying out morphological closing to remove small holes inside the
foreground. Use a $3 \times 3$ kernel. Morphological closing is just dilation followed by erosion.

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist

\item
\textbf{Dilation}: a pixel element is `1' if atleast one pixel under the kernel
is `1'. So it increases the white region
\item
  \textbf{Erosion}: a pixel element is `1' if all the pixel under the kernel is
  `1'. So it decreases the white region

\end{enumerate}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{4}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} 3x3 matrix with all ones, with uint8 dtype}
\PY{n}{kernel} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{getStructuringElement}\PY{p}{(}\PY{n}{cv}\PY{o}{.}\PY{n}{MORPH\PYZus{}RECT}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{)}
\PY{n}{closing\PYZus{}t} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{morphologyEx}\PY{p}{(}\PY{n}{img\PYZus{}t}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{MORPH\PYZus{}CLOSE}\PY{p}{,} \PY{n}{kernel}\PY{p}{)} \PY{c+c1}{\PYZsh{} Dilation followed by Erosion}
\PY{n}{closing\PYZus{}b} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{morphologyEx}\PY{p}{(}\PY{n}{img\PYZus{}b}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{MORPH\PYZus{}CLOSE}\PY{p}{,} \PY{n}{kernel}\PY{p}{)} \PY{c+c1}{\PYZsh{} Dilation followed by Erosion}
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{connected-component-analysis}{%
\subsection{Connected component
analysis}\label{connected-component-analysis}}

Apply the \texttt{cv.connectedComponentsWithStats} function

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{5}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{retval\PYZus{}t}\PY{p}{,} \PY{n}{labels\PYZus{}t}\PY{p}{,} \PY{n}{stats\PYZus{}t}\PY{p}{,} \PY{n}{centroids\PYZus{}t} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{connectedComponentsWithStats}\PY{p}{(}\PY{n}{closing\PYZus{}t}\PY{p}{)}
\PY{n}{retval\PYZus{}b}\PY{p}{,} \PY{n}{labels\PYZus{}b}\PY{p}{,} \PY{n}{stats\PYZus{}b}\PY{p}{,} \PY{n}{centroids\PYZus{}b} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{connectedComponentsWithStats}\PY{p}{(}\PY{n}{closing\PYZus{}b}\PY{p}{)}

\PY{k}{def} \PY{n+nf}{cca\PYZus{}stats}\PY{p}{(}\PY{n}{img\PYZus{}name}\PY{p}{,} \PY{n}{retval}\PY{p}{,} \PY{n}{labels}\PY{p}{,} \PY{n}{stats}\PY{p}{,} \PY{n}{centroids}\PY{p}{)}\PY{p}{:}
    \PY{n+nb}{print}\PY{p}{(}\PY{n}{img\PYZus{}name}\PY{o}{.}\PY{n}{center}\PY{p}{(}\PY{l+m+mi}{50}\PY{p}{,}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{=}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}\PY{p}{)}
    \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Number of labels: }\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{retval}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{labels}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}\PY{p}{,} \PY{n}{cmap} \PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{gray}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}\PY{p}{;} \PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
    \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Stats: }\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{stats}\PY{p}{,}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} stats[label,cv.CC\PYZus{}STAT\PYZus{}quantity])}
    \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Centroids: }\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{centroids}\PY{p}{,}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}

\PY{n}{cca\PYZus{}stats}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Template Image}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{retval\PYZus{}t}\PY{p}{,} \PY{n}{labels\PYZus{}t}\PY{p}{,} \PY{n}{stats\PYZus{}t}\PY{p}{,} \PY{n}{centroids\PYZus{}t}\PY{p}{)}
\PY{n}{cca\PYZus{}stats}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Belt Image}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{retval\PYZus{}b}\PY{p}{,} \PY{n}{labels\PYZus{}b}\PY{p}{,} \PY{n}{stats\PYZus{}b}\PY{p}{,} \PY{n}{centroids\PYZus{}b}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

\begin{figure}[!h]
	\centering
	\subfigure[Template Image]
	{\includegraphics[scale=0.5]{figures/output_9_1.png}
	}
	\subfigure[Belt Image]
	{ \includegraphics[scale=0.5]{figures/output_9_3.png}
	}
\end{figure}

    \begin{Verbatim}[commandchars=\\\{\}]
==================Template Image==================
Number of labels:  2
    \end{Verbatim}

    \begin{Verbatim}[commandchars=\\\{\}]
Stats:
 [[    0     0   286   290 42290]
 [    0     0   286   290 40650]]

Centroids:
 [[142.18770395 145.19172381]
 [142.82489545 143.780369  ]]

====================Belt Image====================
Number of labels:  4
    \end{Verbatim}

    \begin{Verbatim}[commandchars=\\\{\}]
Stats:
 [[      0       0    1600    1200 1798161]
 [    400     100     286     290   40613]
 [   1000     200     286     290   40613]
 [    200     400     286     290   40613]]

Centroids:
 [[ 807.85728475  614.56805258]
 [ 542.82567158  243.78479797]
 [1142.82567158  343.78479797]
 [ 342.82567158  543.78479797]]

    \end{Verbatim}

    \begin{enumerate}
\item
  How many connected components are detected in each image?\\
  \textbf{Template Image} = 2 (\emph{including background})\\ \textbf{Belt
  Image} = 4 (\emph{including background})
\item
  What are the statistics? Interpret these statistics. \\ Statistics are
  properties related to each connected component. Statistics object is a
  2D array where each column represent a different quantity related to a
  given connected component as described below.
  	\begin{itemize}
  		\item \textbf{Column 1:} \emph{cv.CC\_STAT\_LEFT}: the leftmost (x) coordinate
  		which is the inclusive start of the bounding box in the horizontal
  		direction.
  		\item \textbf{Column 2:} \emph{cv.CC\_STAT\_TOP}: the topmost (y)
  		coordinate which is the inclusive start of the bounding box in the
  		vertical direction.
  		\item \textbf{Column 3:} \emph{cv.CC\_STAT\_WIDTH}: the
  		horizontal size of the bounding box.
  		\item \textbf{Column 4:}
  		\emph{cv.CC\_STAT\_HEIGHT}: the vertical size of the bounding box.
  		\item \textbf{Column 5:} \emph{cv.CC\_STAT\_AREA}: the total area (in pixels)
  		of the connected component.
  	\end{itemize}

  \item
  What are the centroids?\\ Each row of the 2D \texttt{Cenroids} obejct
  represents the (x,y) coordinates of centroid of the corresponding
  connected component.
\end{enumerate}

    \hypertarget{contour-analysis}{%
\subsection{Contour analysis}\label{contour-analysis}}

Use \texttt{cv.findContours} function to retrieve the \emph{extreme outer}
contours.\\

The functions output contours is a Python list of all the contours in the image. Each
individual contour is a Numpy array of (x,y) coordinates of boundary
points of the object. Display these countours.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{6}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} cv.RETR\PYZus{}EXTERNAL retrieve only the extreme outer contours}
\PY{n}{contours\PYZus{}t}\PY{p}{,}\PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{findContours}\PY{p}{(}\PY{n}{closing\PYZus{}t}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{RETR\PYZus{}EXTERNAL}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CHAIN\PYZus{}APPROX\PYZus{}SIMPLE}\PY{p}{)}
\PY{n}{contours\PYZus{}b}\PY{p}{,}\PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{findContours}\PY{p}{(}\PY{n}{closing\PYZus{}b}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{RETR\PYZus{}EXTERNAL}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CHAIN\PYZus{}APPROX\PYZus{}SIMPLE}\PY{p}{)}

\PY{c+c1}{\PYZsh{} Visualizing contours (\PYZhy{}1 argument to plot all the contours)}
\PY{n}{im\PYZus{}contours\PYZus{}belt} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{zeros}\PY{p}{(}\PY{p}{(}\PY{n}{belt\PYZus{}im}\PY{o}{.}\PY{n}{shape}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,}\PY{n}{belt\PYZus{}im}\PY{o}{.}\PY{n}{shape}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{,} \PY{n}{np}\PY{o}{.}\PY{n}{uint8}\PY{p}{)}
\PY{n}{conts} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{drawContours}\PY{p}{(}\PY{n}{im\PYZus{}contours\PYZus{}belt}\PY{p}{,} \PY{n}{contours\PYZus{}b}\PY{p}{,} \PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{3}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{conts}\PY{p}{)}\PY{p}{,} \PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.7]{figures/output_12_0.png}
    \end{figure}
    { \hspace*{\fill} \\}

    \hypertarget{count-the-number-of-matching-hexagonal-nuts-in-belt.png.}{%
\subsection{\texorpdfstring{Count the number of matching hexagonal
nuts in
\texttt{belt.png}.}{Count the number of matching hexagonal nuts in belt.png.}}\label{count-the-number-of-matching-hexagonal-nuts-in-belt.png.}}

\texttt{cv.matchShapes} function enables us to compare two shapes, or
two contours and returns a metric showing the similarity. The lower the
result, the better match it is.
\texttt{retval=cv.matchShapes(contour1,\ contour2,\ method,\ parameter)}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{7}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{label} \PY{o}{=} \PY{l+m+mi}{1} \PY{c+c1}{\PYZsh{} remember that the label of the background is 0}
\PY{n}{belt} \PY{o}{=} \PY{p}{(}\PY{p}{(}\PY{n}{labels\PYZus{}b} \PY{o}{\PYZgt{}}\PY{o}{=} \PY{n}{label}\PY{p}{)}\PY{o}{*}\PY{l+m+mi}{255}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{belt}\PY{p}{,} \PY{n}{cmap} \PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{gray}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}\PY{p}{,}\PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\PY{n}{belt\PYZus{}cont}\PY{p}{,}\PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{findContours}\PY{p}{(}\PY{n}{belt}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{RETR\PYZus{}EXTERNAL}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CHAIN\PYZus{}APPROX\PYZus{}SIMPLE}\PY{p}{)}
\PY{k}{for} \PY{n}{j}\PY{p}{,}\PY{n}{c} \PY{o+ow}{in} \PY{n+nb}{enumerate}\PY{p}{(}\PY{n}{belt\PYZus{}cont}\PY{p}{)}\PY{p}{:}
        \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Contour }\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{j} \PY{o}{+}\PY{l+m+mi}{1}\PY{p}{,}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{\PYZhy{}\PYZhy{}\PYZgt{}}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{matchShapes}\PY{p}{(}\PY{n}{contours\PYZus{}t}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,} \PY{n}{c}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CONTOURS\PYZus{}MATCH\PYZus{}I1}\PY{p}{,} \PY{l+m+mf}{0.0}\PY{p}{)}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.7]{figures/output_14_0.png}
    \end{figure}
    { \hspace*{\fill} \\}

    \begin{Verbatim}[commandchars=\\\{\}]
Contour  1 --> 0.00010071698397173812
Contour  2 --> 0.00010071698397950968
Contour  3 --> 0.00010071698397506879
    \end{Verbatim}

    \hypertarget{part---ii}{%
\section{Part - II}\label{part---ii}}

\hypertarget{frame-tracking-through-image-moments.}{%
\subsection{Frame tracking through image
moments.}\label{frame-tracking-through-image-moments.}}

Use the \texttt{cv.contourArea()} to calculate the the area of the \texttt{contours\_b{[}1{]}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{8}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{ca} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{contourArea}\PY{p}{(}\PY{n}{contours\PYZus{}b}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{n}{ca}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
60059.5
    \end{Verbatim}

    Use the \texttt{cv.moments} to extract the x and y coordinates of the
centroid of \texttt{contours\_b{[}1{]}}.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{9}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{M} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{moments}\PY{p}{(}\PY{n}{contours\PYZus{}b}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Area = }\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{)}

\PY{n}{cx}\PY{p}{,} \PY{n}{cy} \PY{o}{=} \PY{n+nb}{int}\PY{p}{(}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m10}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{o}{/}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{)}\PY{p}{,} \PY{n+nb}{int}\PY{p}{(}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m01}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{o}{/}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Centroid = (}\PY{l+s+si}{\PYZob{}\PYZcb{}}\PY{l+s+s2}{, }\PY{l+s+si}{\PYZob{}\PYZcb{}}\PY{l+s+s2}{)}\PY{l+s+s2}{\PYZdq{}}\PY{o}{.}\PY{n}{format}\PY{p}{(}\PY{n}{cx}\PY{p}{,}\PY{n}{cy}\PY{p}{)}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Area =  60059.5
Centroid = (1142, 343)
    \end{Verbatim}

    Make a variable called \texttt{count} to represent the number of
contours and set it to the value 1. Make an np array {[}cx, cy, ca,
count{]} and name this as \texttt{object\_prev\_frame}.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{10}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{count} \PY{o}{=} \PY{l+m+mi}{1}
\PY{n}{object\PYZus{}prev\PYZus{}frame} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{n}{cx}\PY{p}{,} \PY{n}{cy}\PY{p}{,} \PY{n}{ca}\PY{p}{,} \PY{n}{count}\PY{p}{]}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    Similarly, you can create the \texttt{object\_curr\_frame}(to describe
the current values) and define the threshold \texttt{delta\_x} to check
whether the corresponding element of both the
\texttt{object\_curr\_frame} and \texttt{object\_prev\_frame} are less
than the \texttt{delta\_x}. You can set \texttt{delta\_x} as 15 or so.
(Here the \texttt{delta\_x} can be thought of as the movement of the cx
from frame to frame)

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{11}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{delta\PYZus{}x} \PY{o}{=} \PY{l+m+mi}{15}
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{part---iii}{%
\section{Part - III}\label{part---iii}}

\hypertarget{implement-the-function-get_indexed_image-which-takes-an-image-as-the-input-performs-thresholding-closing-and-connected-component-analysis-and-return-retval-labels-stats-centroids.-grading}{%
\subsection{\texorpdfstring{1. Implement the function
\texttt{get\_indexed\_image}, which takes an image as the input,
performs thresholding, closing, and connected component analysis and
return retval, labels, stats, centroids.
(Grading)}{1. Implement the function get\_indexed\_image, which takes an image as the input, performs thresholding, closing, and connected component analysis and return retval, labels, stats, centroids. (Grading)}}\label{implement-the-function-get_indexed_image-which-takes-an-image-as-the-input-performs-thresholding-closing-and-connected-component-analysis-and-return-retval-labels-stats-centroids.-grading}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{12}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k}{def} \PY{n+nf}{get\PYZus{}indexed\PYZus{}image}\PY{p}{(}\PY{n}{im}\PY{p}{)}\PY{p}{:}
    \PY{l+s+sd}{\PYZdq{}\PYZdq{}\PYZdq{} Thresholding, closing, and connected component analysis lumped}
\PY{l+s+sd}{    \PYZdq{}\PYZdq{}\PYZdq{}}

    \PY{n}{\PYZus{}}\PY{p}{,} \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{threshold}\PY{p}{(}\PY{n}{im}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{255}\PY{p}{,}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}BINARY\PYZus{}INV}\PY{o}{+}\PY{n}{cv}\PY{o}{.}\PY{n}{THRESH\PYZus{}OTSU}\PY{p}{)}
    \PY{n}{kernel} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{getStructuringElement}\PY{p}{(}\PY{n}{cv}\PY{o}{.}\PY{n}{MORPH\PYZus{}RECT}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{)}
    \PY{n}{closing} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{morphologyEx}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{MORPH\PYZus{}CLOSE}\PY{p}{,} \PY{n}{kernel}\PY{p}{)} \PY{c+c1}{\PYZsh{} Dilation followed by Erosion}
    \PY{n}{retval}\PY{p}{,} \PY{n}{labels}\PY{p}{,} \PY{n}{stats}\PY{p}{,} \PY{n}{centroids} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{connectedComponentsWithStats}\PY{p}{(}\PY{n}{closing}\PY{p}{)}

    \PY{k}{return} \PY{n}{retval}\PY{p}{,} \PY{n}{labels}\PY{p}{,} \PY{n}{stats}\PY{p}{,} \PY{n}{centroids}
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{implement-the-function-is_new-which-checks-the-dissimilarity-between-2-vectors.-grading}{%
\subsection{\texorpdfstring{2. Implement the function
\texttt{is\_new}, which checks the dissimilarity between 2 vectors.
(Grading)}{2. Implement the function is\_new, which checks the dissimilarity between 2 vectors. (Grading)}}\label{implement-the-function-is_new-which-checks-the-dissimilarity-between-2-vectors.-grading}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{13}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k}{def} \PY{n+nf}{is\PYZus{}new}\PY{p}{(}\PY{n}{a}\PY{p}{,} \PY{n}{b}\PY{p}{,} \PY{n}{delta}\PY{p}{,} \PY{n}{i}\PY{p}{)}\PY{p}{:}
    \PY{l+s+sd}{\PYZdq{}\PYZdq{}\PYZdq{} Vector Dissimilarity with an Array of Vectors}
\PY{l+s+sd}{    Checks if vector b is similar to a one or more vectors in a outside the tolerances specified in delta. }
\PY{l+s+sd}{    vector i specifies which elements in b to compare with those in a. }
\PY{l+s+sd}{    \PYZdq{}\PYZdq{}\PYZdq{}}

    \PY{n}{absolute\PYZus{}different} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{abs}\PY{p}{(}\PY{n}{a} \PY{o}{\PYZhy{}} \PY{n}{b}\PY{p}{)} \PY{c+c1}{\PYZsh{} getting the absolute differences}
    \PY{n}{states} \PY{o}{=} \PY{p}{[}\PY{p}{]} \PY{c+c1}{\PYZsh{} arry to store result of each column}
    \PY{k}{for} \PY{n}{element} \PY{o+ow}{in} \PY{n}{i}\PY{p}{:}
        \PY{c+c1}{\PYZsh{} compare each value in ith column with the specified delta}
        \PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]} \PY{o}{=} \PY{p}{(}\PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]} \PY{o}{\PYZgt{}} \PY{n}{delta}\PY{p}{[}\PY{n}{element}\PY{p}{]}\PY{p}{)}
        \PY{c+c1}{\PYZsh{} check whether the condition is true for all the values in that column}
        \PY{n}{states}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]}\PY{o}{.}\PY{n}{all}\PY{p}{(}\PY{p}{)}\PY{p}{)}

    \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Check whether the absolute different between all the elements of ith column of each array is greater than the ith delta value (See thee example in the next cell)}\PY{l+s+s1}{\PYZsq{}}
    \PY{c+c1}{\PYZsh{} summarize the results of each column to get the final result.}
    \PY{n}{state} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{n}{states}\PY{p}{)}\PY{o}{.}\PY{n}{all}\PY{p}{(}\PY{p}{)}

    \PY{k}{return} \PY{n}{state}
\end{Verbatim}
\end{tcolorbox}
\pagebreak
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{14}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} check is\PYZus{}new  expected answer False}
\PY{n}{a} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{p}{[}\PY{l+m+mf}{1.36100e+03}\PY{p}{,} \PY{l+m+mf}{5.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99245e+04}\PY{p}{,} \PY{l+m+mf}{2.00000e+00}\PY{p}{]}\PY{p}{,}
              \PY{p}{[}\PY{l+m+mf}{7.61000e+02}\PY{p}{,} \PY{l+m+mf}{4.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99385e+04}\PY{p}{,} \PY{l+m+mf}{1.00000e+00}\PY{p}{]}\PY{p}{,}
              \PY{p}{[}\PY{l+m+mf}{1.55200e+03}\PY{p}{,} \PY{l+m+mf}{2.43000e+02}\PY{p}{,} \PY{l+m+mf}{6.00585e+04}\PY{p}{,} \PY{l+m+mf}{3.00000e+00}\PY{p}{]}\PY{p}{]}\PY{p}{)}

\PY{n}{b} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(} \PY{p}{[}\PY{l+m+mf}{7.51000e+02}\PY{p}{,} \PY{l+m+mf}{4.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99385e+04}\PY{p}{,} \PY{l+m+mf}{3.00000e+00}\PY{p}{]}\PY{p}{)}
\PY{n}{delta} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{n}{delta\PYZus{}x}\PY{p}{]}\PY{p}{)}
\PY{n}{i} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}

\PY{k}{assert} \PY{n}{is\PYZus{}new}\PY{p}{(}\PY{n}{a}\PY{p}{,} \PY{n}{b}\PY{p}{,} \PY{n}{delta}\PY{p}{,} \PY{n}{i}\PY{p}{)} \PY{o}{==} \PY{k+kc}{False}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{ Check the function }\PY{l+s+s2}{\PYZdq{}}
\end{Verbatim}
\end{tcolorbox}

    \hypertarget{if-the-array-a-is-in-the-shape-of-number-of-nuts-lenobject_prev_frame-i.e.-array-a-is-made-by-stacking-all-the-object_prev_frame-for-each-frame.-if-b-is-in-the-form-of-cx-cy-ca-count-write-the-function-prev_index-to-find-the-index-of-a-particular-nut-in-the-previous-frame.-grading}{%
\subsection{\texorpdfstring{3. If the array \texttt{a} is in the
shape of (number of nuts , len(object\_prev\_frame)) ( i.e.~array
\texttt{a} is made by stacking all the \texttt{object\_prev\_frame} for
each frame. If b is in the form of {[}cx, cy, ca, count{]}, write the
function \texttt{prev\_index} to find the index of a particular nut in
the previous frame.
(Grading)}{3. If the array a is in the shape of (number of nuts , len(object\_prev\_frame)) ( i.e.~array a is made by stacking all the object\_prev\_frame for each frame. If b is in the form of {[}cx, cy, ca, count{]}, write the function prev\_index to find the index of a particular nut in the previous frame. (Grading)}}\label{if-the-array-a-is-in-the-shape-of-number-of-nuts-lenobject_prev_frame-i.e.-array-a-is-made-by-stacking-all-the-object_prev_frame-for-each-frame.-if-b-is-in-the-form-of-cx-cy-ca-count-write-the-function-prev_index-to-find-the-index-of-a-particular-nut-in-the-previous-frame.-grading}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{15}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k}{def} \PY{n+nf}{prev\PYZus{}index}\PY{p}{(}\PY{n}{a}\PY{p}{,} \PY{n}{b}\PY{p}{,} \PY{n}{delta}\PY{p}{,} \PY{n}{i}\PY{p}{)}\PY{p}{:}
    \PY{l+s+sd}{\PYZdq{}\PYZdq{}\PYZdq{} Returns Previous Index}
\PY{l+s+sd}{    Returns the index of the apppearance of the object in the previous frame.}
\PY{l+s+sd}{    (See thee example in the next cell)}
\PY{l+s+sd}{    \PYZdq{}\PYZdq{}\PYZdq{}}
    \PY{n}{index} \PY{o}{=} \PY{o}{\PYZhy{}}\PY{l+m+mi}{1}
    \PY{n}{absolute\PYZus{}different} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{absolute}\PY{p}{(}\PY{n}{a} \PY{o}{\PYZhy{}} \PY{n}{b}\PY{p}{)}
    \PY{n}{matching\PYZus{}rows} \PY{o}{=} \PY{p}{[}\PY{p}{]}
    \PY{k}{for} \PY{n}{element} \PY{o+ow}{in} \PY{n}{i}\PY{p}{:}
        \PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]} \PY{o}{=} \PY{p}{(}\PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]} \PY{o}{\PYZlt{}}\PY{o}{=} \PY{n}{delta}\PY{p}{[}\PY{n}{element}\PY{p}{]}\PY{p}{)}
        \PY{c+c1}{\PYZsh{} find the row where the above condition is true.}
        \PY{n}{matching\PYZus{}row} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{where}\PY{p}{(}\PY{n}{absolute\PYZus{}different}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{n}{element}\PY{p}{]}\PY{p}{)}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}
        \PY{n}{matching\PYZus{}rows}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{matching\PYZus{}row}\PY{p}{)}

    \PY{c+c1}{\PYZsh{} get the best match out of all the matches}
    \PY{n}{values}\PY{p}{,} \PY{n}{counts} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{unique}\PY{p}{(}\PY{n}{matching\PYZus{}rows}\PY{p}{,} \PY{n}{return\PYZus{}counts}\PY{o}{=}\PY{k+kc}{True}\PY{p}{)}
    \PY{n}{best\PYZus{}match} \PY{o}{=} \PY{n}{values}\PY{p}{[}\PY{n}{np}\PY{o}{.}\PY{n}{argmax}\PY{p}{(}\PY{n}{counts}\PY{p}{)}\PY{p}{]}

    \PY{n}{matching\PYZus{}nut} \PY{o}{=} \PY{n}{a}\PY{p}{[}\PY{n}{best\PYZus{}match}\PY{p}{]}
    \PY{n}{index} \PY{o}{=} \PY{n}{matching\PYZus{}nut}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]} \PY{c+c1}{\PYZsh{} since count keeps the index of a nut.}

    \PY{k}{return} \PY{n}{index}
\end{Verbatim}
\end{tcolorbox}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{16}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} check prev\PYZus{}index  expected answer 1}
\PY{n}{a} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{p}{[}\PY{l+m+mf}{1.36100e+03}\PY{p}{,} \PY{l+m+mf}{5.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99245e+04}\PY{p}{,} \PY{l+m+mf}{2.00000e+00}\PY{p}{]}\PY{p}{,}
              \PY{p}{[}\PY{l+m+mf}{7.61000e+02}\PY{p}{,} \PY{l+m+mf}{4.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99385e+04}\PY{p}{,} \PY{l+m+mf}{1.00000e+00}\PY{p}{]}\PY{p}{,}
              \PY{p}{[}\PY{l+m+mf}{1.55200e+03}\PY{p}{,} \PY{l+m+mf}{2.43000e+02}\PY{p}{,} \PY{l+m+mf}{6.00585e+04}\PY{p}{,} \PY{l+m+mf}{3.00000e+00}\PY{p}{]}\PY{p}{]}\PY{p}{)}

\PY{n}{b} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(} \PY{p}{[}\PY{l+m+mf}{7.51000e+02}\PY{p}{,} \PY{l+m+mf}{4.53000e+02}\PY{p}{,} \PY{l+m+mf}{5.99385e+04}\PY{p}{,} \PY{l+m+mf}{3.00000e+00}\PY{p}{]}\PY{p}{)}
\PY{n}{delta} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{n}{delta\PYZus{}x}\PY{p}{]}\PY{p}{)}
\PY{n}{i} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}

\PY{k}{assert} \PY{n}{prev\PYZus{}index}\PY{p}{(}\PY{n}{a}\PY{p}{,}\PY{n}{b}\PY{p}{,}\PY{n}{delta}\PY{p}{,}\PY{n}{i}\PY{p}{)} \PY{o}{==} \PY{l+m+mi}{1}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{ Check the function }\PY{l+s+s2}{\PYZdq{}}
\end{Verbatim}
\end{tcolorbox}
\pagebreak
    \hypertarget{access-video-frames}{%
\subsection{Access video frames}\label{access-video-frames}}

You can use following code snippet load and access each frame of a video

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{17}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{color\PYZus{}frames} \PY{o}{=} \PY{p}{[}\PY{p}{]} \PY{c+c1}{\PYZsh{} list to store RGB frames}

\PY{n}{cap} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{VideoCapture}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{conveyor\PYZus{}with\PYZus{}rotation.mp4}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} give the correct path here}
\PY{k}{while} \PY{n}{cap}\PY{o}{.}\PY{n}{isOpened}\PY{p}{(}\PY{p}{)}\PY{p}{:}
    \PY{n}{ret}\PY{p}{,} \PY{n}{frame} \PY{o}{=} \PY{n}{cap}\PY{o}{.}\PY{n}{read}\PY{p}{(}\PY{p}{)}
    \PY{k}{if} \PY{o+ow}{not} \PY{n}{ret}\PY{p}{:}
        \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Can}\PY{l+s+s2}{\PYZsq{}}\PY{l+s+s2}{t receive frame (stream end?). Exiting ...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
        \PY{k}{break}
    \PY{n}{color\PYZus{}frames}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{frame}\PY{p}{)}
    \PY{n}{cv}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{n}{frame}\PY{p}{)}
    \PY{k}{if} \PY{n}{cv}\PY{o}{.}\PY{n}{waitKey}\PY{p}{(}\PY{l+m+mi}{1}\PY{p}{)} \PY{o}{==} \PY{n+nb}{ord}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{q}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}\PY{p}{:}
        \PY{k}{break}

\PY{n}{cap}\PY{o}{.}\PY{n}{release}\PY{p}{(}\PY{p}{)}
\PY{n}{cv}\PY{o}{.}\PY{n}{destroyAllWindows}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Can't receive frame (stream end?). Exiting {\ldots}
    \end{Verbatim}

    \hypertarget{implement-a-code-to-detect-hexagonal-nuts-in-a-moving-convey-belt.-grading}{%
\section{Implement a code to detect hexagonal nuts in a moving
convey belt.
(Grading)}\label{implement-a-code-to-detect-hexagonal-nuts-in-a-moving-convey-belt.-grading}}

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist
\item
  Use the above code snippet to access each frame and remember to
  convert the frame into grey scale. Name the variable as \texttt{grey}
\item
  Call \texttt{get\_indexed\_image} and extract
  \texttt{retval,\ labels,\ stats,\ centroids}.
\item
  Find contours of all nuts present in a given frame of the belt.
\item
  Initiate a 3-D array with zeros to draw contours. Call this
  \texttt{im\_contours\_belt}
\item
  Draw each contour. Use \texttt{cv.drawContours}.
  \href{https://docs.opencv.org/master/d4/d73/tutorial_py_contours_begin.html}{See
  this}
\end{enumerate}
\pagebreak
\subsection{Accessing each frame and convert them into gray scale}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{18}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{gray\PYZus{}frames} \PY{o}{=} \PY{p}{[}\PY{p}{]}  \PY{c+c1}{\PYZsh{} list to store Gray Scale frames}
\PY{n}{cap} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{VideoCapture}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{conveyor\PYZus{}with\PYZus{}rotation.mp4}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} give the correct path here}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Video capturing is in progress...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\PY{k}{while} \PY{n}{cap}\PY{o}{.}\PY{n}{isOpened}\PY{p}{(}\PY{p}{)}\PY{p}{:}
    \PY{n}{ret}\PY{p}{,} \PY{n}{frame} \PY{o}{=} \PY{n}{cap}\PY{o}{.}\PY{n}{read}\PY{p}{(}\PY{p}{)}
    \PY{k}{if} \PY{o+ow}{not} \PY{n}{ret}\PY{p}{:}
        \PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Can}\PY{l+s+s2}{\PYZsq{}}\PY{l+s+s2}{t receive frame (stream end?). Exiting ...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
        \PY{k}{break}
    \PY{n}{frame} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{cvtColor}\PY{p}{(}\PY{n}{frame}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{COLOR\PYZus{}BGR2GRAY}\PY{p}{)} \PY{c+c1}{\PYZsh{} convert to grayscale}
    \PY{n}{gray\PYZus{}frames}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{frame}\PY{p}{)} \PY{c+c1}{\PYZsh{} store the grayscale frame images}

    \PY{k}{if} \PY{n}{cv}\PY{o}{.}\PY{n}{waitKey}\PY{p}{(}\PY{l+m+mi}{1}\PY{p}{)} \PY{o}{==} \PY{n+nb}{ord}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{q}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}\PY{p}{:} \PY{c+c1}{\PYZsh{}keyboard interruption}
        \PY{k}{break}

\PY{n}{cap}\PY{o}{.}\PY{n}{release}\PY{p}{(}\PY{p}{)}
\PY{n}{cv}\PY{o}{.}\PY{n}{destroyAllWindows}\PY{p}{(}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Video capturing completed.}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Video capturing is in progress{\ldots}
Can't receive frame (stream end?). Exiting {\ldots}
Video capturing completed.
    \end{Verbatim}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{19}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} visualizing some of the captured frames}
\PY{n}{plt}\PY{o}{.}\PY{n}{figure}\PY{p}{(}\PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{30}\PY{p}{,}\PY{l+m+mi}{20}\PY{p}{)}\PY{p}{)}
\PY{k}{for} \PY{n}{i} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{9}\PY{p}{)}\PY{p}{:}
    \PY{n}{plt}\PY{o}{.}\PY{n}{subplot}\PY{p}{(}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{,}\PY{n}{i}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{gray\PYZus{}frames}\PY{p}{[}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{]}\PY{p}{,} \PY{n}{cmap} \PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{gray}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{xlabel}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame }\PY{l+s+s2}{\PYZdq{}} \PY{o}{+} \PY{n+nb}{str}\PY{p}{(}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{)}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.3]{figures/output_35_0.png}
    \end{figure}
    { \hspace*{\fill} \\}

\subsection{Finding contours of all connected components in a given frame}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{20}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} Find contours of all nuts present in a given frame of the belt}
\PY{n}{contour\PYZus{}plots} \PY{o}{=} \PY{p}{[}\PY{p}{]}
\PY{n}{contours\PYZus{}list} \PY{o}{=} \PY{p}{[}\PY{p}{]}
\PY{k}{for} \PY{n}{gray} \PY{o+ow}{in} \PY{n}{gray\PYZus{}frames}\PY{p}{:}
    \PY{c+c1}{\PYZsh{} finding contours}
    \PY{n}{\PYZus{}}\PY{p}{,} \PY{n}{labels}\PY{p}{,} \PY{n}{\PYZus{}}\PY{p}{,} \PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{get\PYZus{}indexed\PYZus{}image}\PY{p}{(}\PY{n}{gray}\PY{p}{)} \PY{c+c1}{\PYZsh{} Conn: Comp: Analysis}
    \PY{n}{belt} \PY{o}{=} \PY{p}{(}\PY{p}{(}\PY{n}{labels} \PY{o}{\PYZgt{}}\PY{o}{=} \PY{l+m+mi}{1}\PY{p}{)}\PY{o}{*}\PY{l+m+mi}{255}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
    \PY{n}{contours}\PY{p}{,}\PY{n}{\PYZus{}}  \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{findContours}\PY{p}{(}\PY{n}{belt}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{RETR\PYZus{}EXTERNAL}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CHAIN\PYZus{}APPROX\PYZus{}SIMPLE}\PY{p}{)}
    \PY{n}{contours\PYZus{}list}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{contours}\PY{p}{)}
    \PY{c+c1}{\PYZsh{} plotting contours}
    \PY{n}{im\PYZus{}contours\PYZus{}belt} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{zeros}\PY{p}{(}\PY{p}{(}\PY{n}{belt}\PY{o}{.}\PY{n}{shape}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,}\PY{n}{belt}\PY{o}{.}\PY{n}{shape}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{)}\PY{p}{,} \PY{n}{np}\PY{o}{.}\PY{n}{uint8}\PY{p}{)}
    \PY{n}{cont\PYZus{}plot} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{drawContours}\PY{p}{(}\PY{n}{im\PYZus{}contours\PYZus{}belt}\PY{p}{,} \PY{n}{contours}\PY{p}{,} \PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{5}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
    \PY{n}{contour\PYZus{}plots}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{cont\PYZus{}plot}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{21}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} visualizing some of the contour plots on frames}
\PY{n}{plt}\PY{o}{.}\PY{n}{figure}\PY{p}{(}\PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{30}\PY{p}{,}\PY{l+m+mi}{20}\PY{p}{)}\PY{p}{)}
\PY{k}{for} \PY{n}{i} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{9}\PY{p}{)}\PY{p}{:}
    \PY{n}{plt}\PY{o}{.}\PY{n}{subplot}\PY{p}{(}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{,}\PY{n}{i}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{contour\PYZus{}plots}\PY{p}{[}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{]}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{xlabel}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame }\PY{l+s+s2}{\PYZdq{}} \PY{o}{+} \PY{n+nb}{str}\PY{p}{(}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{)}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.3]{figures/output_37_0.png}
    \end{figure}
    { \hspace*{\fill} \\}
\pagebreak
    \hypertarget{object-detection-and-tracking}{%
\section{Object detection and
tracking}\label{object-detection-and-tracking}}

For each contour of the belt frame,

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist
\item
  Use \texttt{is\_new} and \texttt{prev\_index} functions to track each
  frame and get the indices of each nut.
\item
  Write a code to detect and track hexagonal nuts in each frame.
\end{enumerate}

\textbf{Hint}: \emph{If you are thresholding on areas (template and
contour) you can use 500 as the threshold. You can set the matching
threshold to be 0.5 and experiment}.
\subsection{Extracting details about each contour in each frame}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{22}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} frame tracking through image moments}
\PY{c+c1}{\PYZsh{} extracting details about each contour in each frame}
\PY{n}{video} \PY{o}{=} \PY{p}{[}\PY{p}{]}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Details extraction is in progress...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\PY{k}{for} \PY{n}{gray} \PY{o+ow}{in} \PY{n}{gray\PYZus{}frames}\PY{p}{:}
    \PY{c+c1}{\PYZsh{} finding contours}
    \PY{n}{\PYZus{}}\PY{p}{,} \PY{n}{labels}\PY{p}{,} \PY{n}{\PYZus{}}\PY{p}{,} \PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{get\PYZus{}indexed\PYZus{}image}\PY{p}{(}\PY{n}{gray}\PY{p}{)}
    \PY{n}{belt} \PY{o}{=} \PY{p}{(}\PY{p}{(}\PY{n}{labels} \PY{o}{\PYZgt{}}\PY{o}{=} \PY{l+m+mi}{1}\PY{p}{)}\PY{o}{*}\PY{l+m+mi}{255}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}
    \PY{n}{contours}\PY{p}{,}\PY{n}{\PYZus{}}  \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{findContours}\PY{p}{(}\PY{n}{belt}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{RETR\PYZus{}EXTERNAL}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CHAIN\PYZus{}APPROX\PYZus{}SIMPLE}\PY{p}{)}

    \PY{n}{count} \PY{o}{=} \PY{l+m+mi}{0} \PY{c+c1}{\PYZsh{} number of nuts in a given frame}
    \PY{n}{frame} \PY{o}{=} \PY{p}{[}\PY{p}{]}

    \PY{k}{for} \PY{n}{contour} \PY{o+ow}{in} \PY{n}{contours}\PY{p}{:}
        \PY{n}{metric} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{matchShapes}\PY{p}{(}\PY{n}{contours\PYZus{}t}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,} \PY{n}{contour}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{CONTOURS\PYZus{}MATCH\PYZus{}I1}\PY{p}{,} \PY{l+m+mf}{0.0}\PY{p}{)}
        \PY{c+c1}{\PYZsh{} Set the matching threshold to be 0.5}
        \PY{k}{if} \PY{n}{metric} \PY{o}{\PYZlt{}}\PY{o}{=} \PY{l+m+mf}{0.5}\PY{p}{:} \PY{c+c1}{\PYZsh{} if only a complete hexagonal nut}
            \PY{n}{count} \PY{o}{+}\PY{o}{=}\PY{l+m+mi}{1}
            \PY{n}{M}  \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{moments}\PY{p}{(}\PY{n}{contour}\PY{p}{)}
            \PY{n}{ca} \PY{o}{=} \PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}
            \PY{n}{cx}\PY{p}{,} \PY{n}{cy} \PY{o}{=} \PY{n+nb}{int}\PY{p}{(}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m10}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{o}{/}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{)}\PY{p}{,} \PY{n+nb}{int}\PY{p}{(}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m01}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{o}{/}\PY{n}{M}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{m00}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{)}
            \PY{n}{frame}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{n}{cx}\PY{p}{,} \PY{n}{cy}\PY{p}{,} \PY{n}{ca}\PY{p}{,} \PY{n}{count}\PY{p}{]}\PY{p}{)}\PY{p}{)}

    \PY{n}{video}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{frame}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Details extraction completed.}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Details extraction is in progress{\ldots}
Details extraction completed.
    \end{Verbatim}
\pagebreak
\subsection{Nut counter Implementation}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{23}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} Nut counter Implementation}
\PY{c+c1}{\PYZsh{} last element keeps the number of nuts in a given frame. }
\PY{c+c1}{\PYZsh{} Therefore, initial number of nuts is as follows.}
\PY{n}{total\PYZus{}nuts} \PY{o}{=} \PY{n+nb}{int}\PY{p}{(}\PY{n}{video}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Number of nuts in the zeroth frame: }\PY{l+s+s2}{\PYZdq{}}\PY{p}{,}\PY{n}{total\PYZus{}nuts}\PY{p}{)}

\PY{n}{delta\PYZus{}x} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{15}\PY{p}{]}\PY{p}{)}
\PY{n}{i} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}

\PY{n}{prev\PYZus{}frame} \PY{o}{=} \PY{n}{video}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]} \PY{c+c1}{\PYZsh{} Reference frame to compare with the upcoming frame}

\PY{k}{for} \PY{n}{frame\PYZus{}num} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{1}\PY{p}{,} \PY{n+nb}{len}\PY{p}{(}\PY{n}{video}\PY{p}{)}\PY{p}{)}\PY{p}{:}
    \PY{n}{current\PYZus{}frame} \PY{o}{=} \PY{n}{video}\PY{p}{[}\PY{n}{frame\PYZus{}num}\PY{p}{]} \PY{c+c1}{\PYZsh{} frame to be compared    }

    \PY{k}{for} \PY{n}{nut} \PY{o+ow}{in} \PY{n}{current\PYZus{}frame}\PY{p}{:}
        \PY{c+c1}{\PYZsh{} Checking the current nut with previous frame}
        \PY{c+c1}{\PYZsh{} if it is a new nut count it.}
        \PY{k}{if} \PY{n}{is\PYZus{}new}\PY{p}{(}\PY{n}{prev\PYZus{}frame}\PY{p}{,} \PY{n}{nut}\PY{p}{,} \PY{n}{delta\PYZus{}x}\PY{p}{,} \PY{n}{i}\PY{p}{)}\PY{p}{:}
            \PY{n}{total\PYZus{}nuts} \PY{o}{+}\PY{o}{=}\PY{l+m+mi}{1}

    \PY{n}{prev\PYZus{}frame} \PY{o}{=} \PY{n}{current\PYZus{}frame}

\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Total number of nuts found: }\PY{l+s+s2}{\PYZdq{}}\PY{p}{,}\PY{n}{total\PYZus{}nuts}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Number of nuts in the zeroth frame:  1
Total number of nuts found:  5
    \end{Verbatim}
\subsection{Tracking nuts: An extension of the previous nut counting algorithm}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{24}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} trackig nuts: An extension of the previous counting nuts algorithm}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Detection and indexing is in progress...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\PY{n}{total\PYZus{}nuts} \PY{o}{=} \PY{n+nb}{int}\PY{p}{(}\PY{n}{video}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)} \PY{c+c1}{\PYZsh{}initial number of nuts in frame 0}
\PY{n}{delta\PYZus{}x} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{15}\PY{p}{]}\PY{p}{)}
\PY{n}{i} \PY{o}{=} \PY{n}{np}\PY{o}{.}\PY{n}{array}\PY{p}{(}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}
\PY{n}{prev\PYZus{}frame} \PY{o}{=} \PY{n}{video}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]} \PY{c+c1}{\PYZsh{} Reference frame to compare with the upcoming frame}

\PY{k}{for} \PY{n}{frame\PYZus{}num} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{1}\PY{p}{,} \PY{n+nb}{len}\PY{p}{(}\PY{n}{video}\PY{p}{)}\PY{p}{)}\PY{p}{:}
    \PY{n}{current\PYZus{}frame} \PY{o}{=} \PY{n}{video}\PY{p}{[}\PY{n}{frame\PYZus{}num}\PY{p}{]} \PY{c+c1}{\PYZsh{} frame to be compared}

    \PY{k}{for} \PY{n}{nut} \PY{o+ow}{in} \PY{n}{current\PYZus{}frame}\PY{p}{:}
        \PY{c+c1}{\PYZsh{} Checking the current nut with previous frame}
        \PY{c+c1}{\PYZsh{} if it is a new nut count it and assign a new index}
        \PY{k}{if} \PY{n}{is\PYZus{}new}\PY{p}{(}\PY{n}{prev\PYZus{}frame}\PY{p}{,} \PY{n}{nut}\PY{p}{,} \PY{n}{delta\PYZus{}x}\PY{p}{,} \PY{n}{i}\PY{p}{)}\PY{p}{:}
            \PY{n}{total\PYZus{}nuts} \PY{o}{+}\PY{o}{=}\PY{l+m+mi}{1}
            \PY{n}{nut}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]} \PY{o}{=} \PY{n}{total\PYZus{}nuts} \PY{c+c1}{\PYZsh{} assignment of a new index}

        \PY{k}{else}\PY{p}{:}
            \PY{c+c1}{\PYZsh{} to be tracked the nut must not be a new nut}
            \PY{n}{nut\PYZus{}index} \PY{o}{=} \PY{n}{prev\PYZus{}index}\PY{p}{(}\PY{n}{prev\PYZus{}frame}\PY{p}{,} \PY{n}{nut}\PY{p}{,} \PY{n}{delta\PYZus{}x}\PY{p}{,} \PY{n}{i}\PY{p}{)}
            \PY{n}{nut}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]} \PY{o}{=} \PY{n}{nut\PYZus{}index} \PY{c+c1}{\PYZsh{} assign the same index it had previously, for old nuts}

    \PY{n}{prev\PYZus{}frame} \PY{o}{=} \PY{n}{current\PYZus{}frame}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Detection and indexing completed.}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Detection and indexing is in progress{\ldots}
Detection and indexing completed.
    \end{Verbatim}
\subsection{Frame annotation with the extracted details}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{25}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} frame annotation with the extracted details}

\PY{n}{annotated\PYZus{}frames} \PY{o}{=}\PY{p}{[}\PY{p}{]}
\PY{n}{frame\PYZus{}num} \PY{o}{=} \PY{l+m+mi}{0}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame annotation is in progress...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\PY{k}{for} \PY{n}{frame}\PY{p}{,} \PY{n}{color\PYZus{}frame}\PY{p}{,} \PY{n}{contours} \PY{o+ow}{in} \PY{n+nb}{zip}\PY{p}{(}\PY{n}{video}\PY{p}{,} \PY{n}{color\PYZus{}frames}\PY{p}{,} \PY{n}{contours\PYZus{}list}\PY{p}{)}\PY{p}{:}

    \PY{c+c1}{\PYZsh{} Annotation was done on the frames of the original video}
    \PY{n}{img} \PY{o}{=} \PY{n}{color\PYZus{}frame}
    \PY{n}{y} \PY{o}{=} \PY{l+m+mi}{0} \PY{c+c1}{\PYZsh{} to change the vertical position of \PYZsq{}object details\PYZsq{} of a frame}

    \PY{k}{for} \PY{n}{nut} \PY{o+ow}{in} \PY{n}{frame}\PY{p}{:}
        \PY{c+c1}{\PYZsh{} Annotate the nut index}
        \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{putText}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{n+nb}{str}\PY{p}{(}\PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}\PY{p}{)}\PY{p}{,}\PYZbs{}
                \PY{p}{(}\PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}\PY{p}{,}\PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}\PY{p}{)}\PY{p}{,}\PY{n}{cv}\PY{o}{.}\PY{n}{FONT\PYZus{}HERSHEY\PYZus{}SIMPLEX}\PY{p}{,} \PY{l+m+mi}{2}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{4}\PY{p}{)}
        \PY{c+c1}{\PYZsh{} Annotate the nut(object) details}
        \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{putText}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Object }\PY{l+s+si}{\PYZob{}\PYZcb{}}\PY{l+s+s2}{: }\PY{l+s+si}{\PYZob{}:04\PYZcb{}}\PY{l+s+s2}{ }\PY{l+s+si}{\PYZob{}:04\PYZcb{}}\PY{l+s+s2}{ }\PY{l+s+si}{\PYZob{}:05\PYZcb{}}\PY{l+s+s2}{\PYZdq{}}\PY{o}{.}\PY{n}{format}\PY{p}{(}\PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}\PY{p}{,} \PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}\PY{p}{,} \PY{n+nb}{int}\PY{p}{(}\PY{n}{nut}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}\PY{p}{,} \PY{n}{nut}\PY{p}{[}\PY{l+m+mi}{2}\PY{p}{]}\PY{p}{)}\PY{p}{,}\PYZbs{}
                         \PY{p}{(}\PY{l+m+mi}{50}\PY{p}{,}\PY{l+m+mi}{850} \PY{o}{+} \PY{l+m+mi}{70}\PY{o}{*}\PY{n}{y}\PY{p}{)}\PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{FONT\PYZus{}HERSHEY\PYZus{}SIMPLEX}\PY{p}{,} \PY{l+m+mi}{2}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{4}\PY{p}{)}

        \PY{n}{y} \PY{o}{+}\PY{o}{=}\PY{l+m+mi}{1} \PY{c+c1}{\PYZsh{} change vertical position for next object details annotation.}

    \PY{c+c1}{\PYZsh{} Annotation of the frame number and draw the extracted contours}
    \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{putText}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame }\PY{l+s+s2}{\PYZdq{}}\PY{o}{+}\PY{n+nb}{str}\PY{p}{(}\PY{n}{frame\PYZus{}num}\PY{p}{)} \PY{p}{,} \PY{p}{(}\PY{l+m+mi}{50}\PY{p}{,}\PY{l+m+mi}{750}\PY{p}{)} \PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{FONT\PYZus{}HERSHEY\PYZus{}SIMPLEX}\PY{p}{,} \PY{l+m+mi}{2}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{3}\PY{p}{)}
    \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{drawContours}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{n}{contours}\PY{p}{,} \PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{5}\PY{p}{)}\PY{o}{.}\PY{n}{astype}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{uint8}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)}

    \PY{c+c1}{\PYZsh{} Index number 180631J}
    \PY{n}{img} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{putText}\PY{p}{(}\PY{n}{img}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{180631J}\PY{l+s+s2}{\PYZdq{}} \PY{p}{,} \PY{p}{(}\PY{l+m+mi}{50}\PY{p}{,}\PY{l+m+mi}{150}\PY{p}{)} \PY{p}{,} \PY{n}{cv}\PY{o}{.}\PY{n}{FONT\PYZus{}HERSHEY\PYZus{}SIMPLEX}\PY{p}{,} \PY{l+m+mi}{2}\PY{p}{,} \PY{p}{(}\PY{l+m+mi}{255}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{,}\PY{l+m+mi}{0}\PY{p}{)}\PY{p}{,} \PY{l+m+mi}{3}\PY{p}{)}
    \PY{n}{annotated\PYZus{}frames}\PY{o}{.}\PY{n}{append}\PY{p}{(}\PY{n}{img}\PY{p}{)}
    \PY{n}{frame\PYZus{}num} \PY{o}{+}\PY{o}{=}\PY{l+m+mi}{1}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame annotation completed.}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Frame annotation is in progress{\ldots}
Frame annotation completed.
    \end{Verbatim}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{26}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} visulaizing some annotated frames }
\PY{n}{plt}\PY{o}{.}\PY{n}{figure}\PY{p}{(}\PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{30}\PY{p}{,}\PY{l+m+mi}{20}\PY{p}{)}\PY{p}{)}
\PY{k}{for} \PY{n}{i} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{9}\PY{p}{)}\PY{p}{:}
    \PY{n}{plt}\PY{o}{.}\PY{n}{subplot}\PY{p}{(}\PY{l+m+mi}{3}\PY{p}{,}\PY{l+m+mi}{3}\PY{p}{,}\PY{n}{i}\PY{o}{+}\PY{l+m+mi}{1}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{imshow}\PY{p}{(}\PY{n}{annotated\PYZus{}frames}\PY{p}{[}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{]}\PY{p}{[}\PY{p}{:}\PY{p}{,}\PY{p}{:}\PY{p}{,}\PY{p}{:}\PY{p}{:}\PY{o}{\PYZhy{}}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
    \PY{n}{plt}\PY{o}{.}\PY{n}{xlabel}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Frame }\PY{l+s+s2}{\PYZdq{}} \PY{o}{+} \PY{n+nb}{str}\PY{p}{(}\PY{l+m+mi}{100} \PY{o}{+}\PY{n}{i}\PY{p}{)}\PY{p}{)}
\PY{n}{plt}\PY{o}{.}\PY{n}{show}\PY{p}{(}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{figure}[!h]
		\centering
    \includegraphics[scale=0.3]{figures/output_43_0.png}
    \end{figure}
    { \hspace*{\fill} \\}
\pagebreak
    \hypertarget{save-the-frames-as-a-video}{%
\subsection{Save the frames as a
video}\label{save-the-frames-as-a-video}}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{27}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{c+c1}{\PYZsh{} Defining necessary parameters for video write}

\PY{n}{output} \PY{o}{=} \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{180631j\PYZus{}en2550\PYZus{}a05.mp4}\PY{l+s+s1}{\PYZsq{}} \PY{c+c1}{\PYZsh{} Name of the output video file.}
\PY{n}{fourcc} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{VideoWriter\PYZus{}fourcc}\PY{p}{(}\PY{o}{*}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{MP4V}\PY{l+s+s1}{\PYZsq{}}\PY{p}{)} \PY{c+c1}{\PYZsh{} 4\PYZhy{}character code of codec used to compress the frames}
\PY{n}{duration} \PY{o}{=} \PY{l+m+mi}{9} \PY{c+c1}{\PYZsh{} duration of the source video}
\PY{n}{fps} \PY{o}{=} \PY{n+nb}{int}\PY{p}{(}\PY{n+nb}{len}\PY{p}{(}\PY{n}{annotated\PYZus{}frames}\PY{p}{)}\PY{o}{/}\PY{n}{duration}\PY{p}{)} \PY{c+c1}{\PYZsh{} Framerate of the created video stream}
\PY{n}{height}\PY{p}{,} \PY{n}{width}\PY{p}{,}\PY{n}{\PYZus{}} \PY{o}{=} \PY{n}{annotated\PYZus{}frames}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{o}{.}\PY{n}{shape}
\PY{n}{frame\PYZus{}size} \PY{o}{=} \PY{p}{(}\PY{n}{width}\PY{p}{,} \PY{n}{height}\PY{p}{)}
\PY{n}{isColor} \PY{o}{=} \PY{k+kc}{True} \PY{c+c1}{\PYZsh{} to write color images to the video}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Frame Size(WxH) :}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{frame\PYZus{}size} \PY{p}{,}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s+s1}{Frames Per Second :}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{fps}\PY{p}{)}

\PY{c+c1}{\PYZsh{} Creating the Video Writer object}
\PY{n}{out} \PY{o}{=} \PY{n}{cv}\PY{o}{.}\PY{n}{VideoWriter}\PY{p}{(}\PY{n}{output}\PY{p}{,} \PY{n}{fourcc}\PY{p}{,} \PY{n}{fps}\PY{p}{,} \PY{n}{frame\PYZus{}size}\PY{p}{,} \PY{n}{isColor}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Video writer in progress...}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\PY{k}{for} \PY{n}{frame} \PY{o+ow}{in} \PY{n}{annotated\PYZus{}frames}\PY{p}{:}
    \PY{n}{out}\PY{o}{.}\PY{n}{write}\PY{p}{(}\PY{n}{frame}\PY{p}{)}

\PY{c+c1}{\PYZsh{} Release everything if job is finished}
\PY{n}{out}\PY{o}{.}\PY{n}{release}\PY{p}{(}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Video writing completed.}\PY{l+s+s2}{\PYZdq{}}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]
Frame Size(WxH) : (1920, 1080)
Frames Per Second : 31
Video writer in progress{\ldots}
Video writing completed.
    \end{Verbatim}

\vfill
    % Add a bibliography block to the postdoc
 \begin{center}
	\textit{ \textbf{-- Executable code can be found on}} \href{https://github.com/bimalka98/Computer-Vision-and-Image-Processing/blob/main/EN2550Assignments/A5/180631j_en2550_a05.ipynb}{\faGithub} \textbf{\textit{--}}
\end{center}

\end{document}


%!TEX root =  ../main.tex

\indexedSection{Sets}\label{sec:Sets}

\objective{Manipulate and create sets and intervals using set-builder notation.}

In this section, we will review how to describe regions of numbers and sets.

\begin{derivation}{Set}
A \gls{set} is a well-defined collection of distinct objects, and is considered as an
object in its own right.  ``Well-defined''
means it is readily apparent to anyone if an object is or is not part of the set.
\end{derivation}

An object in a set is called an ``element''.  If $A = \{1, 2, 5\}$ then the
elements of $A$ are 1, 2, and 5\footnote{Notice that the convention is to
choose capital letters close to the start of the alphabet for set names, and then
delimit the entries in a comma-separated list, inside curly brackets.}.  We may
also say $5 \in A$, which pronounced aloud as ``five is an element
of $A$''\footnote{You might remember this symbol
by noting how much it looks like a capital E, which is the first letter
of ``element'', as in ``is an element of''.}.  If set $B$ is
defined as $B=\{1,2\}$, then we can say $B \subseteq A$, that is, ``$B$ is a
subset of $A$''.  $\varnothing$ is the symbol for the
null set, also called the empty set, i.e. the set with no elements.

With these tools for sets, we may define variables using \gls{set-builder notation}.
For example, we might say:
\begin{equation}
\{ x | x > 0, x \in \{-3, -2, -1, 0, 1, 2, 3\}\}
\end{equation}

You should read A.1 if it were the prose paragraph, ``There is a variable $x$ such
that $x$ is greater than 0,
and $x$ is in the set from -3 to 3.''  Can you figure out what $x$ is actually equal to?
All that was a very
long way to write that $x = \{1,2,3\}$!  Why would anyone write this way?
The power of this notation becomes
obvious later, when we bring in infinite sets.  To begin with, we will use ``. . .''
(called an ``ellipsis'') to make infinite sets that keep going as before.

\begin{derivation}{Set-Builder Notation}
A subject and a predicate, separated by a pipe and enclosed in curly-brackets.
\end{derivation}

\begin{example}
\exProblem
Use set-builder notation to describe all the odd numbers greater than 3.

\exSolution
Odd numbers are one unit away from even numbers, which are themselves two times \textit{any} number.
\begin{align*}
\{ x | x \in \{5, 7, 9, ...\} \} \\
\{ 2x + 1 | x \in \{2, 3, 4, ...\} \} \\
\{ 2x + 1 | x>2, x \in \{1, 2, 3, ...\} \}
\end{align*}
\end{example}

\subsection{Union and Intersection}
Lastly, sets may be joined, looking only for the overlap, or united, look for anything in either.
The overlap is called ``intersection'' and is symbolized with a $\cap$, while
``anything in either'' is called ``union'' and
is symbolized with a $\cup$.  This can be most easily visualized via Venn diagrams:

\reminder{\lefthand}{$\cup$ is an easy symbol to memorize, since its name is
\textbf{u}nion, and it looks like a U.  You might consider intersection as it opposite.}

\begin{figure}[h]
\centering

    \begin{tikzpicture}[scale=0.3]
      \begin{scope}
    \clip (180:1.75cm) circle (2.5cm);
    \fill[cyan] (0:1.75cm) circle (2.5cm);
      \end{scope}
      \draw (0:1.75cm) circle (2.5cm) node[text=black,right] {$A$};
      \draw (180:1.75cm) circle (2.5cm) node [text=black,left] {$B$};
      \draw (0,-2.4) node [anchor=north] {$A \cap B$};

\draw[fill=cyan] (7,0) circle (2.5cm) node {$C$};
\draw[fill=cyan] (10.5,0) circle (2.5cm) node {$D$};
\draw (7,0) circle (2.5cm);
\draw (8.75,-2.4) node [anchor=north] {$C\cup D$};
    \end{tikzpicture}
\caption[Union]{Union and Intersection}
\end{figure}

\begin{example}
\exProblem
Given that that $A = \{1, 2, 3, 4, 5\}$, $B = \{-3, -1, 1, 3, 5\}$, and
$C = \{-1, 2, 3, 5, 6\}$, find $(A \cap C) \cup (B \cap C)$.

\exSolution
$A \cap C$ means ``What do $A$ and $C$ have in common?'', which is 1, 3, and 5.
$B \cap C$ means ``What do $B$ and $C$ have in common?", which is -1, 3, 5.
$\{1, 3, 5\} \cup \{-1, 3, 5\}$ means, ``What is in either one?", which is $\{-1, 1, 3, 5\}$.
\end{example}

\begin{figure}[h]
\centering
\def\firstcircle{(90:1.75cm) circle (2.5cm)}
  \def\secondcircle{(210:1.75cm) circle (2.5cm)}
  \def\thirdcircle{(330:1.75cm) circle (2.5cm)}
    \begin{tikzpicture}[scale=0.3]
      \begin{scope}
    \clip \secondcircle;
    \fill[cyan] \thirdcircle;
      \end{scope}
      \begin{scope}
    \clip \firstcircle;
    \fill[cyan] \thirdcircle;
      \end{scope}
      \draw \firstcircle node[text=black,above] {$A$};
      \draw \secondcircle node [text=black,below left] {$B$};
      \draw \thirdcircle node [text=black,below right] {$C$};
    \end{tikzpicture}
\caption[Venn]{$(A \cap C) \cup (B \cap C)$}
\end{figure}

\newpage

\ExSection{Exercises}
Use set builder notation, both mathematical and verbal.
\begin{exercises}{sec:Sets}
\prob[AASet1] Write each given set in the Set-Builder Form:
\subprob $\{2, 4, 6, 8, 10\}$
\subprob $\{2, 3, 5, 7, 11\}$
\subprob $\{$January, June, July$\}$
\subprob $\{$a, e, i, o, u$\}$
\subprob $\{$Tuesday, Thursday$\}$
\subprob $\{1, 4, 9, 16, 25\}$
\subprob $\{5, 10, 15, 20, 25, 30\}$

\prob[AASet2] Write the following sets in Set-Builder Form or Rule form:
\subprob $\{1, 3 5, 7, 9\}$
\subprob $\{16, 25, 36, 49, 64\}$
\subprob $\{$a, e, i, o, u$\}$
\subprob $\{$violet, indigo, blue, green, yellow, orange, red$\}$
\subprob $\{$January, March, May, July, August, October, December$\}$

\end{exercises}


\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{hyperref}

\newtheorem*{remark}{Remark}

\newcommand{\G}{\mathbb{G}}
\newcommand{\F}{\mathbb{F}}
\newcommand{\func}[1]{\mathsf{#1}}
\newcommand{\com}{\func{Com}}
\newcommand{\oracle}{\mathcal{O}_{\$}}

\title{Haven Protocol technical notes}
\author{Cypher Stack\thanks{\url{https://cypherstack.com}}}
\date{\today}

\begin{document}

\maketitle

This document describes technical information relevant to Haven Protocol.
It reflects the intention of the protocol designers, but does not reflect any particular implementation and has not been independently reviewed.
This document does not reflect a comprehensive protocol specification, and should not be used as such.
The author asserts no warranty and disclaims liability for its use.
The author further expresses no endorsement of Haven Protocol or its associated entities.

\section{Introduction}

Haven Protocol aims to permit signer-ambiguous confidential transactions using a modification of the Monero transaction protocol and its associated confidential transaction model \cite{ringct}.
Assets in the protocol are of multiple independent types, and have a hidden value represented by a commitment.
Transactions consume one or more assets of the same type, and produce new assets of arbitrary type.
While individual asset values remain concealed in transactions, total input and output values for each type are revealed.
An externally-provided public exchange rate is used to regulate balance validity, where a transaction is valid if (but not only if) input and output asset values balance according to this rate.

In this technical note, we provide a description of the relevant cryptography used to achieve these goals, discuss practical security, and suggest improvements and best practices to improve the protocol.
However, we do not provide a formal security model or proofs for the protocol, and this note should not be interpreted as doing so.

\section{Constructions}

The Haven Protocol transaction model, like that of \cite{ringct}, integrates several cryptographic constructions.
We briefly describe relevant constructions here, but refer the reader elsewhere for further details.

\subsection{Pedersen commitment}

Amounts in assets are hidden using Pedersen commitments.
Let the public parameters for a Pedersen commitment scheme be $pp_{\text{com}} = (\G,\F,G,H)$, where $\G$ is a prime-order group where the discrete logarithm problem is hard, $\F$ is its scalar field, and $G,H \in \G$ are randomly-sampled generators.
The commitment scheme is a function $\com: \F \times \F \to \G$ defined by $\com(v,r) = vG + rH$, where we refer to $v$ as the \textit{value} and $r$ as the \textit{mask}.
Pedersen commitments are perfectly hiding, computationally binding, and additively homomorphic, such that
$$\com(v,r) + \com(v',r') = \com(v + v',r + r')$$
for all $v,v',r,r' \in \F$.

\subsection{Discrete logarithm proofs}

While not used specifically in the existing protocol, we will rely in our later recommendations on a zero-knowledge discrete logarithm proving system that asserts the prover knows the discrete logarithm of a given group element with respect to a given generator.
Let the public parameters for a discrete logarithm proving system by $pp_{\text{dl}} = (\G,\F)$, where $\G$ is a prime-order group where the discrete logarithm problem is hard, and $\F$ is its scalar field.
The proving system consists of functions $\func{DLProve}$ and $\func{DLVerify}$ for the following relation:
$$\{pp_{\text{dl}}, G, Y \in \G ; y \in \F : Y = yG\}$$

The simple and well-known Schnorr proving system can be used for this purpose.

\subsection{Range proofs}

Because balance relies on sums and differences of committed values and $\G$ is a prime-order group, it is necessary to assert that committed amounts are unlikely to effectively bind to negative values.
To do so, we require the use of a zero-knowledge range proving system that asserts a Pedersen commitment binds to a value within a specified range.
Let the public parameters for a range proving scheme be $pp_{\text{rp}} = (pp_{\text{com}},n)$, where $pp_{\text{com}}$ is a set of public parameters for a Pedersen commitment scheme and the desired value range is $[0,2^n)$.
The range proving scheme consists of functions $\func{RangeProve}$ and $\func{RangeVerify}$ for the following relation:
$$\{pp_{\text{rp}}, C \in \G ; v, r \in \F : v \in [0,2^n), C = \com(v,r)\}$$

It is also possible in some instantiations to permit aggregation of independent value assertions within the same proof, which allows for improved efficiency.
In this case, the range proving system is generalized to functions $\func{AggregateRangeProve}$ and $\func{AggregateRangeVerify}$ for the following relation:
\begin{multline*}
\{pp_{\text{rp}}, \{C_j\}_{j=0}^{t-1} \subset \G ; \{(v_j, r_j)\}_{j=0}^{t-1} \subset \F^2 : \\
v_j \in [0,2^n) \forall j \in [0,t), C_j = \com(v_j,r_j) \forall j \in [0,t)\}
\end{multline*}

In practice, constructions like Bulletproofs \cite{bp} or Bulletproofs+ \cite{bpplus} are efficient instantiations of range proving schemes that permit value aggregation.
Haven Protocol selects Bulletproofs for this purpose.

\subsection{Linkable ring signature}

Signer ambiguity in the context of Haven Protocol requires the use of a 2-linkable ring signature (2-LRS) scheme.
In such a construction, the signer provides a list of group element pairs, and shows (in at least a witness-indistinguishable manner) that at least one such pair consists of independent Pedersen commitments to zero for which it knows the corresponding openings.
Further, a linkability property asserts that attempts to generate multiple signatures with the same key can be publicly detected; in the context of the transaction protocol, this would constitute a double-spend attempt and be rejected by consensus rules.
There are several security models reflecting general ring signature and linkable ring signature constructions, but we consider the definitions in \cite{clsag} for this work.

Let $pp_{\text{lrs}} = (pp_{\text{com}},N)$ be the public parameters for a 2-LRS scheme, where $pp_{\text{com}}$ is a set of public parameters for a Pedersen commitment scheme and $N$ is the size of the input list.
The 2-LRS consists of functions $\func{LRSSign}$, $\func{LRSVerify}$, and $\func{LRSLink}$ that respectively produce signatures, verify signatures, and determine if signatures are linked by a common signer.

Constructions like MLSAG \cite{ringct}, CLSAG \cite{clsag}, and Triptych \cite{triptych} can be used for this purpose, with different tradeoffs in efficiency and applications.
Haven Protocol selects CLSAG for this purpose.

\begin{remark}
We note that the selection of range proof and 2-LRS schemes may necessitate additional requirements on the group $\G$ chosen.
Fortunately, common elliptic curve groups satisfy typical cryptographic hardness assumptions.
Haven Protocol selects the prime-order subgroup of the \texttt{ed25519} elliptic curve group for this purpose.
\end{remark}

\section{Protocol description}

We describe how Haven Protocol defines assets, as well as the proofs and signatures required to authorize their transfer.

\subsection{Assets}

Assets are represented by outputs, which are structures generically containing (among other data) the following:
\begin{itemize}
    \item a public key $P \in \G$, the private key $p \in \F$ of which is required to authorize a transaction consuming the output
    \item a value commitment $C \in \G$, the value of which is encrypted to the recipient
    \item a type flag $T$ identifying the asset type
\end{itemize}

\subsection{Transfer transactions}

Transfer transactions consume outputs of a single type $T$, and generate outputs of the same type.
These transactions operate effectively the same as in \cite{ringct}.
Suppose such a transaction consumes $w \geq 1$ outputs, and generates $t > 1$ outputs.
We consider the method by which the sender produces output public keys $\{P_j\}_{j=0}^{t-1}$ and other auxiliary transaction data outside the scope of this analysis, so we focus instead on value-based operations.

The sender does the following (among other steps):
\begin{enumerate}
    \item Gathers an input cover set $\{P_i,C_i\}_{i=0}^{N-1}$ of outputs of type $T$ such that for all $u = [0,w)$, the value $l_u$ represents the index of a consumed output within this set.
    That is, we define this index such that $P_{l_u} = \com(0,p_u)$ for output private key $p_u$, and $C_{l_u} = \com(v_u,x_u)$ for known value and mask $v_u$ and $x_u$.
    \item Selects a fee $f \in \F$.
    \item For each $j \in [0,t)$, produces a new generated output:
    \begin{enumerate}
        \item Generates the output public key $\overline{P}_j$ according to protocol-specific rules.
        \item Chooses a value $\overline{v}_j \in \F$ for the output, selects a mask $\overline{x}_j \in \F$ uniformly at random, and computes the output value commitment $\overline{C}_j = \com(\overline{v}_j,\overline{x}_j)$.
    \end{enumerate}
    \item\label{step:transfer-prover-input-masks} For each $u \in [0,w-1)$, selects a mask $x_u' \in \F$ uniformly at random, and computes a consumed output value commitment offset $C_u' = \com(v_u,x_u')$ to the same value as $C_{l_u}$.
    \item\label{step:transfer-prover-last-mask} Computes the final mask $$x_{w-1}' = \sum_{j=0}^{t-1} \overline{x}_j - \sum_{u=0}^{w-2} x_u'$$ and consumed output value commitment offset $C_{w-1}' = \com(v_{w-1},x_{w-1}')$.
    \item For each $u \in [0,w-1)$, generates an authorizing signature $\sigma_u$ using $\func{LRSSign}(pp_{\text{lrs}})$ showing that, among the set $\{P_i, C_i - C_u'\}_{i=0}^{N-1}$, the signer knows the commitment openings to both $P_{l_u}$ and $C_{l_u} - C_u'$.
    \item Generates one or more range proofs on generated outputs:
    \begin{enumerate}
        \item If the range proving system supports aggregation, produces a single range proof on all generated outputs:
        $$\Pi_{\text{rp}} = \func{AggregateRangeProve}(pp_{\text{rp}},\{\overline{C}_j\}_{j=0}^{t-1} ; \{(\overline{v}_j, \overline{x}_j)\}_{j=0}^{t-1})$$
        \item Otherwise, produces a separate range proof for each $j \in [0,t)$:
        $$(\Pi_{\text{rp}})_j = \func{RangeProve}(pp_{\text{rp}},\overline{C}_j ; \overline{v}_j, \overline{x}_j)$$
    \end{enumerate}
\end{enumerate}

We require specifically that the transaction balance, which means that $$\sum_{u=0}^{w-1} v_u - \sum_{j=0}^{t-1} \overline{v}_j - f = 0.$$

To verify a transfer transaction, a verifier does the following (among other steps):
\begin{enumerate}
    \item For each $u \in [0,w)$, uses $\func{LRSVerify}$ to verify that $\sigma_u$ is a valid signature.
    \item Verifies any range proofs using either $\func{RangeVerify}$ or $\func{AggregateRangeVerify}$, as appropriate.
    \item Confirms that the fee $f$ is within an implementation-specific valid range.
    \item\label{step:transfer-balance} Checks that $$\sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{t-1} \overline{C}_j - \com(f,0) = 0.$$
\end{enumerate}

Since the commitment scheme is computationally binding, the validity of signatures $\{\sigma_u\}_{u=0}^{w-1}$ asserts that each $C_{l_u}$ and $C_u'$ bind to the same value except with negligible probability.
Further, if the transaction balances, then verification step \ref{step:transfer-balance} holds; the converse holds except with negligible probability since the commitment scheme is computationally binding.

\subsection{Conversion transactions}

Conversion transactions consume outputs of a single type, but generate outputs of two different types: the consumed output type and a converted type.
Suppose that such a transaction consumes $w \geq 1$ outputs.
Let $T$ represent the type flag of the consumed outputs, and $T'$ represent the type flag of the converted outputs.
Let $n_T \geq 1$ be the number of generated outputs of type $T$, and $n_{T'} \geq 1$ be the number of generated outputs of type $T'$.
Let $t = n_T + n_{T'}$.

We assume the existence of a trusted external price oracle $\oracle$ whose values are public and immutable.
On inputs $T$ and $T'$, the oracle $\oracle$ returns a nonzero value $r \in \F$ representing the conversion rate between asset values of these types.
That is, a value conversion is correct if, for a rate $r = \oracle(T,T')$, value $v_T$ of type $T$, and value $v_{T'}$ of type $T'$, the equation $v_{T'} = rv_T$ holds.
We stress that the assumptions on the oracle are broad, and that practical security is likely to depend highly on the properties of this oracle; for the purposes of this protocol description, we consider an abstract idealized oracle.

The sender does the following (among other steps):
\begin{enumerate}
    \item Gathers an input cover set $\{P_i,C_i\}_{i=0}^{N-1}$ of outputs of type $T$ such that for all $u = [0,w)$, the value $l_u$ represents the index of a consumed output within this set.
    That is, we define this index such that $P_{l_u} = \com(0,p_u)$ for output private key $p_u$, and $C_{l_u} = \com(v_u,x_u)$ for known value and mask $v_u$ and $x_u$.
    \item Queries a conversion rate $r = \oracle(T,T')$.
    \item Selects a fee $f$ in $T$ units.
    \item For each $j \in [0,n_T)$, produces a new generated output of type $T$:
    \begin{enumerate}
        \item Generates the output public key $\overline{P}_j$ according to protocol-specific rules.
        \item Chooses a value $\overline{v}_j \in \F$ in $T$ units for the output, selects a mask $\overline{x}_j \in \F$ uniformly at random, and computes the output value commitment $\overline{C}_j = \com(\overline{v}_j,\overline{x}_j)$.
    \end{enumerate}
    \item For each $j \in [n_T,t)$, produces a new generated output of type $T'$:
    \begin{enumerate}
        \item Generates the output public key $\overline{P}_j$ according to protocol-specific rules.
        \item Chooses a value $\overline{v}_j \in \F$ in $T'$ units for the output, selects a mask $\overline{x}_j \in \F$ uniformly at random, and computes the output value commitment $\overline{C}_j = \com(\overline{v}_j,\overline{x}_j)$.
    \end{enumerate}
    \item\label{step:conversion-prover-input-masks} For each $u \in [0,w-1)$, selects a mask $x_u' \in \F$ uniformly at random, and computes a consumed output value commitment offset $C_u' = \com(v_u,x_u')$ to the same value as $C_{l_u}$.
    \item\label{step:conversion-prover-last-mask} Computes the final mask $$x_{w-1}' = \sum_{j=0}^{n_T-1} \overline{x}_j + \frac{1}{r}\sum_{j=n_T}^{t-1} \overline{x}_j - \sum_{u=0}^{w-2} x_u'$$ and consumed output value commitment offset $C_{w-1}' = \com(v_{w-1},x_{w-1}')$.
    \item For each $u \in [0,w-1)$, generates an authorizing signature $\sigma_u$ using $\func{LRSSign}(pp_{\text{lrs}})$ showing that, among the set $\{P_i, C_i - C_u'\}_{i=0}^{N-1}$, the signer knows the commitment openings to both $P_{l_u}$ and $C_{l_u} - C_u'$.
    \item Generates one or more range proofs on generated outputs:
    \begin{enumerate}
        \item If the range proving system supports aggregation, produces a single range proof on all generated outputs:
        $$\Pi_{\text{rp}} = \func{AggregateRangeProve}(pp_{\text{rp}},\{\overline{C}_j\}_{j=0}^{t-1} ; \{(\overline{v}_j, \overline{x}_j)\}_{j=0}^{t-1})$$
        \item Otherwise, produces a separate range proof for each $j \in [0,t)$:
        $$(\Pi_{\text{rp}})_j = \func{RangeProve}(pp_{\text{rp}},\overline{C}_j ; \overline{v}_j, \overline{x}_j)$$
    \end{enumerate}
    \item\label{step:conversion-prover-mask-sums} Generates the following commitment mask sums:
    \begin{align*}
        a_T =& \sum_{u=0}^{w-1} x_u' \\
        \overline{a}_T =& \sum_{j=0}^{n_T-1} \overline{x}_j
    \end{align*}
    \item Computes the net value sums in each asset type:
    \begin{align*}
        y_T =& \sum_{u=0}^{w-1} v_u - \sum_{j=0}^{n_T-1} \overline{v}_j - f \\
        y_{T'} =& \sum_{j=n_T}^{t-1} \overline{v}_j
    \end{align*}
\end{enumerate}

In this case, transaction balance requires that $$\sum_{u=0}^{w-1} v_u - \sum_{j=0}^{n_T-1} \overline{v}_j - \frac{1}{r}\sum_{j=n_T}^{t-1} \overline{v}_j - f = 0.$$

To verify a conversion transaction, a verifier does the following (among other steps):
\begin{enumerate}
    \item Queries the conversion rate $r = \oracle(T,T')$ appropriate to the transaction.
    \item For each $u \in [0,w)$, uses $\func{LRSVerify}$ to verify that $\sigma_u$ is a valid signature.
    \item Verifies any range proofs using either $\func{RangeVerify}$ or $\func{AggregateRangeVerify}$ as appropriate.
    \item Confirms that the fee $f$ is within an implementation-specific valid range.
    \item\label{step:conversion-balance} Confirms the transaction balances by checking that $$\sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j - \frac{1}{r}\sum_{j=n_T}^{t-1} \overline{C}_j - \com(f,0) = 0.$$
    \item\label{step:conversion-value-T} Confirms the type-$T$ amount by checking that $$\sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j - \com(f, 0) - \com(0,a_T - \overline{a}_T) - \com(y_T,0) = 0.$$
    \item\label{step:conversion-value-T-prime} Confirms the plaintext type-$T'$ amount by checking that $y_{T'} - ry_T = 0$.
\end{enumerate}

If the transaction balances, then verification steps \ref{step:conversion-balance}, \ref{step:conversion-value-T}, and \ref{step:conversion-value-T-prime} hold; the converses hold except with negligible probability since the commitment scheme is computationally binding.

\section{Observations and recommendations}

In this section, we make observations and propose changes to the protocol to improve its practical security.

\subsection{Remove the plaintext type-\texorpdfstring{$T'$}{T'} amount check}
\label{rec:remove-amount-check}

While the type-$T$ amount $y_T$ is verified in conversion transactions by testing its relationship to the relevant commitments in verification step \ref{step:conversion-value-T}, the type-$T'$ amount $y_{T'}$ is never tested against commitments.
Rather, it only appears in the check in verification step \ref{step:conversion-value-T-prime}, where its presence in the transaction structure and algorithms is unnecessary and offers no additional security.
An adversary who can produce a transaction that passes verification steps \ref{step:conversion-balance} and \ref{step:conversion-value-T}, but produce type-$T'$ commitments to an unexpected total value, would break the binding property of the commitment scheme.
The value $y_{T'}$ and associated check in step \ref{step:conversion-value-T-prime} can therefore be safely removed, and this value can simply be computed by the verifier as needed for other purposes.

\subsection{Reveal a single aggregate type-\texorpdfstring{$T$}{T} commitment mask}
\label{rec:single-mask}

In conversion transaction generation step \ref{step:conversion-prover-mask-sums}, mask sums $a_T$ and $\overline{a}_T$ are computed.
However, in verification step \ref{step:conversion-value-T}, only their difference $a_T - \overline{a}_T$ is used, yielding no additional security by including both values in transaction data.
Since no additional checks are required or performed on the individual values, only the difference needs to be included in the transaction data.

\subsection{Replace aggregate type-\texorpdfstring{$T$}{T} commitment masks with representation proof}
\label{rec:zk-masks-T}

In conversion transactions, commitment mask sums are uniformly distributed, but they are not independent.
In particular, the mask equation
$$\sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j - \frac{1}{r}\sum_{j=n_T}^{t-1} \overline{x}_j = 0$$
holds.
When a user produces a conversion transaction that reveals mask terms, it can leak information that depends on the particular transaction input and output structure.
To mitigate this leakage, it is possible to modify the protocol to instead prove knowledge of the commitment mask sums, rather than reveal them.
Because amount verification requires the use of these sums, the check in verification step \ref{step:conversion-value-T} also must be slightly modified.

To do so, generation step \ref{step:conversion-prover-mask-sums} is replaced.
Instead of revealing the mask sums $a_T$ and $\overline{a}_T$ in the transaction data, the prover instead defines
$$A = \com\left( 0, \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j \right)$$
and produces a discrete logarithm proof
$$\Pi_{\text{dl},T} = \func{DLProve}\left( pp_{\text{dl}}, \com(0,1), A ; \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j \right)$$
on this value, and includes $\Pi_{\text{dl},T}$ in the transaction.

Verification step \ref{step:conversion-value-T} is then modified to account for this change.
The verifier defines
$$A' = \sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j - \com(f,0) - \com(y_T,0)$$
and checks that $\func{DLVerify}(pp_{\text{dl}}, \com(0,1), A', \Pi_{\text{dl},T})$ succeeds.

\subsection{Select all commitment masks independently}
\label{rec:zk-masks}

The balance equations used in the protocol (for both transfer and conversion transactions) relies on commitment masks being chosen in such a way that input commitment offsets and output commitments sum to zero.
While this means that such masks can be distributed uniformly at random, they are not chosen independently for this reason.
An adversary who knows all but one of these masks can therefore identify the remaining mask and corresponding value.
Other transaction structures and components can also leak information.

Similarly to the above notes on type-$T$ commitment mask sums, it is possible to choose all commitment masks independently and prove knowledge of them in zero knowledge.
This means that knowledge of any particular subset of masks gives an adversary no inherent advantage in identifying unknown values.

\subsubsection{Transfer transactions}

To do this for transfer transactions, generation step \ref{step:transfer-prover-last-mask} is removed, and step \ref{step:transfer-prover-input-masks} is modified to select all masks uniformly at random independently.
Because verifier step \ref{step:transfer-balance} no longer holds, the prover defines
$$B = \com\left( 0, \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{t-1} \overline{x}_j \right)$$
and produces a discrete logarithm proof
$$\Pi_{\text{dl}} = \func{DLProve}\left( pp_{\text{dl}}, \com(0,1), B ; \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{t-1} \overline{x}_j \right)$$
on this value, and includes $\Pi_{\text{dl}}$ in the transaction.

The verification step \ref{step:transfer-balance} is then modified to account for this change.
The verifier defines
$$B' = \sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{t-1} \overline{C}_j - \com(f,0)$$
and checks that $\func{DLVerify}(pp_{\text{dl}}, \com(0,1), B', \Pi_{\text{dl}})$ succeeds.

\subsubsection{Conversion transactions}

To do this for conversion transactions, generation step \ref{step:conversion-prover-last-mask} is removed, and step \ref{step:conversion-prover-input-masks} is modified to select all masks uniformly at random independently.
Because verifier step \ref{step:conversion-balance} no longer holds, the prover defines
$$B = \com\left( 0, \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j - \frac{1}{r} \sum_{j=n_T}^{t-1} \overline{x}_j \right)$$
and produces a discrete logarithm proof
$$\Pi_{\text{dl}} = \func{DLProve}\left( pp_{\text{dl}}, \com(0,1), B ; \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j - \frac{1}{r} \sum_{j=n_T}^{t-1} \overline{x}_j \right)$$
on this value, and includes $\Pi_{\text{dl}}$ in the transaction.

The verification step \ref{step:conversion-balance} is then modified to account for this change.
The verifier defines
$$B' = \sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j - \frac{1}{r} \sum_{j=n_T}^{t-1} \overline{C}_j - \com(f,0)$$
and checks that $\func{DLVerify}(pp_{\text{dl}}, \com(0,1), B', \Pi_{\text{dl}})$ succeeds.

\subsection{Aggregate all discrete logarithm proofs}

The recommendations in sections \ref{rec:zk-masks-T} and \ref{rec:zk-masks} each produce a proof of knowledge of a discrete logarithm against the same group generator, which can be considered proofs of commitments to zero.
To optimize space and verifier efficiency, it may be desirable to combine these proofs.
Doing so requires the use of an aggregate discrete logarithm proving system, which asserts knowledge of openings to multiple independent commitments to zero in zero knowledge.

Let the public parameters of an aggregate discrete logarithm proving system be $pp_{\text{agg}} = (pp_{\text{com}},d)$, where $pp_{\text{com}}$ is a set of public parameters for a Pedersen commitment scheme and $d > 0$ is the number of commitments.
The proving scheme consists of functions $\func{AggregateDLProve}$ and $\func{AggregateDLVerify}$ for the following relation:
$$\{pp_{\text{agg}}, \{Y_i\}_{i=0}^{d-1} \subset \G ; \{y_i\}_{i=0}^{d-1} \subset \F : Y_i = \com(0,y_i) \forall i \in [0,d)\}$$

The batching construction of Gennaro \textit{et al.} \cite{schnorr} is an efficient and straightforward instantiation of such a proving system.
Proving knowledge of openings of $d > 1$ commitments to zero incurs the same communication cost as for $d = 1$ commitments, and the additional computational complexity is minimal.

For completeness, we list the algorithm steps here; the reader is referred to \cite{schnorr} for details and security proofs.

\begin{enumerate}
    \item The prover chooses $r \in \F$ uniformly at random, sets $X = r\com(0,1)$, and sends $X$ to the verifier.
    \item The verifier chooses $c \in \F \setminus \{0\}$ uniformly at random, and sends $c$ to the prover.
    \item The prover sets $s = r + \sum_{i=0}^{d-1} y_i c^{i+1}$, and sends $s$ to the verifier.
    \item The verifier checks that the equality $$X + \sum_{i=0}^{d-1} c^{i+1}Y_i = s\com(0,1)$$ holds.
\end{enumerate}

If applying both recommendations that use discrete logarithm representation proofs, the goal is to combine the two proofs $\Pi_{\text{dl},T}$ and $\Pi_{\text{dl}}$ into a single proof $\Pi_{\text{agg}}$ using this method.
In this case, we use the notation from the previous sections and produce the proof
$$\Pi_{\text{agg}} = \func{AggregateDLProve}(pp_{\text{agg}}, \{Y_0,Y_1\} ; \{y_0,y_1\}),$$
where
$$y_0 = \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j$$
and $Y_0 = A$ are the witness and statement from $\Pi_{\text{dl},T}$ in section \ref{rec:zk-masks-T}, and
$$y_1 = \sum_{u=0}^{w-1} x_u' - \sum_{j=0}^{n_T-1} \overline{x}_j - \frac{1}{r} \sum_{j=n_T}^{t-1} \overline{x}_j$$
and $Y_1 = B$ are the witness and statement from $\Pi_{\text{dl}}$ in section \ref{rec:zk-masks}.

Verification of this single aggregate proof with $\func{AggregateDLVerify}$ uses the corresponding verification statements described in those sections.

\bibliographystyle{plain}
\bibliography{main}

\end{document}


\newpage\section{Length Relations}

		\lem{E.R.I.Q. (Equal Ration in Quadrilateral) Lemma}{Let $ A_1, B_1, C_1;\ A_2, B_2, C_2 $ be two sets of collinear points such that \[ \frac{A_1B_1}{B_1C_1} = \frac{A_2B_2}{B_2C_2} = k \]. Let points $ A, B, C $ be on $ A_1A_2, B_1B_2, C_1, C_2 $ such that: \[ \frac{A_1A}{A_2A} = \frac{B_1B}{B_2B} = \frac{C_1C}{C_2C} \] Then we have, \[ A, B, C \text{ are collinear and, } \frac{AB}{BC} = k  \]
			\fig{1}{ERIQ_Lemma}{E.R.I.Q. Lemma}
		}\label{eriq_lemma}

		\solu{A great use of this problem is in proving some midpoints collinear. Line in Newton-Gauss Line and some other such problems (\hrf{eriq_lemma_1}{1}, \hrf{eriq_lemma_2}{2}, \hrf{eriq_lemma_3}{3}) where it is asked to proved that some midpoints are collinear.}

		\lem{Steiner's Isogonal Cevian Lemma}{In $ \triangle ABC $, $ AA_1, AA_2 $ are two isogonal cevians, with $ A_1, A_2 \in BC $. Then we have \[ \frac{BA_1}{A_1C} \times \frac{BA_2}{A_2C} = \frac{BA^2}{AC^2} \]}

		\theo{}{}{Let $ P_1,P_2 $ be two isogonal conjugates wrt $ \triangle ABC $. Then if the Pedal triangle of $ P_1 $ is homological wrt to $ \triangle ABC $ then so is the Pedal triangle of $ P_2 .$}

		\theo{}{Erdos-Mordell Theorem (Forum Geometricorum Volume 1 (2001) 7-8)}{If from a point $O$ inside a given $\triangle ABC$ perpendiculars $OD,OE,OF$ are drawn to its sides, then $OA+OB+OC \geq 2(OD+OE+OF)$. Equality holds if and only if $\triangle ABC$ is equilateral.}

		Apparently nothing is needed except ``Ptolemy's Theorem''. Think of a way to connect $OA$ with $OE, OF$ and the sides of the triangle. As it is the most natural to use $AB, AC$, we have to deal with $BE, CF$ too. And dealing with lengths is the easiest when we have similar triangles. So we do some construction.

		\prob{https://artofproblemsolving.com/community/c6h488832p2739339}{ISL 2011 G7}{E}{Let $ABCDEF$ be a convex hexagon all of whose sides are tangent to a circle $\omega$ with centre $O$. Suppose that the circumcircle of triangle $ACE$ is concentric with $\omega$. Let $J$ be the foot of the perpendicular from $B$ to $CD$. Suppose that the perpendicular from $B$ to $DF$ intersects the line $EO$ at a point $K$. Let $L$ be the foot of the perpendicular from $K$ to $DE$. Prove that $DJ=DL$.}

			\solu{There are a LOT of equal lenths, equal angles, and we have a perpendicularity lemma working as well. Why don't we try cosine :0}