text:
---
layout: post
title: "Real-Time Monocular Segmentation and Pose Tracking"
tagline: "Variational Methods"
categories: Mathematics
image: /thumbnail-mobile.png
author: "Bao-Huy Nguyen"
meta: "Springfield"
---

## Real-Time Monocular Segmentation and Pose Tracking

This blog presents you a light weight real time segmentation and pose tracking method which only uses monocular RGB camera and can run with multiple objects and robust to occlusion. You can watch the [demonstration](#demonstration) first to have a sense. The whole process is just mathematics which makes the output of each step predictable and allows us to have insight for further improvement.

## Preliminaries

Let $$I$$ be the image in the image domain $$\Omega \subset \mathbb{R}^2$$. With every pixel $$\textbf{x} = [x, y]^T$$, there is a corresponding color $$\textbf{c} = I(x, y)$$ (this can be grey value or RGB).

The 3D model will be transformed from its model space into camera space by a transformation matrix $$T$$ (our camera is fixed at the origin and looks in the positive direction of $$z$$ axis - a little bit different to OpenGL). The rigid transformation matrix $$T$$ we call pose of 3D model and is presented by a $$4 x 4$$ homogeneous matrix:

$$T = \left[\begin{matrix}
    R & \textbf{t} \\
    \textbf{0} & 1 \\
\end{matrix}\right] \in \mathbb{SE}(3)$$

with $$R \in \mathbb{SO}(3)$$ and $$\textbf{t} \in \mathbb{R}^3$$.

*To understand more about the definition of $$\mathbb{SE}(3)$$ (Lie - group Special Euclidean ) as well as its properties we recommend you read chapter 2 of the book: [An Invitation to 3D Computer Vision](https://www.amazon.com/Invitation-3-D-Vision-Interdisciplinary-Mathematics/dp/0387008934).*

Another of this tracking problem is that we must have the intrinsic matrix $$K$$ of our camera. This can be achieved easily by estimating the matrix with multiple checkerboard images captured beforehand.

$$K = \left[ \begin{matrix}
    f_x & 0 & c_x \\
    0 & f_y & c_y \\
    0 & 0 & 1
\end{matrix} \right]$$

With a point in a 3D model $$\textbf{X}_i = [X_i, Y_i, Z_i, 1]^T$$ (represented in homogeneous coordinate), its project in 2D image is:

$$Z'\textbf{x} = Z'\left[\begin{matrix}
    x \\
    y \\
    1
\end{matrix}\right] =
\left[\begin{matrix}
    f_x & 0 & c_x \\
    0 & f_y & c_y \\
    0 & 0 & 1
\end{matrix}\right]
\left[\begin{matrix}
    1 & 0 & 0 & 0 \\
    0 & 1 & 0 & 0 \\
    0 & 0 & 1 & 0
\end{matrix}\right]
\left[\begin{matrix}
    r_{11} & r_{12} & r_{13} & t_1 \\
    r_{21} & r_{22} & r_{23} & t_2 \\
    r_{31} & r_{32} & r_{33} & t_3 \\
    0 & 0 & 0 & 1
\end{matrix}\right]
\left[\begin{matrix}
    X_i \\
    Y_i \\
    Z_i \\
    1
\end{matrix}\right]
$$

The silhouette of 3D model in image plane after projection splits image into 2 regions: foreground $$\Omega_f \subset \Omega$$ and background $$\Omega_b = \Omega \setminus \Omega_f$$. In the figure below, the white region is foreground and the rest (black color) is background.

![](/images/Tracking/mask.jpg)

For pose tracking, the goal of the problem is to find the pose of 3D model in each frame. With an assumption that the pose $$T_k$$ of frame $$I_k$$ is already known, we only need to perform pose tracking at frame $$I_{k+1}$$. Because of linearity of transformation, the pose of next frame can be expressed by the current pose according to this equation: $$T_{k+1} = \Delta T T_{k}$$. So, for each new frame, we just need to find $$\Delta T$$ to rectify the current pose $$T_k$$.

For pose optimization, we model the rigid body motion $$\Delta T$$ with twists:

$$\hat{\xi} = \left[ \begin{matrix}
    \hat{\textbf{w}} & \textbf{v} \\
    \textbf{0} & 0 \\
\end{matrix}\right] \in \mathfrak{se}(3)$$

with $$\textbf{w} \in \mathfrak{so}(3)$$ and $$\textbf{v} \in \mathbb{R}^3$$.

Each twist is parametrized by a six dimensional vector of so-called *twist coordinates*:

$$\xi = [\omega_1, \omega_2, \omega_3, v_1, v_2, v_3]^T \in \mathbb{R}^6$$

and the matrix exponential:

$$\Delta T = \operatorname{exp}(\hat{\xi}) \in \mathbb{SE}(3)$$

*Again, if you have trouble with these notations, Chapter 2 Lie - Algebra in the book: [An Invitation to 3D Computer Vision](https://www.amazon.com/Invitation-3-D-Vision-Interdisciplinary-Mathematics/dp/0387008934) will help you.*

## Statistical Image Segmentation

### Shape Kernel $$\Phi$$

The approach of this method is mainly based on statistical segmentation (you can read our blog in [here](https://graphicsminer.github.io/mathematics/2022/09/24/variational-method-and-image-segmentation_part3.html)), so as usual the silhouette of 3D model will be implicitly represented by a so-called shape kernel $$\Phi$$. This is called level set embedding function and the $$\Phi$$ must have the properties:

$$\begin{equation*}
\begin{cases}
C &= \{(x, y) \in \Omega \, | \, \phi(x, y) = 0\} \\
inside (C) &= \{(x, y) \in \Omega \, | \, \phi(x, y) \lt 0\} \\
outside (C) &= \{(x, y) \in \Omega \, | \, \phi(x, y) \gt 0\}
\end{cases}
\end{equation*}$$

where $$C$$ is contour of the silhouette (image below).

Silhouette             |  Contour
:-----------------------:|:-------------------------:
![](/images/Tracking/mask.jpg) |  ![](/images/Tracking/edge.jpg)

To present $$\Phi$$, we use signed distance function:

$$d(\textbf{x}) = \underset{\textbf{x}_c \in C}{\operatorname{min}}|\textbf{x} - \textbf{x}_c|$$
$$\begin{equation*}
\Phi(\textbf{x}) = \begin{cases}
-d(\textbf{x}) \quad \forall \textbf{x} \in R_f \\
d(\textbf{x}) \quad \forall \textbf{x} \in R_b
\end{cases}
\end{equation*}$$

where $$R_f$$ is foreground region and $$R_b$$ is background region.

Signed Distance Function             |  Heatmap
:-----------------------:|:-------------------------:
![](/images/Tracking/sdf.jpg) |  ![](/images/Tracking/heatmap.jpg)

For efficient method of calculating signed distance function, you can read [[6]](#6)

### Generative Model

Let's start first with graphical model that Victor et al [[1]](#1) proposed:

![Graphical Model](/images/Tracking/graphical_model.jpg)

where

* $$\textbf{p}$$: pose of 3D object (6 DoF).
* $$\Phi$$: Shape kernel.
* $$\textbf{x}$$: 2D coordinate in image plane.
* $$R$$: Foreground or Background region.
* $$\textbf{c}$$: color

This graphical model makes sense since random variable pose of 3D model will affect the shape kernel $$\Phi$$ through its silhouette. The probability random variable $$\textbf{x}$$ in image plane would depend on pose $$\textbf{p}$$ , the region $$R$$ whether foreground or background and $$\Phi$$. And finally, the probability of color $$\textbf{c}$$ definitely depends on the region $$R$$.

Our goal now is to **maximize a posteriori** $$P(\Phi, \textbf{p} \mid \Omega)$$ with give image $$I \subset \Omega$$. However, first, let's have a look on **generative model** $$P(\textbf{x}, \textbf{c}, R, \Phi, \textbf{p})$$:

$$P(\textbf{x}, \textbf{c}, R, \Phi, \textbf{p}) = P(\textbf{x} \mid R, \Phi, \textbf{p}) \, P(\textbf{c} \mid R) \, P(R) \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

Expand it by dividing both sides by:
$$P(\textbf{c}) = \sum_{R \in {R_f, R_b}} P(\textbf{c} \mid R) \, P(R)$$

to get:

$$P(\textbf{x}, R, \Phi, \textbf{p} \mid \textbf{c}) = P(\textbf{x} \mid R, \Phi, \textbf{p})  \, P(R \mid \textbf{c}) \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

where:
$$P(R_j \mid \textbf{c}) = \dfrac{P(\textbf{c} | R_j) \, P(R_j)}{\sum_{i = \{f, b\}} P(\textbf{c} | R_i) \, P(R_i)} \qquad j = \{f, b\}$$

Next, marginalize over $$R$$:

$$P(\textbf{x}, \Phi, \textbf{p} \mid \textbf{c}) = \sum_{i=\{f, b\}} P(\textbf{x} \mid  R_i, \Phi, \textbf{p}) \, P(R_i \mid \textbf{c}) \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

And divide by $$P(\textbf{x})$$:

$$P(\Phi, \textbf{p} \mid \textbf{c}, \textbf{x}) = \dfrac{1}{P(\textbf{x})}\sum_{i=\{f, b\}} P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c}) \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

Since we can assume that $$P(\textbf{x})$$ is a constant (for the sake of simplicity), the posterior of a given pixel and its color can be written as:

$$P(\Phi, \textbf{p} \mid \textbf{c}, \textbf{x}) \propto \sum_{i=\{f, b\}} P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c}) \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

And final posterior over an image is:

$$P(\Phi, \textbf{p} \mid \Omega) \propto \prod_{\textbf{x, c} \in \Omega } \sum_{i=\{f, b\}} \{P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c})\} \, P(\Phi \mid \textbf{p}) \, P(\textbf{p})$$

