\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{thatguyandy27} \pdfinfo{ /Title (open-cv.pdf) /Creator (Cheatography) /Author (thatguyandy27) /Subject (Open CV Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{0000FF} \definecolor{LightBackground}{HTML}{EFEFFF} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Open CV Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{thatguyandy27} via \textcolor{DarkBackground}{\uline{cheatography.com/42823/cs/12846/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}thatguyandy27 \\ \uline{cheatography.com/thatguyandy27} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Not Yet Published.\\ Updated 17th September, 2017.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{3} \begin{tabularx}{5.377cm}{x{1.89126 cm} x{3.08574 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Accessing and Modifying pixel values}} \tn % Row 0 \SetRowColor{LightBackground} Pixel value & `img{[}100,100{]}` \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} Accessing only blue pixel & `img{[}100,100,0{]}` \tn % Row Count 3 (+ 2) % Row 2 \SetRowColor{LightBackground} Modifying A Pixel & `img{[}100,100{]} = {[}255,255,255{]}` \tn % Row Count 5 (+ 2) % Row 3 \SetRowColor{white} Better pixel accessing & `img.item(10,10,2)` \tn % Row Count 7 (+ 2) % Row 4 \SetRowColor{LightBackground} Better pixel modifying & `img.itemset((10,10,2),100)` \tn % Row Count 9 (+ 2) % Row 5 \SetRowColor{white} Access image properties & `img.shape` \tn % Row Count 11 (+ 2) % Row 6 \SetRowColor{LightBackground} Total number of pixels & `img.size` \tn % Row Count 13 (+ 2) % Row 7 \SetRowColor{white} Image datatype & `img.dtype` \tn % Row Count 14 (+ 1) % Row 8 \SetRowColor{LightBackground} Getting ROI & `ball = img{[}280:340, 330:390{]}` \tn % Row Count 16 (+ 2) % Row 9 \SetRowColor{white} Setting ROI & `img{[}273:333, 100:160{]} = ball` \tn % Row Count 18 (+ 2) % Row 10 \SetRowColor{LightBackground} Split Channels & `b,g,r = cv2.split(img)` \{\{nl\}\} `b = img{[}:,:,0{]}` \tn % Row Count 20 (+ 2) % Row 11 \SetRowColor{white} Making Borders for Images & \seqsplit{`cv2.copyMakeBorder(img1},10,10,10,10,cv2.BORDER\_REPLICATE)` \tn % Row Count 23 (+ 3) % Row 12 \SetRowColor{LightBackground} borderType & `cv2.BORDER\_CONSTANT `\{\{nl\}\} `cv2.BORDER\_REFLECT`\{\{nl\}\} `cv2.BORDER\_REFLECT\_101`\{\{nl\}\} `cv2.BORDER\_REPLICATE`\{\{nl\}\} `cv2.BORDER\_WRAP` \tn % Row Count 29 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.84149 cm} x{3.13551 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Arithmetic Operations on Images}} \tn % Row 0 \SetRowColor{LightBackground} Image Addition (OPENCV) & `print cv2.add(x,y) \# 250+10 = 260 =\textgreater{} 255` \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Image Addition (Numpy) & `print x+y \# 250+10 = 260 \% 256 = 4` \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} Image Alpha Blending & `dst = cv2.addWeighted(img1,0.7,img2,0.3,0)` \tn % Row Count 6 (+ 2) % Row 3 \SetRowColor{white} Bitwise AND & `img1\_bg = cv2.bitwise\_and(roi,roi,mask = mask\_inv)` \tn % Row Count 9 (+ 3) % Row 4 \SetRowColor{LightBackground} Bitwise NOT & `mask\_inv = cv2.bitwise\_not(mask)` \tn % Row Count 11 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.9908 cm} x{2.9862 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Morphological Transformations}} \tn % Row 0 \SetRowColor{LightBackground} Erosion & `erosion = cv2.erode(img,kernel,iterations = 1)` \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Dilation & `dilation = cv2.dilate(img,kernel,iterations = 1)` \tn % Row Count 5 (+ 3) % Row 2 \SetRowColor{LightBackground} Opening & `opening = cv2.morphologyEx(img, cv2.MORPH\_OPEN, kernel)` \tn % Row Count 8 (+ 3) % Row 3 \SetRowColor{white} Closing & `closing = cv2.morphologyEx(img, cv2.MORPH\_CLOSE, kernel)` \tn % Row Count 11 (+ 3) % Row 4 \SetRowColor{LightBackground} Morphological Gradient & gradient = cv2.morphologyEx(img, cv2.MORPH\_GRADIENT, kernel) \tn % Row Count 14 (+ 3) % Row 5 \SetRowColor{white} Top Hat & tophat = cv2.morphologyEx(img, cv2.MORPH\_TOPHAT, kernel) \tn % Row Count 17 (+ 3) % Row 6 \SetRowColor{LightBackground} Black Hat & blackhat = cv2.morphologyEx(img, cv2.MORPH\_BLACKHAT, kernel) \tn % Row Count 20 (+ 3) % Row 7 \SetRowColor{white} Create Structuring Elements & \seqsplit{`cv2.getStructuringElement(cv2.MORPH\_RECT},(5,5))` \{\{nl\}\} \seqsplit{`cv2.getStructuringElement(cv2.MORPH\_ELLIPSE},(5,5))` \{\{nl\}\} \seqsplit{`cv2.getStructuringElement(cv2.MORPH\_CROSS},(5,5))` \tn % Row Count 27 (+ 7) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.33919 cm} x{2.63781 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Performance Measurement and Improvement Techniques}} \tn % Row 0 \SetRowColor{LightBackground} Find \# of clock-cycles & `e1 = cv2.getTickCount()` \{\{nl\}\} `\# your code execution` \{\{nl\}\} `e2 = cv2.getTickCount()` \{\{nl\}\} `time = (e2 - e1)/ \seqsplit{cv2.getTickFrequency()`} \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} Find clock cycles per second & \seqsplit{`cv2.getTickFrequency`} \tn % Row Count 9 (+ 2) % Row 2 \SetRowColor{LightBackground} Enable Optimizations & \seqsplit{`cv2.setUseOptimized(True)`} \tn % Row Count 11 (+ 2) % Row 3 \SetRowColor{white} Measure Performance (IPython) & `\%timeit y=x**2` \tn % Row Count 13 (+ 2) % Row 4 \SetRowColor{LightBackground} Performance Optimization Techniques & 1. Avoid using loops in Python as far as possible, especially double/triple loops etc. They are inherently slow. \{\{nl\}\} 2. Vectorize the algorithm/code to the maximum possible extent because Numpy and OpenCV are optimized for vector operations. \{\{nl\}\} 3. Exploit the cache coherence. \{\{nl\}\} 4. Never make copies of array unless it is needed. Try to use views instead. Array copying is a costly operation. \tn % Row Count 33 (+ 20) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.94103 cm} x{3.03597 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Geometric Transformations of Images}} \tn % Row 0 \SetRowColor{LightBackground} Scaling Types & `cv2.INTER\_AREA` \{\{nl\}\} `cv2.INTER\_CUBIC` \{\{nl\}\} `cv2.INTER\_LINEAR` \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} Scaling & `res = cv2.resize(img,(2{\emph{width, 2}}height), interpolation = cv2.INTER\_CUBIC)` \tn % Row Count 7 (+ 4) % Row 2 \SetRowColor{LightBackground} Shifting (100 x 50) & `M = np.float32({[}{[}1,0,100{]},{[}0,1,50{]}{]})` \{\{nl\}\} `dst = cv2.warpAffine(img,M,(cols,rows))` \tn % Row Count 11 (+ 4) % Row 3 \SetRowColor{white} Rotation & `M = \seqsplit{cv2.getRotationMatrix2D((cols/2},rows/2),90,1)` \{\{nl\}\} `dst = cv2.warpAffine(img,M,(cols,rows))` \tn % Row Count 16 (+ 5) % Row 4 \SetRowColor{LightBackground} Affine Transformation & `pts1 = np.float32({[}{[}50,50{]},{[}200,50{]},{[}50,200{]}{]})` \{\{nl\}\} `pts2 = np.float32({[}{[}10,100{]},{[}200,50{]},{[}100,250{]}{]})` \{\{nl\}\} `M = \seqsplit{cv2.getAffineTransform(pts1},pts2)` \{\{nl\}\} `dst = cv2.warpAffine(img,M,(cols,rows))` \tn % Row Count 25 (+ 9) % Row 5 \SetRowColor{white} Perspective Transformation & `pts1 = np.float32({[}{[}56,65{]},{[}368,52{]},{[}28,387{]},{[}389,390{]}{]})` \{\{nl\}\} `pts2 = np.float32({[}{[}0,0{]},{[}300,0{]},{[}0,300{]},{[}300,300{]}{]})` \{\{nl\}\} `M = \seqsplit{cv2.getPerspectiveTransform(pts1},pts2)` \{\{nl\}\} `dst = cv2.warpPerspective(img,M,(300,300))` \tn % Row Count 35 (+ 10) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.59264 cm} x{3.38436 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Canny Edge Detection}} \tn % Row 0 \SetRowColor{LightBackground} Canny Detection & `edges = cv2.Canny(img,100,200)` \tn % Row Count 2 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.84149 cm} x{3.13551 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Image Pyramids}} \tn % Row 0 \SetRowColor{LightBackground} Lower Gaussian Pyramid & `lower\_reso = \seqsplit{cv2.pyrDown(higher\_reso)`} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Higher Gaussian Pyramid & `higher\_reso2 = cv2.pyrUp(lower\_reso)` \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} Pyramid Blending & 1. Load the two images \{\{nl\}\} 2. Find the Gaussian Pyramids \{\{nl\}\} 3. From Gaussian Pyramids, find their Laplacian Pyramids \{\{nl\}\} 4. Now each levels of Laplacian Pyramids \{\{nl\}\} 5. Finally from this joint image pyramids, reconstruct the original image \tn % Row Count 15 (+ 11) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.04057 cm} x{2.93643 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Changing Colorspaces}} \tn % Row 0 \SetRowColor{LightBackground} List Colorspace Flags (150+) & `flags = {[}i for i in dir(cv2) if \seqsplit{i.startswith('COLOR\_')`} \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} Convert to Gray & `img\_gray = cv2.cvtColor(img, cv2. COLOR\_BGR2GRAY)` \tn % Row Count 6 (+ 3) % Row 2 \SetRowColor{LightBackground} Convert to hsv & `hsv = cv2.cvtColor(img, cv2. COLOR\_BGR2HSV)` \tn % Row Count 8 (+ 2) % Row 3 \SetRowColor{white} Track Blue (color) Object & `lower\_blue = np.array({[}110,50,50{]})` \{\{nl\}\} `upper\_blue = np.array({[}130,255,255{]})` \{\{nl\}\} `mask = cv2.inRange(hsv, lower\_blue, upper\_blue)` \{\{nl\}\} `res = cv2.bitwise\_and(frame,frame, mask= mask)` \tn % Row Count 17 (+ 9) % Row 4 \SetRowColor{LightBackground} Find HSV Color & `green = np.uint8({[}{[}{[}0,255,0 {]}{]}{]})` \{\{nl\}\} `hsv\_green = cv2.cvtColor(green,cv2.COLOR\_BGR2HSV)` \tn % Row Count 22 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.69218 cm} x{3.28482 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Image Thresholding}} \tn % Row 0 \SetRowColor{LightBackground} Thresholding Types & `cv2.THRESH\_BINARY` \{\{nl\}\} \seqsplit{`cv2.THRESH\_BINARY\_INV`} \{\{nl\}\} `cv2.THRESH\_TRUNC` \{\{nl\}\} `cv2.THRESH\_TOZERO` \{\{nl\}\} \seqsplit{`cv2.THRESH\_TOZERO\_INV`} \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} Getting Threshold & `ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH\_TOZERO)` \tn % Row Count 9 (+ 3) % Row 2 \SetRowColor{LightBackground} Adaptive Method Types & \seqsplit{`cv2.ADAPTIVE\_THRESH\_MEAN\_C`} \{\{nl\}\} \seqsplit{`cv2.ADAPTIVE\_THRESH\_GAUSSIAN\_C`} \tn % Row Count 12 (+ 3) % Row 3 \SetRowColor{white} Adaptive Threshold & `th3 = \seqsplit{cv2.adaptiveThreshold(img},255,cv2.ADAPTIVE\_THRESH\_GAUSSIAN\_C, cv2.THRESH\_BINARY,11,2)` \tn % Row Count 16 (+ 4) % Row 4 \SetRowColor{LightBackground} Otsu's Binarization & `ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH\_BINARY+cv2.THRESH\_OTSU)` \tn % Row Count 19 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.89126 cm} x{3.08574 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Smoothing Images}} \tn % Row 0 \SetRowColor{LightBackground} Convolve an Image & `dst = cv2.filter2D(img,-1,kernel)` \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Box (averaging) Filtering & `blur = cv2.blur(img,(5,5))` \{\{nl\}\} `cv2.boxFilter()` \tn % Row Count 5 (+ 3) % Row 2 \SetRowColor{LightBackground} Create Gaussian Kernel & \seqsplit{`cv2.getGaussianKernel(size}, sigma, type)` \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} Gaussian Blur & `blur = cv2.GaussianBlur(img,(5,5),0)` \tn % Row Count 9 (+ 2) % Row 4 \SetRowColor{LightBackground} Median Blur & `median = cv2.medianBlur(img,5)` \tn % Row Count 11 (+ 2) % Row 5 \SetRowColor{white} Bilateral Blur & `blur = cv2.bilateralFilter(img,9,75,75)` \tn % Row Count 13 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{0.89586 cm} x{4.08114 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Image Gradients}} \tn % Row 0 \SetRowColor{LightBackground} Sobel & `sobelx = cv2.Sobel(img,cv2.CV\_64F,1,0,ksize=5)` \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \seqsplit{Laplacian} & `laplacian = cv2.Laplacian(img,cv2.CV\_64F)` \tn % Row Count 4 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{*Output datatype cv2.CV\_8U or np.uint8. So when you convert data to np.uint8, all negative slopes are made zero. In simple words, you miss that edge. If you want to detect both edges, better option is to keep the output datatype to some higher forms, like cv2.CV\_16S, cv2.CV\_64F etc, take its absolute value and then convert back to cv2.CV\_8U} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}