-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcv2cheatsheet.tex
More file actions
365 lines (306 loc) · 21.4 KB
/
cv2cheatsheet.tex
File metadata and controls
365 lines (306 loc) · 21.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
% Base on http://wch.github.io/latexsheet/}{http://wch.github.io/latexsheet/
\documentclass[10pt,landscape, a4paper]{article}
\usepackage{multicol}
\usepackage{calc}
\usepackage{ifthen}
\usepackage[landscape]{geometry}
\usepackage{hyperref}
\usepackage{minted}
\usepackage{amsmath}
% rescale the whole thing
\usepackage[]{datetime2}
% This sets page margins to .5 inch if using letter paper, and to 1cm
% if using A4 paper. (This probably isn't strictly necessary.)
% If using another size paper, use default 1cm margins.
\ifthenelse{\lengthtest { \paperwidth = 11in}}
{ \geometry{top=.5in,left=.5in,right=.5in,bottom=.5in} }
{\ifthenelse{ \lengthtest{ \paperwidth = 297mm}}
{\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
{\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
}
% Turn off header and footer
\pagestyle{empty}
% Redefine section commands to use less space
\makeatletter
\renewcommand{\section}{\@startsection{section}{1}{0mm}%
{-1ex plus -.5ex minus -.2ex}%
{0.5ex plus .2ex}%x
{\normalfont\large\bfseries}}
\renewcommand{\subsection}{\@startsection{subsection}{2}{0mm}%
{-1explus -.5ex minus -.2ex}%
{0.5ex plus .2ex}%
{\normalfont\normalsize\bfseries}}
\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{0mm}%
{-1ex plus -.5ex minus -.2ex}%
{1ex plus .2ex}%
{\normalfont\small\bfseries}}
\makeatother
% Define BibTeX command
\def\BibTeX{{\rm B\kern-.05em{\sc i\kern-.025em b}\kern-.08em
T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}
% Don't print section numbers
\setcounter{secnumdepth}{0}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0pt plus 0.5ex}
% -----------------------------------------------------------------------
\begin{document}
\raggedright
\footnotesize
\begin{multicols}{2}
% multicol parameters
% These lengths are set only within the two main columns
%\setlength{\columnseprule}{0.25pt}
\setlength{\premulticols}{1pt}
\setlength{\postmulticols}{1pt}
\setlength{\multicolsep}{1pt}
\setlength{\columnsep}{2pt}
\begin{center}
\Large{\textbf{OpenCV 4.x Cheat Sheet (Python version)}} \\
\small{A summary of: \url{https://docs.opencv.org/master/}}
\end{center}
\section{I/O}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = imread("name.png")} & Loads image as BGR (if grayscale, \texttt{B=G=R})\\
\mintinline{python}{i = imread("name.png", IMREAD_UNCHANGED)} & Loads image as is (inc.\ transparency if available)\\
\mintinline{python}{i = imread("name.png", IMREAD_GRAYSCALE)} & Loads image as grayscale\\
\mintinline{python}{imshow("Title", i)} & Displays image $I$\\
\mintinline{python}{imwrite("name.png", i)} & Saves image $I$\\
\mintinline{python}{waitKey(500)} & Wait 0.5 seconds for keypress (0 waits forever)\\
\mintinline{python}{destroyAllWindows()} & Releases and closes all windows\\
\end{tabular}
\subsection{Color/Intensity}
\newlength{\MyLen}
%\settowidth{\MyLen}{\texttt{letterpaper}/\texttt{a4paper} \ }
%\begin{tabular}{@{}p{\the\MyLen}%
% @{}p{\linewidth-\the\MyLen}@{}}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i_gray = cvtColor(i, COLOR_BGR2GRAY)}& BGR to gray conversion\\
\mintinline{python}{i_rgb = cvtColor(i, COLOR_BGR2RGB)}& BGR to RGB (useful for \mintinline{python}{matplotlib})\\
\mintinline{python}{i = cvtColor(i, COLOR_GRAY2RGB)}& Converts grayscale to RGB (\texttt{R=G=B})\\
\mintinline{python}{i = equalizeHist(i)}& Histogram equalization\\
\mintinline{python}{i = normalize(i, None, 0, 255, NORM_MINMAX, CV_8U)} & Normalizes $I$ between 0 and 255\\
\mintinline{python}{i = normalize(i, None, 0, 1, NORM_MINMAX, CV_32F)} & Normalizes $I$ between 0 and 1
\end{tabular}
\subsubsection{Other useful color spaces}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{COLOR_BGR2HSV}& BGR to HSV (Hue, Saturation, Value)\\
\mintinline{python}{COLOR_BGR2LAB}& BGR to Lab (Lightness, Green/Magenta, Blue/Yellow)\\
\mintinline{python}{COLOR_BGR2LUV}& BGR to Luv ($\approx$ Lab, but different normalization)\\
\mintinline{python}{COLOR_BGR2YCrCb}& BGR to YCrCb (Luma, Blue-Luma, Red-Luma)\\
\end{tabular}
\subsection{Channel manipulation}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{b, g, r = split(i)}& Splits the image $I$ into channels\\
\mintinline{python}{b, g, r, a = split(i)}& Same as above, but $I$ has alpha channel\\
\mintinline{python}{i = merge((b, g, r))}& Merges channels into image\\
\end{tabular}
\subsection{Arithmetic operations}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = add(i1, i2)}& $\min(I_1 + I_2, 255)$, i.e.\ saturated addition if \texttt{uint8}\\
\mintinline{python}{i = addWeighted(i1, alpha, i2, beta, gamma)}& $\min(\alpha I_1 + \beta I_2 + \gamma, 255)$, i.e.\ image blending\\
\mintinline{python}{i = subtract(i1, i2)}& $\max(I_1 - I_2, 0)$, i.e.\ saturated subtraction if \texttt{uint8}\\
\mintinline{python}{i = absdiff(i1, i2)}& $\left| I_1 - I_2\right|$, i.e.\ absolute difference\\
\end{tabular}
\textbf{Note:} one of the images can be replaced by a scalar.
\subsection{Logical operations}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = bitwise_not(i)}& Inverts every bit in $I$ (e.g.\ mask inversion)\\
\mintinline{python}{i = bitwise_and(i1, i2)}& Logical \textit{and} between $I_1$ and $I_2$ (e.g.\ mask image)\\
\mintinline{python}{i = bitwise_or(i1, i2)}& Logical \textit{or} between $I_1$ and $I_2$ (e.g.\ merge 2 masks)\\
\mintinline{python}{i = bitwise_xor(i1, i2)}& Exclusive \textit{or} between $I_1$ and $I_2$\\
\end{tabular}
\subsection{Statistics}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{mB, mG, mR, mA = mean(i)} & Average of each channel (i.e.\ BGRA)\\
\mintinline{python}{ms, sds = meanStdDev(i)} & Mean and SDev p/channel (3 or 4 rows each)\\
\mintinline{python}{h = calcHist([i], [c], None, [256], [0,256])} & Histogram of channel \texttt{c}, no mask, 256 bins (0-255)\\
%\mintinline{python}{h = calcHist([i], [0,1], None, [256,256], [0,256, 0,256])} & 2D histogram using channels 0, 1\\
\mintinline{python}{h = calcHist([i], [0,1], None, [256,256],} & 2D histogram using channels 0 and 1, with\\
\multicolumn{1}{r}{\mintinline{python}{[0,256, 0,256])}}&\phantom{ } ``resolution'' 256 in each dimension\\
\end{tabular}
\subsection{Filtering}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = blur(i, (5, 5))} & Filters $I$ with $5\times 5$ box filter (i.e.\ average filter)\\
\mintinline{python}{i = GaussianBlur(i, (5,5), sigmaX=0, sigmaY=0)} & Filters $I$ with $5\times 5$ Gaussian; auto $\sigma$s; ($I$ is \mintinline{python}{float})\\
\mintinline{python}{i = GaussianBlur(i, None, sigmaX=2, sigmaY=2)} & Blurs, auto kernel dimension\\
\mintinline{python}{i = filter2D(i, -1, k)} & Filters with 2D kernel using cross-correlation\\
\mintinline{python}{kx = getGaussianKernel(5, -1)} & 1D Gaussian kernel with length 5 (auto StDev)\\
\mintinline{python}{i = sepFilter2D(i, -1, kx, ky)} & Filter using separable kernel (same output type)\\
\mintinline{python}{i = medianBlur(i, 3)} & Median filter with size=3 (size $\geq 3$)\\
\mintinline{python}{i = bilateralFilter(i, -1, 10, 50)} & Bilateral filter with $\sigma_\text{r} = 10$, $\sigma_\text{s}=50$, auto size\\
\end{tabular}
\subsubsection{Borders}
All filtering operations have parameter \mintinline{python}{borderType} which can be set to:
\begin{tabular}{@{}ll@{}}
\mintinline{python}{BORDER_CONSTANT} & Pads with constant border (requires additional parameter \mintinline{python}{value})\\
\mintinline{python}{BORDER_REPLICATE} & Replicates the first/last row and column onto the padding\\
\mintinline{python}{BORDER_REFLECT} & Reflects the image borders onto the padding\\
\mintinline{python}{BORDER_REFLECT_101} & Same as previous, but doesn't include the pixel at the border (the default)\\
\mintinline{python}{BORDER_WRAP} & Wraps around the image borders to build the padding\\
\end{tabular}
Borders can also be added with custom widths:
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = copyMakeBorder(i, 2, 2, 3, 1, borderType=BORDER_WRAP)} & Widths: top, bottom, left, right\\\\
\end{tabular}
\subsection{Differential operators}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i_x = Sobel(i, CV_32F, 1, 0)} & Sobel in the x-direction: $I_x = \frac{\partial}{\partial x}I$\\
\mintinline{python}{i_y = Sobel(i, CV_32F, 0, 1)} & Sobel in the y-direction: $I_y = \frac{\partial}{\partial y}I$\\
\mintinline{python}{i_x, i_y = spatialGradient(i, 3)} & The gradient: $\nabla I$ (using $3\times 3$ Sobel): needs \mintinline{python}{uint8} image\\
\mintinline{python}{m = magnitude(i_x, i_y)} & $\lVert\nabla I\rVert$; $I_x, I_y$ must be float (for conversion, see \mintinline{python}{np.astype()})\\
\mintinline{python}{m, d = cartToPolar(i_x, i_y)} & $\lVert\nabla I\rVert$; $\theta \in [0, 2\pi]$; \mintinline{python}{angleInDegrees=False}; needs \mintinline{python}{float32} $I_x, I_y$\\
\mintinline{python}{l = Laplacian(i, CV_32F, ksize=5)} & $\Delta I$, Laplacian with kernel size of 5\\
\end{tabular}
\subsection{Geometric transforms}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{i = resize(i, (width, height))} & Resizes image to \texttt{width}$\times$\texttt{height}\\
\mintinline{python}{i = resize(i, None, fx=0.2, fy=0.1)} & Scales image to 20\% width and 10\% height\\
\mintinline{python}{M = getRotationMatrix2D((xc, yc), deg,} & Returns $2\times 3$ rotation matrix \texttt{M}, arbitrary $(x_c, y_c)$\\
\multicolumn{1}{r}{\mintinline{python}{scale)}} &\\
\mintinline{python}{M = getAffineTransform(pts1,pts2)} & Affine transform matrix \texttt{M} from 3 correspondences\\
\mintinline{python}{i = warpAffine(i, M, (cols,rows))} & Applies Affine transform \texttt{M} to $I$, output size=(\texttt{cols}, \texttt{rows}) \\
\mintinline{python}{M = getPerspectiveTransform(pts1,pts2)} & Perspective transform matrix \texttt{M} from 4 correspondences\\
\mintinline{python}{M, s = findHomography(pts1, pts2)} & Persp transf mx \texttt{M} from all $\gg 4$ corresps (Least squares)\\
\mintinline{python}{M, s = findHomography(pts1, pts2, RANSAC)} & Persp transf mx \texttt{M} from best $\gg 4$ corresps (RANSAC)\\
\mintinline{python}{i = warpPerspective(i, M, (cols, rows))} & Applies perspective transform \texttt{M} to image $I$\\
\end{tabular}
\subsubsection{Interpolation methods}
\mintinline{python}{resize}, \mintinline{python}{warpAffine} and \mintinline{python}{warpPerspective} use bilinear interpolation by default. It can be changed by parameter \mintinline{python}{interpolation} for \mintinline{python}{resize}, and \mintinline{python}{flags} for the others:
\begin{tabular}{@{}ll@{}}
\mintinline{python}{flags=INTER_NEAREST} & Simplest, fastest (or \mintinline{python}{interpolation=INTER_NEAREST})\\
\mintinline{python}{flags=INTER_LINEAR} & Bilinear interpolation: Default\\
\mintinline{python}{flags=INTER_CUBIC} & Bicubic interpolation\\
\end{tabular}
\subsection{Segmentation}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{_, i_t = threshold(i, t, 255, THRESH_BINARY)} & Manually thresholds image $I$ given threshold level $t$\\
\mintinline{python}{t, i_t = threshold(i, 0, 255, THRESH_OTSU)} & Returns thresh level and thresholded image using Otsu\\
\mintinline{python}{i_t = adaptiveThreshold(i, 255, } & \\
\multicolumn{1}{r}{\mintinline{python}{ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, b, c)}}& Adaptive mean-c with block size $b$ and constant $c$\\
\mintinline{python}{bp = calcBackProject([i_hsv], [0,1], h,} & Back-projects histogram $h$ onto the image \texttt{i\_hsv}\\
\multicolumn{1}{r}{\mintinline{python}{ [0,180, 0,256], 1)}}&\phantom{ } using only hue and saturation; no scaling (i.e.\ 1)\\
\mintinline{python}{cp, la, ct = kmeans(feats, K, None, crit, 10,} & Returns the labels \texttt{la} and centers \texttt{ct} of \texttt{K} clusters,\\
\multicolumn{1}{r}{\mintinline{python}{KMEANS_RANDOM_CENTERS)}}&\phantom{ } best compactness \texttt{cp} out of 10; 1 feat/column\\
\end{tabular}
\subsection{Features}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{e = Canny(i, tl, th)} & Returns the Canny edges (\texttt{e} is binary)\\
\mintinline{python}{l = HoughLines(e, 1, pi/180, 150)} & Returns all $(\rho, \theta) \geq 150$ votes, Bin res: $\rho = 1$ pix, $\theta = 1\deg$\\
\mintinline{python}{l = HoughLinesP(e, 1, pi/180, 150,}&\\
\multicolumn{1}{r}{\mintinline{python}{None, 100, 20)}} & Probabilistic Hough, min length=100, max gap=20\\
\mintinline{python}{c = HoughCircles(i, HOUGH_GRADIENT, 1,} & Returns all $(x_c, y_c, r)$ with at least 18 votes, bin resolution=1,\\
\multicolumn{1}{r}{\mintinline{python}{minDist=50, param1=200, param2=18,}} & \phantom{ } param1 is the $t_h$ of Canny, and the centers must be at least\\
\multicolumn{1}{r}{\mintinline{python}{minRadius=20, maxRadius=60)}} & \phantom{ } 50 pixels away from each other\\
\mintinline{python}{r = cornerHarris(i, 3, 5, 0.04)} & Harris corners' $R$s per pixel, window=3, Sobel=5, $\alpha=0.04$\\
\end{tabular}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{f = FastFeatureDetector_create()} & Instantiates the Star feature detector\\
\mintinline{python}{k = f.detect(i, None)} & Detects keypoints on grayscale image $I$\\
\mintinline{python}{i_k = drawKeypoints(i, k, None)} & Draws keypoints \texttt{k} on color image $I$\\
\mintinline{python}{d = xfeatures2d.BriefDescriptorExtractor_create()} & Instantiates a BRIEF descriptor\\
\mintinline{python}{k, ds = d.compute(i, k)} & Computes the descriptors of keypoints \texttt{k} over $I$\\
\mintinline{python}{dd = AKAZE_create()} & Instantiates the AKAZE detector/descriptor\\
\mintinline{python}{m = BFMatcher.create(NORM_HAMMING,} & Instantiates a brute-force matcher,\\
\multicolumn{1}{r}{\mintinline{python}{crossCheck=True)}} & \phantom{ }with x-checking, and Hamming distance\\
\mintinline{python}{ms = m.match(ds_l, ds_r)} & Matches the left and right descriptors\\
\mintinline{python}{i_m = drawMatches(i_l, k_l, i_r, k_r, ms, None)} & Draws matches from the left keypoints \texttt{k\_l} on\\
&\phantom{ } left image $I_l$ to right $I_r$, using matches \texttt{ms}\\
\end{tabular}
\subsection{Detection}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{ccs = matchTemplate(i, t, TM_CCORR_NORMED)} & Matches template $T$ to image $I$ (normalized X-correl)\\
\mintinline{python}{m, M, m_l, M_l = minMaxLoc(ccs)} & Min, max values and respective coordinates in \texttt{ccs}\\
\mintinline{python}{c = CascadeClassifier()} & Creates an instance of an ``empty'' cascade classifier\\
\mintinline{python}{r = c.load("file.xml")}& Loads a pre-trained model from file; \texttt{r} is \mintinline{python}{True/False}\\
\mintinline{python}{objs = c.detectMultiScale(i)} & Returns 1 tuple \texttt{(x, y, w, h)} per detected object\\
\end{tabular}
\subsection{Motion and Tracking}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{pts = goodFeaturesToTrack(i, 100, 0.5, 10)} & Returns 100 Shi-Tomasi corners with, at least, 0.5\\
&\phantom{ }quality, and 10 pixels away from each other\\
\mintinline{python}{pts1, st, e = calcOpticalFlowPyrLK(i0, i1,}& New positions of pts from estimated optical\\
\multicolumn{1}{r}{\mintinline{python}{pts0, None)}}&flow between $I_0$ and $I_1$; \texttt{st[i]} is 1 if flow\\
&\phantom{ }for point \texttt{i} was found, or 0 otherwise\\
\mintinline{python}{t = TrackerCSRT_create()} & Instantiates the CSRT tracker\\
\mintinline{python}{r = t.init(f, bbox)} & Initializes tracker with frame and bounding box\\
\mintinline{python}{r, bbox = t.update(f)} & Returns new bounding box, given next frame\\
\end{tabular}
\subsection{Drawing on the image}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{line(i,(x0, y0),(x1, y1), (b, g, r), t)}& Line\\
\mintinline{python}{rectangle(i, (x0, y0), (x1, y1), (b, g, r), t)}& Rectangle\\
\mintinline{python}{circle(i,(x0, y0), radius, (b, g, r), t)}& Circle\\
\mintinline{python}{polylines(i,[pts], True, (b, g, r), t)}& Closed (\mintinline{python}{True}) polygon (\mintinline{python}{pts} is array of points)\\
\mintinline{python}{putText(i, "Hi", (x,y), FONT_HERSHEY_SIMPLEX,}\\
\multicolumn{1}{r}{\mintinline{python}{1, (r,g,b), 2, LINE_AA)}}& Writes ``Hi'' at $(x, y)$, font size=1, thickness=2\\
\end{tabular}
\subsubsection{Parameters}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{(x0, y0)} & Origin/Start/Top left corner (note that it's not (row,column))\\
\mintinline{python}{(x1, y1)} & End/Bottom right corner\\
\mintinline{python}{(b, g, r)} & Line color (\mintinline{python}{uint8})\\
\mintinline{python}{t} & Line thickness (fills, if negative)
\end{tabular}
\subsection{Calibration and Stereo}
\begin{tabular}{@{}ll@{}}
%\mintinline{python}{s = cv2.StereoSGBM_create(minDisparity = 0, numDisparities = 32, blockSize = 11)} & initializes \\
%
\mintinline{python}{r, crns = findChessboardCorners(i, (n_x,n_y))} & 2D coords of detected corners; \mintinline{python}{i} is gray; \mintinline{python}{r} is\\
\multicolumn{1}{r}{} & \phantom{ }the status; \mintinline{python}{(n_x, n_y)} is size of calib target\\
\mintinline{python}{crnrs = cornerSubPix(i, crns, (5,5), (-1,-1), crit)} & Improves coordinates with sub-pixel accuracy\\
\mintinline{python}{r, K, D, ExRs, ExTs = calibrateCamera(crns_3D,}& Calculates intrinsics (inc. distortion coeffs), \&\\
\multicolumn{1}{r}{\mintinline{python}{crns_2D, i.shape[:2], None, None)}} &\phantom{ }extrinsics (i.e.\ \texttt{1 R+T} per target view); \mintinline{python}{crns_3D}\\
\multicolumn{1}{r}{} & \phantom{ }contains 1 array of 3D corner coords p/target\\
\multicolumn{1}{r}{} & \phantom{ }view; \mintinline{python}{crns_2D} contains the respective arrays of\\
\multicolumn{1}{r}{} & \phantom{ }2D corner coordinates (i.e.\ 1 \mintinline{python}{crns} p/target view)\\
\mintinline{python}{drawChessboardCorners(i, (n_x, n_y), crns, r)} & Draws corners on $I$ (may be color); \texttt{r} is status\\
\multicolumn{1}{r}{} & \phantom{ } from corner detection\\
\mintinline{python}{u = undistort(i, K, D)} & Undistorts $I$ using the intrinsics\\
\mintinline{python}{s = StereoSGBM_create(minDisparity = 0,}&\\
\multicolumn{1}{r}{\mintinline{python}{numDisparities = 32, blockSize = 11)}} & Instantiates Semi-Global Block Matching method\\
\mintinline{python}{s = StereoBM_create(32, 11)} & Instantiates a simpler block matching method\\
\mintinline{python}{d = s.compute(i_L, i_R)} & Computes disparity map ($\propto^{-1}$ depth map)\\
\end{tabular}
\subsection{Termination criteria (used in e.g.\ K-Means, Camera calibration)}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{crit = (TERM_CRITERIA_MAX_ITER, 20, 0)}& Stops after 20 iterations\\
\mintinline{python}{crit = (TERM_CRITERIA_EPS, 0, 1.0)}& Stop if ``movement'' is less than 1.0\\
\mintinline{python}{crit = (TERM_CRITERIA_MAX_ITER | TERM_CRITERIA_EPS, 20, 1.0)}& Stops whatever happens first\\
\end{tabular}
\subsection{Useful stuff}
\subsubsection{Numpy (\mintinline{python}{np.})}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{m = mean(i)} & Mean/average of array $I$\\
\mintinline{python}{m = average(i, weights)} & Weighted mean/average of array $I$\\
\mintinline{python}{v = var(i)} & Variance of array/image $I$\\
\mintinline{python}{s = std(i)} & Standard deviation of array/image $I$\\
\mintinline{python}{h,b = histogram(i.ravel(),256,[0,256])} & \texttt{numpy} histogram also returns the bins \texttt{b}\\
\mintinline{python}{i = clip(i, 0, 255)} & \texttt{numpy}'s saturation/clamping function\\
\mintinline{python}{i = i.astype(np.float32)} & Converts the image type to \mintinline{python}{float32} (vs.\ \mintinline{python}{uint8, float64})\\
\mintinline{python}{x, _, _, _ = linalg.lstsq(A, b)} & Solves the least squares problem $\frac{1}{2}\lVert Ax - b\rVert^2$\\
\mintinline{python}{i = hstack((i1, i2))} & Merges $I_1$ and $I_2$ side-by-side\\
\mintinline{python}{i = vstack((i1, i2))} & Merges $I_1$ above $I_2$ \\
\mintinline{python}{i = fliplr(i)} & Flips image left-right\\
\mintinline{python}{i = flipud(i)} & Flips image up-down\\
\mintinline{python}{i = pad(i, ((1, 1), (3, 3)), 'reflect')} & Alternative to \mintinline{python}{copyMakeBorder} (also top, bottom, left, right)\\
\mintinline{python}{idx = argmax(i)} & Linear index of maximum in $I$ (i.e.\ index of flattened $I$)\\
\mintinline{python}{r, c = unravel_index(idx, i.shape)} & 2D coordinate of the index with respect to shape of \texttt{i}\\
\texttt{b = any(M > 5)} & Returns \mintinline{python}{True} if any element in array $M$ is greater than 5\\
\texttt{b = all(M > 5)} & Returns \mintinline{python}{True} if all elements in array $M$ are greater than 5\\
\texttt{rows, cols = where(M > 5)} & Returns indices of the rows and cols where elems in $M$ are >5\\
\mintinline{python}{coords = list(zip(rows, cols))} & Creates a list with the elements of \texttt{rows} and \texttt{cols} paired\\
\mintinline{python}{M_inv = linalg.inv(M)} & Inverse of $M$\\
\mintinline{python}{rad = deg2rad(deg)} & Converts degrees into radians\\
\end{tabular}
\subsubsection{Matplotlib.pyplot (\mintinline{python}{plt.})}
\begin{tabular}{@{}ll@{}}
\mintinline{python}{imshow(i, cmap="gray", vmin=0, vmax=255)} & \mintinline{python}{matplotlib}'s \mintinline{python}{imshow} preventing auto-normalization\\
\mintinline{python}{quiver(xx, yy, i_x, -i_y, color="green")} & Plots the gradient direction at positions \mintinline{python}{xx, yy}\\
\mintinline{python}{savefig("name.png")} & Saves the plot as an image\\
\end{tabular}
\rule{0.3\linewidth}{0.25pt}
\scriptsize
Copyright \copyright\ 2019 António Anjos (Rev: \today)\\
Most up-to-date version: \url{https://github.com/a-anjos/python-opencv}
\end{multicols}
\end{document}