To reduce the complexity, Victor et al [[1]](#1) eliminated the prior term to get a simple version which makes maximizing a posterior become maximizing likelihood.

$$P(\Phi, \textbf{p} \mid \Omega) \propto \prod_{\textbf{x, c} \in \Omega } \sum_{i=\{f, b\}} \{P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c})\}$$

**Maximizing likelihood is also equivalent to minimizing negative logarithm likelihood**:

$$\underset{\textbf{p}}{\operatorname{arg min}} \log{P(\Phi, \textbf{p}\mid \Omega)} = \sum_{\textbf{x}, \textbf{c}\in \Omega} -\operatorname{log}\left(\sum_{i=\{f, b\}} P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c})\right)$$

### Minimize Negative Logarithm Likelihood

Our goal now is to minimize the negative log likelihood:

$$\underset{\textbf{p}}{\operatorname{arg min}} \log{P(\Phi, \textbf{p}\mid \Omega)} = \sum_{\textbf{x}, \textbf{c}\in \Omega} -\operatorname{log}\left(\sum_{i=\{f, b\}} P(\textbf{x} \mid R_i, \Phi, \textbf{p})\, P(R_i \mid \textbf{c})\right)$$

To solve this optimization problem, we need to know the explicit probability of each term in the equation:

1. Let start first with $$P(\textbf{x} \mid R_f, \Phi, \textbf{p})$$.

![](/images/Tracking/pixel_probability.jpg)

Intuitively, the probability of the red pixel in foreground $$R_f$$ will be:

$$P(\textbf{x} \mid R_f, \Phi, \textbf{p}) = \dfrac{1}{\operatorname{Area}_f}$$

and that of the green pixel in background $$R_b$$ will be:

$$P(\textbf{x} \mid R_b, \Phi, \textbf{p}) = \dfrac{1}{\operatorname{Area}_b}$$

To generalize both expressions, we can utilize the shape kernel probability.

We already know:

$$\begin{equation*}
\begin{cases}
C &= \{(x, y) \in \Omega \, | \, \phi(x, y) = 0\} \\
inside (C) &= \{(x, y) \in \Omega \, | \, \phi(x, y) \lt 0\} \\
outside (C) &= \{(x, y) \in \Omega \, | \, \phi(x, y) \gt 0\}
\end{cases}
\end{equation*}$$

So, with the introduction of Heaviside function:

$$\begin{equation*}
H(x) = \begin{cases}
1 & \quad x \le 0, \\
0 & \quad x \gt 0.
\end{cases}
\end{equation*}$$

the above two probabilities can be written as:

$$\begin{aligned}
    P(\textbf{x} \mid R_f, \Phi, \textbf{p}) &= \dfrac{H(\Phi(\textbf{x}))}{\eta_f} \\
P(\textbf{x} \mid R_b, \Phi, \textbf{p}) &= \dfrac{1 - H(\Phi(\textbf{x}))}{\eta_b}
\end{aligned}$$

where

$$\begin{aligned}
    \eta_f &= \sum_{i = 1}^{N}H(\Phi(\textbf{x})) \\
\eta_b &= \sum_{i = 1}^{N}1 - H(\Phi(\textbf{x}))
\end{aligned}$$

2. Second is $$P(R_i \mid \textbf{c})$$

Base on Bayes' rule, we can get:

$$P(R_f \mid \textbf{c}) = \dfrac{P(\textbf{c} \mid R_f) P(R_f)}{P(\textbf{c} \mid R_f) P(R_f) + P(\textbf{c} \mid R_b) P(R_b)}$$
$$P(R_b \mid \textbf{c}) = \dfrac{P(\textbf{c} \mid R_b) P(R_b)}{P(\textbf{c} \mid R_f) P(R_f) + P(\textbf{c} \mid R_b) P(R_b)}$$

where:

$$\begin{aligned}
    P(R_f) &= \dfrac{\eta_f}{\eta} \\
P(R_b) &= \dfrac{\eta_b}{\eta} \\
\eta &= \eta_f + \eta_b
\end{aligned}$$

Two likelihood $$P(\textbf{c} \mid R_f)$$ and $$P(\textbf{c} \mid R_b)$$ are represented by two $$32\times32\times32$$ - bin histograms.

$$\begin{aligned}
    E(\Phi, \textbf{p})
    &= \sum_{\textbf{x}, \textbf{c} \in \Omega} -\operatorname{log}(\dfrac{H(\Phi(\textbf{x}))}{\eta_f}\dfrac{P(\textbf{c} \mid R_f)\eta_f}{P(\textbf{c} \mid R_f) \eta_f+ P(\textbf{c} \mid R_b) \eta_b} \\
    &+ \dfrac{1 - H(\Phi(\textbf{x}))}{\eta_b}\dfrac{P(\textbf{c} \mid R_b)\eta_b}{P(\textbf{c} \mid R_f) \eta_f+ P(\textbf{c} \mid R_b) \eta_b} )\\
    &= \sum_{\textbf{x}, \textbf{c} \in \Omega} -\operatorname{log} \left(H(\Phi(\textbf{x})) P_f + (1 - H(\Phi(\textbf{x})))P_b\right)
\end{aligned}$$

where:

$$P_f = \dfrac{P(\textbf{c} \mid R_f)}{P(\textbf{c} \mid R_f) \eta_f+ P(\textbf{c} \mid R_b) \eta_b}$$

$$P_b = \dfrac{P(\textbf{c} \mid R_b)}{P(\textbf{c} \mid R_f) \eta_f+ P(\textbf{c} \mid R_b) \eta_b}$$

Finally, we have the objective function for optimization problem:

$$\begin{aligned}
    E(\textbf{p})
    &= \sum_{\textbf{x}, \textbf{c} \in \Omega} -\operatorname{log} (H(\Phi(\textbf{x})) P_f + (1 - H(\Phi(\textbf{x})))P_b) \\
    &= \sum_{\textbf{x}, \textbf{c} \in \Omega} F(\textbf{x}, \textbf{c})
\end{aligned}$$

## Optimize Energy Function

For the rest of the blog, we will use $$\xi$$ instead of pose $$\textbf{p}$$.

To find $$\xi$$ such that energy function $$E(\xi)$$ is minimum, the numerical optimization method Gauss - Newton is chosen because of its fast convergence. However the energy function is not in linear form, so we need to rewrite it before applying Gauss - Newton strategy:

$$E(\xi) = \dfrac{1}{2}\sum_{\textbf{x}, \textbf{c} \in \Omega} \dfrac{1}{\psi(\textbf{x}, \textbf{c})}F^2(\textbf{x}, \textbf{c})$$

where:

$$\psi(\textbf{x}, \textbf{c}) = F(\textbf{x}, \textbf{c})$$

is considered as a constant when optimizing.

### Gauss - Newton Strategy

The Jacobian and pseudo Hessian matrix are:

$$\begin{aligned}
    \dfrac{\partial E(\xi)}{\partial\xi} &= \dfrac{1}{2}\sum_{\textbf{x}, \textbf{c} \in \Omega}\psi(\textbf{x}, \textbf{c})\dfrac{\partial F^2(\textbf{x}, \textbf{c})}{\partial \xi} = \sum_{\textbf{x}, \textbf{c} \in \Omega}\psi(\textbf{x}, \textbf{c})F\dfrac{\partial F}{\partial \xi} \\

    \dfrac{\partial^2 E(\xi)}{\partial\xi^2} &= \sum_{\textbf{x}, \textbf{c} \in \Omega}\psi(\textbf{x}, \textbf{c})\left( \left(\dfrac{\partial F}{\partial \xi}\right)^T\dfrac{\partial F}{\partial \xi} + F\dfrac{\partial^2 F}{\partial \xi^2} \right)
\end{aligned}$$

Approximating the energy function with Taylor series and the Hessian matrix by pseudo Hessian:

$$E(\xi + \Delta\xi) \approx E(\xi) + \sum_{\Omega}J\Delta\xi + \dfrac{1}{2}\sum_{\Omega}\psi(\textbf{x})\Delta\xi^TJ^TJ\Delta\xi$$

When we reach optimum, this $$E(\xi + \Delta\xi) \approx E(\xi)$$ should happen which makes:

$$\begin{aligned}
    \sum_{\Omega}J\Delta\xi + \dfrac{1}{2}\sum_{\Omega}\psi(\textbf{x})\Delta\xi^TJ^TJ\Delta\xi &= 0 \\
    \Rightarrow \left(\sum_{\Omega}J + \dfrac{1}{2}\sum_{\Omega}\psi(\textbf{x})\Delta\xi^TJ^TJ\right)\Delta\xi &= 0 \\
\end{aligned}$$

Since $$\Delta \xi$$ can not be zero so:

$$\sum_{\Omega}J + \dfrac{1}{2}\sum_{\Omega}\psi(\textbf{x})\Delta\xi^TJ^TJ = 0$$

which leads:

$$\Delta\xi = -\left(\sum_\Omega\psi(x)J^TJ\right)^{-1}\left(\sum_\Omega J\right)$$

The current pose is updated with:

$$T \leftarrow \operatorname{exp}(\Delta \hat{\xi})T$$

### Chain rule

We already have updated equation for $$\Delta \xi$$, what remains is how we construct the Jacobian and pseudo Hessian matrix.

$$F(\textbf{x}, \textbf{c}) = -\operatorname{log} (H(\Phi(\textbf{x})) P_f + (1 - H(\Phi(\textbf{x})))P_b)$$

This is pretty easy thanks to chain rule:

$$J = \dfrac{P_b - P_f}{H(\Phi(\textbf{x})) P_f + (1 - H(\Phi(\textbf{x})))P_b} \delta(\Phi(x)) \dfrac{\partial \Phi(\textbf{x})}{\partial \xi}$$

where Dirac function $$\delta(.)$$ is derivative of Heaviside function $$H(.)$$. In implementation, the smooth Heaviside is used.

$$H(x) = \dfrac{1}{\pi} \left(-\operatorname{atan}(\epsilon \cdot  x) + \dfrac{\pi}{2}\right)$$

with $$\epsilon = 0.1$$.

Next is derivative of $$\dfrac{\partial \Phi(\textbf{x})}{\partial \textbf{p}}$$.

Based on chain rule, we have:

$$\dfrac{\partial \Phi(\textbf{x})}{\partial \xi} = \dfrac{\partial \Phi}{\partial \textbf{x}} \dfrac{\partial \textbf{x}}{\partial \xi}$$

The first term $$\dfrac{\partial \Phi}{\partial \textbf{x}}$$ is approximated by **central difference**:

$$\left[\dfrac{\partial \Phi(\textbf{x})}{\partial x}, \dfrac{\partial \Phi(\textbf{x})}{\partial y}\right] = \left[ \begin{matrix}
    \Phi_y \\
    \Phi_x
\end{matrix} \right]^T =
\left[
\begin{matrix}
    \dfrac{\Phi(x + 1, y) - \Phi(x - 1, y)}{2} \\
    \dfrac{\Phi(x, y + 1) - \Phi(x, y - 1)}{2}
\end{matrix}
\right]^T
$$

While the second term $$\dfrac{\partial \textbf{x}}{\partial \xi}$$ is:

To remind you of the projection equation, we write the equation again here with a little change:

$$Z\textbf{x} = Z\left[\begin{array}{c}
    x \\
    y \\
    1
\end{array}\right] =
\left[\begin{array}{ccc}
    f_x & 0 & c_x \\
    0 & f_y & c_y \\
    0 & 0 & 1
\end{array}\right]
\left[\begin{array}{cccc}
    1 & 0 & 0 & 0 \\
    0 & 1 & 0 & 0 \\
    0 & 0 & 1 & 0
\end{array}\right]
\operatorname{exp}(\hat{\xi})
\left[\begin{array}{c}
    X' \\
    Y' \\
    Z' \\
    1
\end{array}\right]
$$

where $$[X', Y', Z', 1]^T$$ is the current position of a point $$[X, Y, Z, 1]^T$$ at current frame.

We assume that the movement of object between 2 frames is really small, the approximation below is true:

$$\operatorname{exp}(\hat{\xi}) = \mathbb{I}_{4\times4} + \hat{\xi}$$

The second term $$\dfrac{\partial \textbf{x}}{\partial \xi}$$ is:

$$\dfrac{\partial \textbf{x}}{\partial \xi} =
\left[
\begin{array}{ccc}
    \dfrac{f_x}{Z'} & 0 & -\dfrac{X'f_x}{(Z')^2} \\
    0 & \dfrac{f_y}{Z'} & -\dfrac{Y'f_y}{(Z')^2}
\end{array}
\right]

\left[
\begin{array}{cccccc}
    0 & Z' & -Y' & 1 & 0 & 0 \\
    -Z' & 0 & X' & 0 & 1 & 0 \\
    Y' & -X' & 0 & 0 & 0 & 1 \\
\end{array}
\right]
$$

Some of you may ask how can we know the depth value $$Z'$$?

Obviously, because we project the 3D model into image plane, we definitely can know this (we are kings in computer graphics). In OpenGL, we can access depth map by the function [glReadPixel](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glReadPixels.xhtml), but with openGLES, a little trick is required that we have to compact depth value in fragment shader into RGBA value and render it before accessing with glReadPixel since openGLES doesn't support reading depth map operator, but there will be variance.

### Rendering

Because our camera is a little bit different to normal schema in OpenGL that is our camera simulates the real camera looking in positive direction of $$z$$ axis. So, the look at matrix and projection matrix would be different.

$$\begin{aligned}
    L &= \left[
        \begin{matrix}
            1 & 0 & 0 & 0 \\
            0 & -1 & 0 & 0 \\
            0 & 0 & -1 & 0 \\
            0 & 0 & 0 & 1
        \end{matrix}
    \right] \\
    P &= \left[
        \begin{matrix}
            \dfrac{2f_x}{w} & 0 & 1 - \dfrac{2c_x}{w} & 0 \\
            0 & -\dfrac{2f_y}{h} & \dfrac{2c_y}{h} -1 & 0 \\
            0 & 0 & -\dfrac{Z_f + Z_n}{Z_f - Z_n} & -\dfrac{2Z_fZn}{Z_f - Z_n} \\
            0 & 0 & -1 & 0
        \end{matrix}
    \right] \\
\end{aligned}$$

To know how to construct the matrices, visit [this](http://www.songho.ca/opengl/gl_projectionmatrix.html).

## Demonstration

[![Single Object Tracking](https://res.cloudinary.com/marcomontalbano/image/upload/v1667062876/video_to_markdown/images/youtube--V0rqnS49Jmo-c05b58ac6eb4c4700831b2b3070cd403.jpg)](https://www.youtube.com/watch?v=V0rqnS49Jmo&feature=youtu.be "Single Object Tracking")

[![Multiple-Object Tracking](https://res.cloudinary.com/marcomontalbano/image/upload/v1667062919/video_to_markdown/images/youtube--zMS4lG3k6I8-c05b58ac6eb4c4700831b2b3070cd403.jpg)](https://www.youtube.com/watch?v=zMS4lG3k6I8 "Multiple-Object Tracking")

## Reference

To comprehend the whole system, we recommend you read [[1]](#1), [[2]](#2), [[3]](#3), [[4]](#4) and [[5]](#5) for further improvement in speed.

[1] Prisacariu, Victor A., and Ian D. Reid. "PWP3D: Real-time segmentation and tracking of 3D objects." International journal of computer vision 98.3 (2012): 335-354.

[2] Prisacariu, Victor Adrian, et al. "Real-time 3d tracking and reconstruction on mobile phones." IEEE transactions on visualization and computer graphics 21.5 (2014): 557-570.

[3] Bibby, Charles, and Ian Reid. "Robust real-time visual tracking using pixel-wise posteriors." European conference on computer vision. Springer, Berlin, Heidelberg, 2008.

[4] Tjaden, Henning, et al. "A region-based gauss-newton approach to real-time monocular multiple object tracking." IEEE transactions on pattern analysis and machine intelligence 41.8 (2018): 1797-1812.

[5] Stoiber, Manuel, et al. "A sparse gaussian approach to region-based 6DoF object tracking." Proceedings of the Asian Conference on Computer Vision. 2020.

[6] Felzenszwalb, Pedro F., and Daniel P. Huttenlocher. "Distance transforms of sampled functions." Theory of computing 8.1 (2012): 415-428.


text:
---
title: "Best Xiaomi phones of 2020: these are the top Mi, Redmi and Pocophone devices"
author: "myicthub"
date: 2020-01-01 00:00:00
image: ./xiaomi.jpg
featured: true
keywords:
  - xiaomi
  - best xiaomi phones
  - redmi
  - pocophone
categories:
  - mobile
  - Xiaomi
---

This list of the best Xiaomi phones should be one of the first places you look for a new phone if you're in the market for something affordable; phones from this Chinese company combine the features of mid-range or top-end devices, with lower price tags than you'd expect.

Xiaomi is quickly becoming a major player in Europe thanks to its aggressive pricing, with savvy phone buyers seeing the brand as a way to get a device with the latest design and top-end specs, without paying flagship prices. Could 2020 be the year it takes on top competition like Samsung, Huawei and Apple? Only time will tell.

Xiaomi markets its phones under three brand names: Mi, Redmi and Pocophone; Mi tends to be its main mid-range brand, with Redmi and Pocophone being its budget series. Well, Pocophone used to be a sub-brand until it 'declared independence' so to speak, but we've included the one phone it put out while it was still part of Xiaomi.

At the time of writing, our list is mainly populated with Mi smartphones, as that's the brand Xiaomi has focused on in Western markets. However, the company seems to be ramping up releases of Redmi devices, and Pocophone handsets have proven popular too, so we could see a wider mix in the future.

There are two absences from this buying guide at the moment: the Xiaomi Mi Note 10 and Redmi Note 8T. We're currently reviewing both phones, and we'll add them to this list when we've decided where they rank.

We're also expecting to see the Xiaomi Mi 10 (and maybe other devices from the company) at the Mobile World Congress 2020 expo in February, and there's a good chance that it'll earn a place on this list, seeing as the Mi 9 currently tops it.

Here's our ranking of the best Xiaomi phones, including Mi, Redmi and Pocophone handsets, that you can buy right now.

license: MIT

repository: kingkyle/myicthub

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: kingkyle/myicthub


text:
[HTML5 與 JavaScript：Web Fullstack 開發入門，第三版](https://www.moko365.com/enterprise/ap100-html5-javascript-apps-cloud)

## Jollen's Node.js Training

Simples for websocket client and server. The server is in Node.js

Please see www.moko365.com for more course information.

Use [jollen/isomorphic-js-demo](https://github.com/jollen/isomorphic-js-demo) as the frontend for testing [server/07-websocket-data-push](https://github.com/jollen/html5-websocket-nodejs/tree/master/server/07-websocket-data-push).


text:
{Queue} is a data structure similar to a [thread
pool](http://en.wikipedia.org/wiki/Thread_pool_pattern). Tasks added to a Queue
will be processed in parallel through a `worker` function up to the
`concurrency` limit. They are given to workers in index order (using
`Array.prototype.shift`). It is suited to more chaotic situations where
asynchronous operations may need to start at any time or be halted abruptly.
Complex UI operations come to mind.

### States

{Queue} has two states: "running" and "stopped". It begins in a **stopped
state** and will not begin processing tasks until {Queue#start} has been
called. {Queue#stop} will transition back into the "stopped" state.

### Events

{Queue} uses the [js-signals](http://millermedeiros.github.io/js-signals/)
library to dispatch events as tasks are added and completed. {Queue#on} and
{Queue#off} are used to add and remove event listeners. The events:

* {Queue#event:saturated}
* {Queue#event:empty}
* {Queue#event:drain}

### Array methods

{Queue}'s prototype object is an instance of {Array}. That means that the
standard {Array} properties and methods are present and behave how you would
expect them to behave. The following methods have been modified for {Queue}
(but keep the same parameter signatures by delegating to {Array}):

#### Mutator methods

These mutators delegate to their {Array} equivalents and then, if needed, kick
off task processing or dispatch the `"saturated"` event:

* {Queue#push}
* {Queue#pop}
* {Queue#reverse}
* {Queue#shift}
* {Queue#sort}
* {Queue#splice}
* {Queue#unshift}

#### Iteration methods

These iteration methods delegate to their {Array} equivalents and then return a
new (stopped) {Queue} rather than a new {Array}:

* {Queue#concat}
* {Queue#filter}
* {Queue#map}
* {Queue#slice}

## start

Transitions the {Queue} into the "running" state and begins processing tasks.

## stop

{Queue#stop} will begin transitioning the {Queue} into the "stopped" state,
returning a {Promise} which will be fulfilled when all currently-running tasks
in the {Queue} have completed.

## on

Add an event listener `callback` of type `key` to this {Queue}.

## off

Remove all event listeners of type `key` from this {Queue}. If `callback` is
passed, remove only that event listener.

## saturated

Dispatched when {Queue#length} equals the concurrency limit (meaning further
tasks will be queued).

## empty

Dispatched when a worker begins running the last item.

## drain

Dispatched when a worker completes the last item.

## clone

Makes a copy of this {Queue} with the same `worker` and `concurrency`. Intended
mainly for use by the {Array}-derived methods {Queue#concat}, {Queue#filter},
{Queue#map}, and {Queue#slice}.

## pop

Removes the last element from this {Queue} and returns that element. See
{Array#pop} on MDN.

## push

Adds one or more elements to the end of this {Queue} and returns the new length
of the {Queue}. See {Array#push} on MDN.

## reverse

Reverses the order of the elements of this {Queue} -- the first becomes the
last, and the last becomes the first. See {Array#reverse} on MDN.

## shift

Removes the first element from this {Queue} and returns that element. See
{Array#shift} on MDN.

## sort

Sorts the elements of this {Queue} in place and returns the {Queue}. See
{Array#sort} on MDN.

## splice

Adds and/or removes elements from this {Queue}, returning the {Queue}. See
{Array#splice} on MDN.

## unshift

Adds one or more elements to the front of the {Queue} and returns the new
length of the {Queue}. See {Array#unshift} on MDN.

## concat

Returns a new (stopped) {Queue} comprised of this {Queue} joined with other
{Queue}(s) and/or value(s). See {Array#concat} on MDN.

## slice

Extracts a section of the {Queue} and returns a new (stopped) {Queue}. See
{Array#slice} on MDN.

## filter

Creates a new (stopped) {Queue} with all of the elements of this {Queue} for
which the provided filtering function returns true. See {Array#filter} on MDN.

## map

Creates a new (stopped) {Queue} with the results of calling a provided function
on every element in this {Queue}. See {Array#map} on MDN.

gha_language: JavaScript

gha_license_id: NOASSERTION


text:
# Description

**Type:** Specific
**Requires CredSSP:** No

This resource is responsible for provisioning the distributed cache to the
service it runs on. This is required in your farm on at least one server (as
the behavior of SPFarm is to not enroll every server as a cache server).
The service will be provisioned or de-provisioned based on the
Ensure property, and when provisioned the CacheSizeInMB property and
ServiceAccount property will be used to configure it. The property
createFirewallRules is used to determine if exceptions should be added to the
windows firewall to allow communication between servers on the appropriate
ports.

The ServerProvisionOrder optional property is used when a pull server is
handing out configurations to nodes in order to tell this resource about a
specific order of enabling the caches. This allows for multiple servers to
receive the same configuration, but they will always check for the server
before them in the list first to ensure that it is running distributed cache.
By doing this you can ensure that you do not create conflicts with two or more
servers provisioning a cache at the same time. Note, this approach only makes
a server check the others for distributed cache, it does not provision the
cache automatically on all servers. If a previous server in the sequence does
not appear to be running distributed cache after 30 minutes, the local server
that was waiting will begin anyway. The expected values for ServerProvisionOrder
are the hostnames `$env:COMPUTERNAME` of the servers.

The default value for the Ensure parameter is Present. When not specifying this
parameter, the distributed cache is provisioned.

repository: ykuijs/SharePointDsc

gha_language: C#

gha_license_id: MIT

repo_name: ykuijs/SharePointDsc


text:
# postcss-flexbox
PostCSS Flexbox provides an easy to use option for using CSS3 Flexbox layouts. This is supported by IE 10+ and all evergreen browsers.

## Installation
npm install postcss-flexbox

## Dependencies
[PostCSS Autoprefixer](https://github.com/postcss/autoprefixer)

Please add autoprefixer after postcss-flexbox. This will ensure all the appropriate vendor prefixes are added. Flexbox is not supported without these prefixes in some browsers yet. Please refer [here](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes) for detailed information.

## Usage
CSS3 Flexbox lets you set the layout for container divs: horizontal alignment of children or vertical. The children can in turn choose the space they occupy in the container and the alignment as well. Below are examples to show how this works. [Here is a detailed blogpost I wrote on building using Flexbox in Coursera's tech blog](https://tech.coursera.org/blog/2015/06/23/flexbox-at-work/)

postcss-flexbox offers 2 props to set on a selector:

1. box : This is to make a HTML element a flexbox
   Below are the values it can take. Please provide these values separated by a empty space.
   Provide a combination of these values and see the wonders of Flexbox working effortlessly.

   One of the following options is necessary to specify the direction of laying things out:
   1. horizontal
   2. horizontal-reverse
   3. vertical
   4. vertical-reverse

   Here are the rest of the options which will apply based on the direction:

   1. top
   2. bottom
   3. left
   4. right
   5. middle (vertical center)
   6. center (horizontal center)
   7. space-around
   8. space-between
   9. wrap
   10. wrap-reverse

2. box-item : This is to align or adjust size of elements within a flexbox.
   Here are the list of options. Please specify them with a space between.
   You can provide the alignment option like top or right along with the size option like flex-1.
   Use a combination of these.

   1. top
   2. bottom
   3. right
   4. left
   5. middle
   6. center
   7. stretch
   8. flex-auto
   9. flex-1 ... flex-12
   10. flex-none

### Horizontal box
    .horizontal-box {
      box: horizontal;
    }
![HorizontalBox](https://lh3.googleusercontent.com/-aSnIdPAty78/VoCc3jOo0eI/AAAAAAAAOv0/7UMisdT-YSk/s1024-Ic42/snapshot1.png "Horizontal Box")

## Horizontal box + items centered
    .horizontal-box.align-items-center {
       box: horizontal center;
    }
![Horizontal Box Items Centered](https://lh3.googleusercontent.com/-Q2Umh0TOeBE/VoCc4X-BvDI/AAAAAAAAOv8/sLsPCjvSQOc/s1016-Ic42/snapshot2.png "Horizontal Box Items Centered")

## Horizontal box + items centered at the bottom
    .horizontal-box.align-items-bottom-center {
       box: horizontal bottom center;
    }
![Horizontal Box Items Centered at Bottom](https://lh3.googleusercontent.com/-ldkAKXJxMEk/VoCc447MEMI/AAAAAAAAOwA/vugH4TyvQx4/s1024-Ic42/snapshot3.png "Horizontal Box Items Centered at Bottom")

## Horizontal box + items with space between
    .horizontal-box.align-items-space-between {
      box: horizontal space-between;
    }
![Horizontal Box with space between](https://lh3.googleusercontent.com/-7CGd7I_CmeI/VoCfpUBJ9MI/AAAAAAAAOw0/AOdArcV--j4/s1016-Ic42/snapshot4.png "Horizontal box with space between items")

## Horizontal box + space around items
    .horizontal-box.align-items-space-around {
      box: horizontal space-around;
    }
![Horizontal Box with space around](https://lh3.googleusercontent.com/-kKDwSrYOPkU/VoChEgjw4fI/AAAAAAAAOxE/gzSvwOnv0og/s1018-Ic42/snapshot5.png "Horizontal box with space around items")

## Horizontal Box + align items bottom right
    .horizontal-box.align-items-bottom-right {
      box: horizontal bottom right;
    }
![Horizontal Box with items in bottom right and items](https://lh3.googleusercontent.com/-641BL1qkDKs/VoCiW8RLCgI/AAAAAAAAOxQ/ufAy18jQ92M/s1018-Ic42/snapshot6.png "Horizontal box with items aligned bottom right")

## Horizontal Box with items in the ratio 1:2:auto
    .horizontal-box {
      box: horizontal;
    }

    .first {
      box-item: flex-1;
    }

    .second {
      box-item: flex-2;
    }
![Horizontal Box with items 1:2:auto](https://lh3.googleusercontent.com/-GMt9tFFaavE/VoClKYn8cnI/AAAAAAAAOxs/5RuoFcH7vnk/s1016-Ic42/snapshot7.png "Horizontal box with items in 1:auto:auto")

## Horizontal Box : align items individually
    .horizontal-box{
      box: horizontal;
    }
    .first, .second, .third, .fourth {
      box-item: flex-1;
    }
    .first {
      box-item: top;
    }
    .second {
      box-item: center;
    }
    .third {
      box-item: stretch;
    }
    .fourth {
      box-item: bottom;
    }
![Horizontal Box with items aligned individually](https://lh3.googleusercontent.com/-M6Whv0ekXJc/VoCmXPxgGCI/AAAAAAAAOx4/6VSn7cuCNkU/s1016-Ic42/snapshot8.png "Horizontal box with items aligned individually")

## Horizontal box wrap items
    .horizontal-box {
      box: horizontal wrap;
    }
![Horizontal Box with items wrapped for smaller widths](https://lh3.googleusercontent.com/-rUa839zO1fA/VoCp14NQbZI/AAAAAAAAOyE/1tJnDZ3x1hs/s376-Ic42/snapshot9.png "Horizontal box with items wrapped for smaller widths")

## Vertical box with items in ratio auto:1:auto
    .vertical-box {
      box: vertical;
    }
    .second {
      box-item: flex-1;
    }
![Vertical Box with items auto:1:auto](https://lh3.googleusercontent.com/-EHVdgtYCCGk/VoCqwOvi2UI/AAAAAAAAOyM/hP-BrtyYwBw/s512-Ic42/snapshot10.png "Vertical Box")

## Vertical box with fullbleed item
    .vertical-box {
      box: vertical;
    }

    .fullbleed {
      box-item: flex-1;
    }
![Vertical Box with one fullbleed item](https://lh3.googleusercontent.com/-iO2WxZJB7tQ/VoCr3py-M_I/AAAAAAAAOyY/MJ0CNj0ogYQ/s512-Ic42/snapshot11.png "Vertical box with fullbleed item")

## [Changelog] (./CHANGELOG.md "Changelog")
## [License](./LICENSE "License")

repository: gooklani/postcss-flexbox

repo_name: gooklani/postcss-flexbox


text:
# Community Project (Groups of 5)
The second to last project here in the Array Bootcamp! Congratulations on reaching this far. In this project you'll be working on a group project in teams of 5, with the goal of providing something unique to the community of Cheyenne, WY! You are assigned a company in Cheyenne to work with, and you'll be working on creating a website with features they want to have provided on it. In this project, leadership from Array will act as the "client" in weekly client meetings that you have to attend as a group to gather information on the project and provide updates/statuses on the project.

### Technologies Required

- HTML, CSS, Bootstrap
- JavaScript, ES6
- NodeJS, ExpressJS, Mongoose
- MongoDB

## Project Requirements

Your general project requirements are going to come from your client meetings with the leadership teams. We're going to tell you the features we want, and then your team's tech leader will decide the feasibility of "additional" things we want besides the true requirements of the project. Good luck to everyone!

There are no bonus taskes for this assignment. Honor requirements will be automatically rewarded to the group if their project receives good review during the presentations as well as the code passes a 90/100 standard when grading!

repository: lindlym/community-project-template

branch_name: refs/heads/main

repo_name: lindlym/community-project-template


text:
# Content Authoring Accelerators build for Salesforce #
In this directory you will find files needed to set up accelerators on Salesforce platform.

## Quick Start

```bash
# Install dependencies
$ npm install

# Build project
$ gulp salesforce
```

## Content types Schema Json files
Content Type Schemas for Content Authoring App can be found in `dist/salesforce/renders/RENDER_NAME/RENDER_NAME.json`
e.g. `dist/salesforce/renders/image/image.json`.
Note that some renders have multiple schemas, which have to be populated, for a render to work.
e.g. inside `dist/salesforce/renders/banner/` there are `banner.json` and `link.json`.

## Handlebars templates
Built Handlebars templates can be found in `dist/salesforce/renders/RENDER_NAME/RENDER_NAME.hbs`
e.g. `dist/salesforce/renders/image/image.hbs`.

Note: for complex renders to work (those that have other renders integrated), you need to change content types inside handlebars templates.

E.g. go to `src/salesforce/templates/slider.hbs` and open it in editor.
Find the following line:
```
{{#iff [@type] '==' 'http://schema.cms.amplience.com/f0b1f9c8-9fbd-4470-aeb2-543c3cb01f19'}}
```
Replace `f0b1f9c8-9fbd-4470-aeb2-543c3cb01f19` with your type. Type can be found in renders json.

## JS Dependencies
All JS dependencies for renders are included in one minified file: `dist/salesforce/libs.min.js`.
JS dependencies are composed of helper scripts and 3d party libs. These dependencies are to be included.
This file is to be included in the header of the page.

## JS Initialization
To properly display any render, it is needed to include initialization js file `dist/salesforce/initAll.js` at the bottom of html page (before renders html is included).

## Render types
In `dist/salesforce/renderTypes.js` you can find type ids for each content type. This information can be extracted from DAM.
In order for handlebars templates to work properly, you need to replace ids with the ones from your account.

## Handlebars helpers
Handlebars helpers are defined in `dist/salesforce/handlebars_helpers.js`.
They are needed to output and format data, coming from Handlebars templates.

## CSS Dependencies
All CSS dependencies for renders are included in one minified file: `dist/salesforce/styles.min.css` in the header of the page.

## Visualisations
```dist/salesforce/visualisation.html``` is used for visualisations in DAM. One visualisation file is used for all renders.
Make sure you define proper path to visualisation file in content types.

repository: HristinaTodorova/tempur-ca-renders

repo_name: HristinaTodorova/tempur-ca-renders


text:
# fast-csv-experiments
Tests and Validation of the npm fast-csv package

## Setup

After cloning the newly created repo, I changed into the directory and ran:
```
npm init
npm install -S fast-csv
```

*Note* my testing uses modules and I have an alias for the long command required:
`alias nx=node --experimental-modules`.

Thus all my tests are executed as follows:
`nx basename.mjs`.

## Organization of tests

The tests are divided into `read` and `write` and are in folders with those names.
Each test will at least have a node script like this: `basename.mjs`.
If there are input or output files, they will share the `basename` but with
suffixes added and with different extensions. For example, an input file might be:
`basename_input.csv`.

## Read/Write Tests

These tests read in a file and write it back out. Thus the input and output
should be equivalent. Each test has a basename such as `write1`. This is provided
to the bash script `runtest.sh` like this: `sh runtest.sh write1`.

The script runs this: `node --experimental-modules write1.mjs`. The JavaScript reads
in `write1_input.[tc]sv` and writes out `write1_output.txt`. It then runs a diff
command against the input and output files to compare them.

1. `write1`: simple CSV to CSV
2. `write2`: simple TSV to TSV
3. `write3`: a TSV file with newlines in cell values (see `write3_input.tsv`)
4. `en_tn_tit`: the UTN for the book of Titus
5. `useTabs`: a TSV file that contains tab characters in the column values

## Read Tests

The only read test processes a CSV file and compares the result against
the expected results array of JS Objects.

To run: `node --experimental-modules read1.mjs`.

repository: mandolyte/fast-csv-experiments

repo_name: mandolyte/fast-csv-experiments


text:
Kitchen Sync
============

### Goal

Build your first Couchbase Mobile app in just a few minutes! Take an existing Android application
and add data persistence along with offline support!

![Application Architecture](https://raw.githubusercontent.com/couchbaselabs/mini-hacks/master/kitchen-sync/topology.png "Typical Couchbase Mobile Architecture")

### Setup

 - Clone this repo, or download the [.zip](https://github.com/couchbaselabs/mini-hacks/archive/master.zip).
 - Make sure you are on the latest Android Studio in the `Stable` channel.
 - Launch Android Studio, choose 'Import Project...' and select the `android` folder.
 - Verify your environment is working by debugging the app on your Android device.

 	Note: If you are running on a Mac, the Gradle build script will automatically download
 	Sync Gateway into your `build` folder. It will even start and stop it for you every time
 	you debug your app!

 - Mac users: while your app is running on device, open the
   [Sync Gateway admin console](http://localhost:4985/_admin/). Feel free to look around, but we'll
   come back to this later.

 - In addition to what is already in the MainActivity.java file, import..

    import com.couchbase.lite.android.AndroidContext;
    import com.couchbase.lite.Mapper;
    import com.couchbase.lite.Emitter;

    import java.util.ArrayList;
    import java.net.URL;
 ### Tutorial

 1. Let's begin by starting up Couchbase Lite. Create a new `startCBLite` method on `MainActivity`:
 ```java

	protected void startCBLite() throws Exception {
```

 2. Now we need to get a reference to our database object. To do that, add:
 ```java

    manager = new Manager(new AndroidContext(this), Manager.DEFAULT_OPTIONS);
    database = manager.getDatabase("kitchen-sync");
```

 3. Next, we create an index to allow for fast queries. Couchbase Lite uses MapReduce queries, which
    let us create our queries using plain-old Java functions. We can also do powerful
    transformations of documents, compute aggregates, etc. In this project, however, we're going to
    keep things simple and just index our documents by date.
 ```java

	viewItemsByDate = database.getView("viewItemsByDate");
	viewItemsByDate.setMap(new Mapper() {
	    @Override
	    public void map(Map<String, Object> document, Emitter emitter) {
	        Object createdAt = document.get("created_at");
	        if (createdAt != null) {
	            emitter.emit(createdAt.toString(), null);
	        }
	    }
	}, "1.0");
 ```

 4. Now that we've opened the database and created our index, lets call this new method from our
    `onCreate` function:
 ```java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	...
        addItemEditText.setOnKeyListener(this);

        startCBLite();

        ...
```

 5. Next, let's initialize the `DataAdapter` for our list view. Create the following method, which
    creates our custom adapter and listens for taps on each row:
 ```java

	private void initItemListAdapter() {
	        kitchenSyncArrayAdapter = new KitchenSyncListAdapter(
                getApplicationContext(),
                R.layout.list_item,
                R.id.label,
                new ArrayList<QueryRow>()
        );
        itemListView.setAdapter(kitchenSyncArrayAdapter);
        itemListView.setOnItemClickListener(this);
        itemListView.setOnItemLongClickListener(this);
    }
```

 6. Now let's add this method to `onCreate`:
 ```java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	...
        addItemEditText.setOnKeyListener(this);

        startCBLite();

        initItemListAdapter();

        ...
    ```

 7. We need the ability to create a new Couchbase Lite document from the text edit box's value. In
    `MainActivity` you will find the `createListItem` method. Replace the last line, "return null;"
    with the following:
 ```java
        Document document = database.getDocument(id); // creates a document with the given id

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("_id", id);
        properties.put("text", text);
        properties.put("check", Boolean.FALSE);
        properties.put("created_at", currentTimeString);
        document.putProperties(properties);

         return document;
 ```

    That `putProperties()` method is the one that actually creates the document in Couchbase Lite.

 8. Next, we start our `LiveQuery`. Like a regular `Query`, it gives us the ability to filter and
    order the index we created in step 3. However, it also can send us results that appear
    later--even after we've already iterated through the results! Let's create our new method like
    this:
 ```java

    private void startLiveQuery() throws Exception {

        if (liveQuery == null) {

            liveQuery = viewItemsByDate.createQuery().toLiveQuery();

            liveQuery.addChangeListener(new LiveQuery.ChangeListener() {
                public void changed(final LiveQuery.ChangeEvent event) {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            kitchenSyncArrayAdapter.clear();
                            for (Iterator<QueryRow> it = event.getRows(); it.hasNext();) {
                                kitchenSyncArrayAdapter.add(it.next());
                            }
                            kitchenSyncArrayAdapter.notifyDataSetChanged();
                        }
                    });
                }
            });

            liveQuery.start();

        }

    }
 ```

 9. Add this method to `onCreate` as well:
 ```java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	...
        addItemEditText.setOnKeyListener(this);

        startCBLite();

        initItemListAdapter();

        startLiveQuery();

        ...
```

 10. Now we need to handle checkbox touches. Couchbase Lite documents are like versioned-maps. If we
     want to change a `Document` we do it by adding a new `Revision`. We can do this easily by just
     supplying a `HashMap` containing a snapshot of the new values our document should have. Add the
     code below for the `onItemClick` handler that we already stubbed out for you in `MainActivity`:
 ```java

        QueryRow row = (QueryRow) adapterView.getItemAtPosition(position);
        Document document = row.getDocument();
        Map<String, Object> newProperties = new HashMap<String, Object>(document.getProperties());

        boolean checked = ((Boolean) newProperties.get("check")).booleanValue();
        newProperties.put("check", !checked);

        try {
            document.putProperties(newProperties);
            kitchenSyncArrayAdapter.notifyDataSetChanged();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Error updating database, see logs for details", Toast.LENGTH_LONG).show();
            Log.e(TAG, "Error updating database", e);
        }
```

 11. What about deleting items? Let's add the following code to our `onItemLongClick` handler so
     that long-presses let us prompt the user to delete that row:
 ```java

        QueryRow row = (QueryRow) adapterView.getItemAtPosition(position);
        final Document clickedDocument = row.getDocument();
        String itemText = (String) clickedDocument.getCurrentRevision().getProperty("text");

        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        AlertDialog alert = builder.setTitle("Delete Item?")
                .setMessage("Are you sure you want to delete \"" + itemText + "\"?")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        try {
                            clickedDocument.delete();
                        } catch (Exception e) {
                            Toast.makeText(getApplicationContext(), "Error deleting document, see logs for details", Toast.LENGTH_LONG).show();
                            Log.e(TAG, "Error deleting document", e);
                        }
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // Handle Cancel
                    }
                })
                .create();

        alert.show();
```

 13. Now is a great time to build and run on device. You should see all of your new list items saved.

 14. Let's add sync! First, we need to provide a URL for our Couchbase Sync Gateway. If you are
     doing this tutorial on a Mac and deploying to a real device, then enter the IP address of your
     Wifi interface (i.e. don't use localhost).  If you are deploying to an emulator, you will need
     to use `<IP_ADDRESS>` for the IP. Add the following declaration near the other instance variable
     declarations in `MainActivity`:
 ```java

 	    private static final String SYNC_URL = "http://<YOUR_WIFI_OR_ETHERNET_IP>:4984/kitchen-sync";
```

 15. That's the hardest part! Now we need to add our `startSync` method which, in this case, will
     continuously sync all local and remote changes.
 ```java

 	    private void startSync() throws Exception {

        URL syncUrl;
        try {
            syncUrl = new URL(SYNC_URL);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }

        Replication pullReplication = database.createPullReplication(syncUrl);
        pullReplication.setContinuous(true);

        Replication pushReplication = database.createPushReplication(syncUrl);
        pushReplication.setContinuous(true);

        pullReplication.start();
        pushReplication.start();

        pullReplication.addChangeListener(this);
        pushReplication.addChangeListener(this);

    }
```

 16. Now let's add a call to `startSync` in our `onCreate` override:
 ```java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	...
        addItemEditText.setOnKeyListener(this);

        startCBLite();

        initItemListAdapter();

		startLiveQuery();

        startSync();

        ...
```
 17. Build and run time! Shortly after launching, you should see lots of sync activity scrolling by
     in ADB's logcat window for your device. Make sure that you have some list items for
     Couchbase Lite to sync.

 18. Let's go see the results of sync in the Sync Gateway Admin Console. Open your browser to
     [http://localhost:4985/_admin/](http://localhost:4985/_admin/), and click on the
     [kitchen-sync](http://localhost:4985/_admin/db/kitchen-sync) link. You will land on the
     **Documents** page, which will list all documents found. Clicking on a document id will reveal
     the contents of the document.

 19. Finally, we'd love to hear from you. [Tell us what you think](https://docs.google.com/forms/d/1Qs9svNccKCC5iji6NXC35uCvdmtFzB0dopz57iApSnY/viewform)!


text:
# [752.  Each wheel has 10 slots:  *'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'* . The wheels can rotate freely and wrap around: for example we can turn  *'9'*  to be  *'0'* , or  *'0'*  to be  *'9'* . Each move consists of turning one wheel one slot.

The lock initially starts at  *'0000'* , a string representing the state of the 4 wheels.

You are given a list of  *deadends*  dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.

Given a  *target*  representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.

**Example 1:**

```
Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6
Explanation:
A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end "0102".

```

**Example 2:**

```
Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation:
We can turn the last wheel in reverse to move from "0000" -> "0009".

```

**Example 3:**

```
Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
Output: -1
Explanation:
We can't reach the target without getting stuck.

```

**Example 4:**

```
Input: deadends = ["0000"], target = "8888"
Output: -1

```

**Constraints:**

-  *1 <= deadends.length <= 500*
-  *deadends[i].length == 4*
-  *target.length == 4*
- target **will not be**  in the list  *deadends* .
-  *target*  and  *deadends[i]*  consist of digits only.

# [752. 打开转盘锁][cnTitle]

**中等**

你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字：  *'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'*  。每个拨轮可以自由旋转：例如把  *'9'*  变为  *'0'* ， *'0'*  变为  *'9'*  。每次旋转都只能旋转一个拨轮的一位数字。

锁的初始数字为  *'0000'*  ，一个代表四个拨轮的数字的字符串。

列表  *deadends*  包含了一组死亡数字，一旦拨轮的数字和列表里的任何一个元素相同，这个锁将会被永久锁定，无法再被旋转。

字符串  *target*  代表可以解锁的数字，你需要给出最小的旋转次数，如果无论如何不能解锁，返回 -1。

**示例 1:**

```
输入：deadends = ["0201","0101","0102","1212","2002"], target = "0202"
输出：6
解释：
可能的移动序列为 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。
注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 这样的序列是不能解锁的，
因为当拨动到 "0102" 时这个锁就会被锁定。

```

**示例 2:**

```
输入: deadends = ["8888"], target = "0009"
输出：1
解释：
把最后一位反向旋转一次即可 "0000" -> "0009"。

```

**示例 3:**

```
输入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
输出：-1
解释：无法旋转到目标数字且不被锁定。

```

**示例 4:**

```
输入: deadends = ["0000"], target = "8888"
输出：-1

```

**提示：**

1. 死亡列表  *deadends*  的长度范围为  *[1, 500]* 。
2. 目标数字  *target*  不会在  *deadends*  之中。
3. 每个  *deadends*  和  *target*  中的字符串的数字会在 10,000 个可能的情况  *'0000'*  到  *'9999'*  中产生。

# 算法思路

# 测试用例
```
752. Open the Lock 752. 打开转盘锁 Medium
```

[enTitle]: https://leetcode.com/problems/open-the-lock/
[cnTitle]: https://leetcode-cn.com/problems/open-the-lock/

repository: philippzhang/leetcodeLearnJava

gha_language: Java

repo_name: philippzhang/leetcodeLearnJava


text:
---
Module Name: PnP.PowerShell
title: Set-PnPFileCheckedOut
schema: 2.0.0
applicable: SharePoint Online
external help file: PnP.PowerShell.dll-Help.xml
online version: https://pnp.github.io/powershell/cmdlets/Set-PnPFileCheckedOut.html
---

# Set-PnPFileCheckedOut

## SYNOPSIS
Checks out a file

## SYNTAX

```powershell
Set-PnPFileCheckedOut [-Url] <String> [-Connection <PnPConnection>]
```

## DESCRIPTION

Allows to check out a file.

## EXAMPLES

### EXAMPLE 1
```powershell
Set-PnPFileCheckedOut -Url "/sites/testsite/subsite/Documents/Contract.docx"
```

Checks out the file "Contract.docx" in the "Documents" library.

## PARAMETERS

### -Connection
Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection.

```yaml
Type: PnPConnection
Parameter Sets: (All)

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -Url
The server relative url of the file to check out

```yaml
Type: String
Parameter Sets: (All)

Required: True
Position: 0
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```

## RELATED LINKS

[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

repository: radityoardi/PnP-PowerShell

branch_name: refs/heads/dev

repo_name: radityoardi/PnP-PowerShell


text:
# Rspec_testing

Learning about rspec, applying into previous Enumerables project.

## Built With

Ruby 2.6.5

## Getting Started

To get a local copy up and running follow these simple example steps.

```
Git clone git@github.com:epinczinger/Rspec_enumerables.git
```

## RUN TEST

To run the Rspec and check for testing cases write the following command on the root folder.

```ruby
rspec
```

## Screenshot

![screenshot](/images/screenshot.png)

## Demo Link of Enumerables Project

[Live Demo Link](https://repl.it/@EliasCastaneda/Enumerables).

## Built With

- Ruby
- Rubocop
- Rspec

## Authors

👤 **Esteban Pinczinger**

- Github: [epinczinger](https://github.com/epinczinger)
- Twitter: [@epinczinger](https://twitter.com/epinczinger)
- Linkedin: [Esteban-Pinczinger](https://www.linkedin.com/in/esteban-pinczinger-busai-ab49a254/)

👤 **Jessica Farias**

- Github: [jessicafarias](https://github.com/jessicafarias)
- Twitter: [@FariasRosado](https://twitter.com/FariasRosado)
- Linkedin: [jessica-michelle-farias-rosado](https://www.linkedin.com/in/jessica-michelle-farias-rosado/)

## Getting Started

To get a local copy up and running follow these simple example steps.

1. Open the terminal comand line window
2. `git clone https://github.com/epinczinger/Rspec_enumerables.git`
3. Open the spec folder and execute the bubble_spec.rb script
4. Enjoy!

## 🤝 Contributing

Contributions, issues and feature requests are welcome!

Feel free to check the [issues page](issues/).

## Show your support

Give a ⭐ if you like this project!

## 📝 License

This project is [MIT](LICENSE) licensed.

branch_name: refs/heads/development


text:
# Looplab

> [Live Link](https://looplab.netlify.com/)

## Build Setup

```bash
# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# build for production with minification
npm run build

# build for production and view the bundle analyzer report
npm run build --report
```

For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details

repository: wenfangdu/looplab

repo_name: wenfangdu/looplab


text:
---
parent: Conventions
version: 4.2
---

# Primary navigation

## Perspectives

OpenShift has different perspectives for "administrator" and "developer." These perspectives change the navigation list accordingly to show only relevant pages.

![Perspective switcher](../images/navigation-perspectives.png)

---

## Navigation list

Certain operators, when installed, have the ability to create new navigation items.

*Administrator perspective navigation list:*

![Administrator navigation](../images/navigation-mainnav-admin.png)

*Developer perspective navigation list:*

![Developer navigation](../images/navigation-mainnav-dev.png)

---

## Masthead

*Full:*

![Masthead](../images/navigation-masthead.png)

*Condensed:*

![Masthead mobile](../images/navigation-masthead-mobile.png)

repository: Ranelim/openshift-origin-design

gha_language: HTML

repo_name: Ranelim/openshift-origin-design


text:
# Contribution Guideline
Contributions are welcome. Before sending a pull request

* Conform to the projects code style: 2 spaces for indention. See .editorconfig
* Add tests for what you changed/added/fixed.
* Don't let code coverage drop - run `npm run cover` to see current code coverage.
* Update README.md to document your changes.

## Install dependencies
    npm install

## Test
    npm test

## Coverage
    npm run cover

## Lint
    npm run lint

## Release
Restify-Mongoose uses the module `npm-release` as described below for releases.
It will bump version in `package.json` and release new version to git and npm.

Remember to update [CHANGELOG.md](CHANGELOG.md) **before** release.

    npm run release -- [<newversion> | major | minor | patch | build] -m "<release message>"

The command above enforce the use of [semantic versions](http://semver.org/) when releasing:

Given a version number MAJOR.MINOR.PATCH, increment the:

* **MAJOR** version when you make incompatible API changes,
* **MINOR** version when you add functionality in a backwards-compatible manner, and
* **PATCH** version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

repository: saintedlama/restify-mongoose

repo_name: saintedlama/restify-mongoose


text:
---
id: 510
title: Pretty Target
date: 2010-10-08T23:21:01+00:00
author: MrPhil
layout: post
guid: http://www.mrphilgames.com/?p=510
permalink: /pretty-target/
categories:
  - Gamejams
  - Stacker
---
I created a nice visual target, literally, to aim for. It took me a little bit of time to figure out how to visually display the target separate from the collision mesh. Including, a slow walk down a lane called Child-Parent Scripting Confusion. But, now it is functional.

    October Challenge Progress 10/8

Next Action: Level Two

Total Hours To Date: 18.25


text:
---
title: Acorn estate
date: '2009-01-27 00:00:00 -0700'
published: true
---

![](http://35percent.org/img/acorndemolition.jpeg)

The Wood dene blocks of the Acorn estate comprising 323 homes are demolished. The site is sold to Notting Hill Genesis housing association, which has built 333 new homes of which 54 were approved as social rent. As with Notting Hill's other schemes, we [have shown](http://35percent.org/redefining-social-rent) that were instead delivered as affordable rent - i.e. up to 80% market rent.

[www.35percent.org/wood-dene-regeneration](http://35percent.org/wood-dene-regeneration/)


text:
# React Weather Dashboard

Search for cities and add them to your Dashboard.

![App-Demo](https://cloud.githubusercontent.com/assets/2152969/25304619/7677dc3e-2741-11e7-8c80-d6f5df31d594.png "Application demo")

### Getting Started

There are two methods for getting started with this repo.

#### Familiar with Git?
Checkout this repo, install dependencies, then start the gulp process with the following:

```
> git clone https://github.com/brenotx/react-weather-dashboard.git
> cd react-weather-dashboard
> npm install
> npm start
```

#### Not Familiar with Git?
Click [here](https://github.com/brenotx/react-weather-dashboard/archive/master.zip) then download the .zip file.  Extract the contents of the zip file, then open your terminal, change to the project directory, and:

```
> npm install
> npm start
```

repository: jsdelivrbot/react-weather-dashboard

repo_name: jsdelivrbot/react-weather-dashboard


text:
# Life with Instance

A life manager application developed with Flutter.

## Dependency

- Flutter: https://flutter.io/
- Dart 2: https://www.dartlang.org/

## Usage

```shell
git clone https://github.com/yuwenhuisama/LifeWithInstance.git
cd LifeWithInstance
flutter build apk
```

## Route Map

- Local Storage
- Online Account
- Network Storage

## ScreenShot

<EMAIL_ADDRESS>
## Contact

You are welcomed to make issues for this project !

Or contact with email: yuwenhuisama@outlook.com

repository: yuwenhuisama/LifeWithInstance

repo_name: yuwenhuisama/LifeWithInstance