├── .gitignore ├── Haarcascades ├── haarcascade_car.xml ├── haarcascade_eye.xml ├── haarcascade_frontalface_default.xml └── haarcascade_fullbody.xml ├── Lecture 2.4 - Reading, writing and displaying images.ipynb ├── Lecture 2.5 - Grayscaling.ipynb ├── Lecture 2.6 - Color Spaces.ipynb ├── Lecture 2.7 - Histograms.ipynb ├── Lecture 2.8 - Drawing Images.ipynb ├── Lecture 3.10 - Sharpening.ipynb ├── Lecture 3.11 - Thresholding, Binarization & Adaptive Thresholding.ipynb ├── Lecture 3.12 - Dilation, Erosion, Opening and Closing.ipynb ├── Lecture 3.13 - Edge Detection & Image Gradients.ipynb ├── Lecture 3.14 - Perspective & Affine Transforms.ipynb ├── Lecture 3.15 - Mini Project # 1 - Live Sketch Using Webcam.ipynb ├── Lecture 3.2 - Translations.ipynb ├── Lecture 3.3 - Rotations.ipynb ├── Lecture 3.4 - Scaling, re-sizing and interpolations.ipynb ├── Lecture 3.5 - Image Pyramids.ipynb ├── Lecture 3.6 - Cropping.ipynb ├── Lecture 3.7 - Arithmetic Operations.ipynb ├── Lecture 3.8 - Bitwise Operations and Masking.ipynb ├── Lecture 3.9 - Convolutions and Blurring.ipynb ├── Lecture 4.1 - Understanding Contours.ipynb ├── Lecture 4.2 - Sorting Contours.ipynb ├── Lecture 4.3 - Approximating Contours and Convex Hull .ipynb ├── Lecture 4.4 - Matching Contours Shape.ipynb ├── Lecture 4.5 - Mini Project # 2 - Identifying Contours by Shape.ipynb ├── Lecture 4.6 - Line Detection using Hough Lines.ipynb ├── Lecture 4.7 - Circle Detection using Hough Cirlces.ipynb ├── Lecture 4.8 - Blob Detection.ipynb ├── Lecture 4.9 - Mini Project # 3 - Counting Circles and Ellipses .ipynb ├── Lecture 5.2 - Mini Project # 4 - Finding Waldo.ipynb ├── Lecture 5.4 - Finding Corners.ipynb ├── Lecture 5.5 - SIFT, SURF, FAST, BRIEF & ORB.ipynb ├── Lecture 5.6 - Mini Project # 5 - Object Detection using SIFT & ORB.ipynb ├── Lecture 5.7 Histogram of Oriented Gradients.ipynb ├── Lecture 6.2 - Face & Eye Detection.ipynb ├── Lecture 6.3 - Mini Project # 6 - Car & Pedestrian Detection.ipynb ├── Lecture 7.1 - Facial Landmarks.ipynb ├── Lecture 7.2 - Merging Faces.ipynb ├── Lecture 7.3 - Mini Project # 7 - Live Face Swaps.ipynb ├── Lecture 7.4 - Mini Project # 8 – Yawn Detector and Counting.ipynb ├── Lecture 8.2 - Mini Project # 9 - Handwritten Digit Recognition.ipynb ├── Lecture 8.3 - Mini Project # 10 Face Recognition – Unlock Your Computer With Your Face!.ipynb ├── Lecture 9.1 - Filtering by Color.ipynb ├── Lecture 9.2 - Background Subtraction.ipynb ├── Lecture 9.3 - Meanshift Object Tracking.ipynb ├── Lecture 9.4 - Camshift Object Tracking.ipynb ├── README.md └── images ├── 4star.jpg ├── Bitmap.bmp ├── GeneralMethod.jpg ├── Hillary.jpg ├── IMG_7539.jpg ├── IMG_8295.JPG ├── Origin_of_Species.jpg ├── Sunflowers.jpg ├── Trump.jpg ├── WaldoBeach.jpg ├── abraham.jpg ├── abraham_mask.png ├── beatle.jpg ├── blobs.jpg ├── bottlecaps.jpg ├── box_in_scene.png ├── bunchofshapes.jpg ├── candy.jpg ├── cars.avi ├── chess.JPG ├── chihuahua.jpg ├── coffee.jpg ├── contours.jpg ├── digits.png ├── domino.png ├── download.png ├── eigenface_reconstruction_opencv.png ├── elephant.jpg ├── ex2.jpg ├── faceswap.JPG ├── gradient.jpg ├── hand.jpg ├── house.jpg ├── input.jpg ├── input33.JPG ├── iphone4.jpg ├── kim.jpg ├── lourve_noise.jpg ├── marsface.jpg ├── mask.jpg ├── numbers.jpg ├── obama.jpg ├── obamafacerecog.jpg ├── opencv.png ├── opencv_inv.png ├── output.jpg ├── photorestore.JPG ├── rot.jpg ├── scan.jpg ├── shapes.jpg ├── shapes_donut.jpg ├── shapestomatch.jpg ├── soduku.jpg ├── someshapes.jpg ├── tobago.jpg ├── truck.jpg ├── waldo.jpg └── walking.avi /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /Lecture 2.4 - Reading, writing and displaying images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Hi and welcome to your first code along lesson!\n", 8 | "\n", 9 | "#### Reading, writing and displaying images with OpenCV" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "Let's start by importing the OpenCV libary " 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "outputs": [], 26 | "source": [ 27 | "# Press CTRL + ENTER to run this line\n", 28 | "# You should see an * between the [ ] on the left\n", 29 | "# OpenCV takes a couple seconds to import the first time\n", 30 | "\n", 31 | "import cv2" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": { 38 | "collapsed": true 39 | }, 40 | "outputs": [], 41 | "source": [] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "metadata": { 47 | "collapsed": true 48 | }, 49 | "outputs": [], 50 | "source": [ 51 | "# Now let's import numpy\n", 52 | "# We use as np, so that everything we call on numpy, we can type np instead\n", 53 | "# It's short and looks neater\n", 54 | "\n", 55 | "import numpy as np " 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "Let's now load our first image" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "# We don't need to do this again, but it's a good habit\n", 74 | "import cv2 \n", 75 | "\n", 76 | "# Load an image using 'imread' specifying the path to image\n", 77 | "input = cv2.imread('./images/input.jpg')\n", 78 | "\n", 79 | "# Our file 'input.jpg' is now loaded and stored in python \n", 80 | "# as a varaible we named 'image'\n", 81 | "\n", 82 | "# To display our image variable, we use 'imshow'\n", 83 | "# The first parameter will be title shown on image window\n", 84 | "# The second parameter is the image varialbe\n", 85 | "cv2.imshow('Hello World', input)\n", 86 | "\n", 87 | "# 'waitKey' allows us to input information when a image window is open\n", 88 | "# By leaving it blank it just waits for anykey to be pressed before \n", 89 | "# continuing. By placing numbers (except 0), we can specify a delay for\n", 90 | "# how long you keep the window open (time is in milliseconds here)\n", 91 | "cv2.waitKey()\n", 92 | "\n", 93 | "# This closes all open windows \n", 94 | "# Failure to place this will cause your program to hang\n", 95 | "cv2.destroyAllWindows()" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 5, 101 | "metadata": { 102 | "collapsed": true 103 | }, 104 | "outputs": [], 105 | "source": [ 106 | "# Same as above without the extraneous comments\n", 107 | "\n", 108 | "import cv2 \n", 109 | "\n", 110 | "input = cv2.imread('./images/input.jpg')\n", 111 | "\n", 112 | "cv2.imshow('Hello World', input)\n", 113 | "cv2.waitKey(0)\n", 114 | "cv2.destroyAllWindows()" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "### Let's take a closer look at how images are stored" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 6, 127 | "metadata": { 128 | "collapsed": true 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "# Import numpy\n", 133 | "import numpy as np" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 7, 139 | "metadata": { 140 | "collapsed": false 141 | }, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "(830L, 1245L, 3L)\n" 148 | ] 149 | } 150 | ], 151 | "source": [ 152 | "print input.shape" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "#### Shape gives the dimensions of the image array\n", 160 | "\n", 161 | "The 2D dimensions are 830 pixels in high bv 1245 pixels wide.\n", 162 | "The '3L' means that there are 3 other components (RGB) that make up this image." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 8, 168 | "metadata": { 169 | "collapsed": false 170 | }, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "Height of Image: 830 pixels\n", 177 | "Width of Image: 1245 pixels\n" 178 | ] 179 | } 180 | ], 181 | "source": [ 182 | "# Let's print each dimension of the image\n", 183 | "\n", 184 | "print 'Height of Image:', int(input.shape[0]), 'pixels'\n", 185 | "print 'Width of Image: ', int(input.shape[1]), 'pixels'" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "### How do we save images we edit in OpenCV?" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 10, 198 | "metadata": { 199 | "collapsed": false 200 | }, 201 | "outputs": [ 202 | { 203 | "data": { 204 | "text/plain": [ 205 | "True" 206 | ] 207 | }, 208 | "execution_count": 10, 209 | "metadata": {}, 210 | "output_type": "execute_result" 211 | } 212 | ], 213 | "source": [ 214 | "# Simply use 'imwrite' specificing the file name and the image to be saved\n", 215 | "cv2.imwrite('output.jpg', input)\n", 216 | "cv2.imwrite('output.png', input)" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "metadata": { 223 | "collapsed": true 224 | }, 225 | "outputs": [], 226 | "source": [] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": { 232 | "collapsed": true 233 | }, 234 | "outputs": [], 235 | "source": [] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": { 241 | "collapsed": true 242 | }, 243 | "outputs": [], 244 | "source": [] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "metadata": { 250 | "collapsed": true 251 | }, 252 | "outputs": [], 253 | "source": [] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": null, 258 | "metadata": { 259 | "collapsed": true 260 | }, 261 | "outputs": [], 262 | "source": [] 263 | } 264 | ], 265 | "metadata": { 266 | "anaconda-cloud": {}, 267 | "kernelspec": { 268 | "display_name": "Python [conda env:Python2.7]", 269 | "language": "python", 270 | "name": "conda-env-Python2.7-py" 271 | }, 272 | "language_info": { 273 | "codemirror_mode": { 274 | "name": "ipython", 275 | "version": 2 276 | }, 277 | "file_extension": ".py", 278 | "mimetype": "text/x-python", 279 | "name": "python", 280 | "nbconvert_exporter": "python", 281 | "pygments_lexer": "ipython2", 282 | "version": "2.7.12" 283 | } 284 | }, 285 | "nbformat": 4, 286 | "nbformat_minor": 0 287 | } 288 | -------------------------------------------------------------------------------- /Lecture 2.5 - Grayscaling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Grayscaling\n", 8 | "\n", 9 | "#### Grayscaling is process by which an image is converted from a full color to shades of grey (black & white)\n", 10 | "\n", 11 | "In OpenCV, many functions grayscale images before processing. This is done because it simplifies the image, acting almost as a noise reduction and increasing processing time as there is less information in the image.\n", 12 | "\n", 13 | "### Let convert our color image to greyscale" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": { 20 | "collapsed": false 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "import cv2\n", 25 | "\n", 26 | "# Load our input image\n", 27 | "image = cv2.imread('./images/input.jpg')\n", 28 | "cv2.imshow('Original', image)\n", 29 | "cv2.waitKey()\n", 30 | "\n", 31 | "# We use cvtColor, to convert to grayscale\n", 32 | "gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 33 | "\n", 34 | "cv2.imshow('Grayscale', gray_image)\n", 35 | "cv2.waitKey()\n", 36 | "cv2.destroyAllWindows()" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": { 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "#Another method faster method\n", 48 | "img = cv2.imread('./images/input.jpg',0)\n", 49 | "\n", 50 | "cv2.imshow('Grayscale', img)\n", 51 | "cv2.waitKey()\n", 52 | "cv2.destroyAllWindows()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 7, 58 | "metadata": { 59 | "collapsed": false 60 | }, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "(830L, 1245L, 3L)" 66 | ] 67 | }, 68 | "execution_count": 7, 69 | "metadata": {}, 70 | "output_type": "execute_result" 71 | } 72 | ], 73 | "source": [ 74 | "image.shape" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 9, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/plain": [ 87 | "(830L, 1245L)" 88 | ] 89 | }, 90 | "execution_count": 9, 91 | "metadata": {}, 92 | "output_type": "execute_result" 93 | } 94 | ], 95 | "source": [ 96 | "img.shape" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [] 103 | } 104 | ], 105 | "metadata": { 106 | "anaconda-cloud": {}, 107 | "kernelspec": { 108 | "display_name": "Python [conda env:Python2.7]", 109 | "language": "python", 110 | "name": "conda-env-Python2.7-py" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 2 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython2", 122 | "version": "2.7.12" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 0 127 | } 128 | -------------------------------------------------------------------------------- /Lecture 2.6 - Color Spaces.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Let's take a closer look at color spaces\n", 8 | "\n", 9 | "You may have remembered we talked about images being stored in RGB (Red Green Blue) color Spaces. Let's take a look at that in OpenCV.\n", 10 | "\n", 11 | "### First thing to remember about OpenCV's RGB is that it's BGR (I know, this is annoying)\n", 12 | "\n", 13 | "Let's look at the image shape again. The '3L' " 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": { 20 | "collapsed": false 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "import cv2\n", 25 | "import numpy as np\n", 26 | "\n", 27 | "image = cv2.imread('./images/input.jpg')" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "### Let's look at the individual color levels for the first pixel (0,0)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": { 41 | "collapsed": false 42 | }, 43 | "outputs": [ 44 | { 45 | "name": "stdout", 46 | "output_type": "stream", 47 | "text": [ 48 | "13 19 32\n", 49 | "(830L, 1245L, 3L)\n" 50 | ] 51 | } 52 | ], 53 | "source": [ 54 | "# BGR Values for the first 0,0 pixel\n", 55 | "B, G, R = image[10, 50] \n", 56 | "print B, G, R\n", 57 | "print image.shape" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "Let's see what happens when we convert it to grayscale" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 3, 70 | "metadata": { 71 | "collapsed": false 72 | }, 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "(830L, 1245L)\n", 79 | "22\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 85 | "print gray_img.shape\n", 86 | "print gray_img[10, 50] " 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "It's now only 2 dimensions. Each pixel coordinate has only one value (previously 3) with a range of 0 to 255" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 4, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [ 103 | { 104 | "data": { 105 | "text/plain": [ 106 | "21" 107 | ] 108 | }, 109 | "execution_count": 4, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "gray_img[0, 0] " 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "### Another useful color space is HSV \n", 123 | "Infact HSV is very useful in color filtering." 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 5, 129 | "metadata": { 130 | "collapsed": true 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "#Hue/Farbton: 0 - 180, Saturation: 0 - 255, Value: 0 - 255\n", 135 | "\n", 136 | "image = cv2.imread('./images/input.jpg')\n", 137 | "\n", 138 | "hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n", 139 | "\n", 140 | "cv2.imshow('HSV image', hsv_image)\n", 141 | "# Die Doppelpunkte wählen das Gesamte Bild aus x-y Dimensionen des Graubildes. Der letzte Parameter wählt den Channel\n", 142 | "cv2.imshow('Hue channel', hsv_image[:, :, 0])\n", 143 | "cv2.imshow('Saturation channel', hsv_image[:, :, 1])\n", 144 | "cv2.imshow('Value channel', hsv_image[:, :, 2])# Value Channel ist im Prinzip ein Graubild\n", 145 | "\n", 146 | "cv2.waitKey()\n", 147 | "cv2.destroyAllWindows()" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "### Let's now explore lookng at individual channels in an RGB image" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 6, 160 | "metadata": { 161 | "collapsed": false 162 | }, 163 | "outputs": [ 164 | { 165 | "name": "stdout", 166 | "output_type": "stream", 167 | "text": [ 168 | "(830L, 1245L)\n" 169 | ] 170 | } 171 | ], 172 | "source": [ 173 | "image = cv2.imread('./images/input.jpg')\n", 174 | "\n", 175 | "# OpenCV's 'split' function splites the image into each color index\n", 176 | "B, G, R = cv2.split(image)\n", 177 | "\n", 178 | "print B.shape\n", 179 | "cv2.imshow(\"Red\", R)\n", 180 | "cv2.imshow(\"Green\", G)\n", 181 | "cv2.imshow(\"Blue\", B)\n", 182 | "cv2.waitKey(0)\n", 183 | "cv2.destroyAllWindows()\n", 184 | "\n", 185 | "# Let's re-make the original image, \n", 186 | "merged = cv2.merge([B, G,R]) \n", 187 | "cv2.imshow(\"Merged\", merged) \n", 188 | "\n", 189 | "# Let's amplify the blue color\n", 190 | "merged = cv2.merge([B+100, G, R])\n", 191 | "cv2.imshow(\"Merged with Blue Amplified\", merged) \n", 192 | "\n", 193 | "cv2.waitKey(0)\n", 194 | "cv2.destroyAllWindows()" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 7, 200 | "metadata": { 201 | "collapsed": false 202 | }, 203 | "outputs": [], 204 | "source": [ 205 | "import cv2\n", 206 | "import numpy as np\n", 207 | "\n", 208 | "B, G, R = cv2.split(image)\n", 209 | "\n", 210 | "# Let's create a matrix of zeros \n", 211 | "# with dimensions of the image h x w \n", 212 | "zeros = np.zeros(image.shape[:2], dtype = \"uint8\")\n", 213 | "\n", 214 | "cv2.imshow(\"Red\", cv2.merge([zeros, zeros, R]))\n", 215 | "cv2.imshow(\"Green\", cv2.merge([zeros, G, zeros]))\n", 216 | "cv2.imshow(\"Blue\", cv2.merge([B, zeros, zeros]))\n", 217 | "\n", 218 | "cv2.waitKey(0)\n", 219 | "cv2.destroyAllWindows()" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 19, 225 | "metadata": { 226 | "collapsed": false 227 | }, 228 | "outputs": [ 229 | { 230 | "data": { 231 | "text/plain": [ 232 | "(830L, 1245L)" 233 | ] 234 | }, 235 | "execution_count": 19, 236 | "metadata": {}, 237 | "output_type": "execute_result" 238 | } 239 | ], 240 | "source": [ 241 | "image.shape[:2]" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": {}, 247 | "source": [ 248 | "#### You can view a list of color converisons here, but keep in mind you won't ever use or need many of these\n", 249 | "\n", 250 | "http://docs.opencv.org/trunk/d7/d1b/group__imgproc__misc.html#ga4e0972be5de079fed4e3a10e24ef5ef0" 251 | ] 252 | } 253 | ], 254 | "metadata": { 255 | "kernelspec": { 256 | "display_name": "Python [conda env:Python2.7]", 257 | "language": "python", 258 | "name": "conda-env-Python2.7-py" 259 | }, 260 | "language_info": { 261 | "codemirror_mode": { 262 | "name": "ipython", 263 | "version": 2 264 | }, 265 | "file_extension": ".py", 266 | "mimetype": "text/x-python", 267 | "name": "python", 268 | "nbconvert_exporter": "python", 269 | "pygments_lexer": "ipython2", 270 | "version": "2.7.12" 271 | } 272 | }, 273 | "nbformat": 4, 274 | "nbformat_minor": 0 275 | } 276 | -------------------------------------------------------------------------------- /Lecture 2.8 - Drawing Images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Drawing images and shapes using OpenCV\n", 8 | "\n", 9 | "Let's start off my making a black square" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "# Create a black image\n", 24 | "# Bild hat eine Größe von 512*512 und 3 Schichten für die RGB Farben\n", 25 | "image = np.zeros((512,512,3), np.uint8)\n", 26 | "\n", 27 | "# Can we make this in black and white?\n", 28 | "image_bw = np.zeros((512,512), np.uint8)\n", 29 | "\n", 30 | "cv2.imshow(\"Black Rectangle (Color)\", image)\n", 31 | "cv2.imshow(\"Black Rectangle (B&W)\", image_bw)\n", 32 | "\n", 33 | "cv2.waitKey(0)\n", 34 | "cv2.destroyAllWindows()" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "### Let's draw a line over our black sqare\n", 42 | "\n", 43 | "cv2.line(image, starting cordinates, ending cordinates, color, thickness)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 5, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "# Draw a diagonal blue line of thickness of 5 pixels\n", 55 | "image = np.zeros((512,512,3), np.uint8)\n", 56 | "#cv2.line(image, (startposition), (endposition), (Farbe der Linie), Linienbreite)\n", 57 | "cv2.line(image, (0,0), (511,511), (255,127,0), 5)\n", 58 | "cv2.line(image, (511,0), (0,511), (255,127,0), 5)\n", 59 | "cv2.imshow(\"Blue Line\", image)\n", 60 | "\n", 61 | "cv2.waitKey(0)\n", 62 | "cv2.destroyAllWindows()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Let's now draw a rectangle\n", 70 | "\n", 71 | "cv2.rectangle(image, starting vertex, opposite vertex, color, thickness)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 7, 77 | "metadata": { 78 | "collapsed": false 79 | }, 80 | "outputs": [], 81 | "source": [ 82 | "# Draw a Rectangle in\n", 83 | "image = np.zeros((512,512,3), np.uint8)\n", 84 | "# eine negative Linienbreite füllt das viereck aus\n", 85 | "cv2.rectangle(image, (100,100), (300,250), (127,50,127), -1)\n", 86 | "cv2.imshow(\"Rectangle\", image)\n", 87 | "cv2.waitKey(0)\n", 88 | "cv2.destroyAllWindows()" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "### How about cirlcles?\n", 96 | "\n", 97 | "cv2.cirlce(image, center, radius, color, fill)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 8, 103 | "metadata": { 104 | "collapsed": false 105 | }, 106 | "outputs": [], 107 | "source": [ 108 | "image = np.zeros((512,512,3), np.uint8)\n", 109 | "#cv2.circle(image, (Zentrum), Radius, (15,75,50), -1) \n", 110 | "cv2.circle(image, (350, 350), 100, (15,75,50), 10) \n", 111 | "cv2.imshow(\"Circle\", image)\n", 112 | "cv2.waitKey(0)\n", 113 | "cv2.destroyAllWindows()" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "## And polygons?" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 17, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "(4L, 2L)\n", 135 | "(4L, 1L, 2L)\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "image = np.zeros((512,512,3), np.uint8)\n", 141 | "\n", 142 | "# Let's define four points\n", 143 | "pts = np.array( [[10,50], [400,50], [90,200], [50,500]], np.int32)\n", 144 | "\n", 145 | "print pts.shape\n", 146 | "# Let's now reshape our points in form required by polylines\n", 147 | "pts = pts.reshape((-1,1,2))\n", 148 | "print pts.shape\n", 149 | "\n", 150 | "cv2.polylines(image, [pts], True, (0,0,255), 3)\n", 151 | "cv2.imshow(\"Polygon\", image)\n", 152 | "cv2.waitKey(0)\n", 153 | "cv2.destroyAllWindows()" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "### Let's even add text with cv2.putText\n", 161 | "\n", 162 | "cv2.putText(image, 'Text to Display', bottom left starting point, Font, Font Size, Color, Thickness)\n", 163 | "\n", 164 | "- FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN\n", 165 | "- FONT_HERSHEY_DUPLEX,FONT_HERSHEY_COMPLEX \n", 166 | "- FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL\n", 167 | "- FONT_HERSHEY_SCRIPT_SIMPLEX\n", 168 | "- FONT_HERSHEY_SCRIPT_COMPLEX" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 18, 174 | "metadata": { 175 | "collapsed": false 176 | }, 177 | "outputs": [], 178 | "source": [ 179 | "image = np.zeros((512,512,3), np.uint8)\n", 180 | "\n", 181 | "cv2.putText(image, 'Hello World!', (75,290), cv2.FONT_HERSHEY_COMPLEX, 2, (100,170,0), 3)\n", 182 | "cv2.imshow(\"Hello World!\", image)\n", 183 | "cv2.waitKey(0)\n", 184 | "cv2.destroyAllWindows()" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": { 191 | "collapsed": true 192 | }, 193 | "outputs": [], 194 | "source": [] 195 | } 196 | ], 197 | "metadata": { 198 | "anaconda-cloud": {}, 199 | "kernelspec": { 200 | "display_name": "Python [conda env:Python2.7]", 201 | "language": "python", 202 | "name": "conda-env-Python2.7-py" 203 | }, 204 | "language_info": { 205 | "codemirror_mode": { 206 | "name": "ipython", 207 | "version": 2 208 | }, 209 | "file_extension": ".py", 210 | "mimetype": "text/x-python", 211 | "name": "python", 212 | "nbconvert_exporter": "python", 213 | "pygments_lexer": "ipython2", 214 | "version": "2.7.12" 215 | } 216 | }, 217 | "nbformat": 4, 218 | "nbformat_minor": 0 219 | } 220 | -------------------------------------------------------------------------------- /Lecture 3.10 - Sharpening.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Sharpening \n", 8 | "\n", 9 | "By altering our kernels we can implement sharpening, which has the effects of in strengthening or emphasizing edges in an image." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "collapsed": true 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "image = cv2.imread('images/input.jpg')\n", 24 | "cv2.imshow('Original', image)\n", 25 | "\n", 26 | "# Create our shapening kernel, we don't normalize since the \n", 27 | "# the values in the matrix sum to 1\n", 28 | "kernel_sharpening = np.array([[-1,-1,-1], \n", 29 | " [-1,9,-1], \n", 30 | " [-1,-1,-1]])\n", 31 | "\n", 32 | "# applying different kernels to the input image\n", 33 | "sharpened = cv2.filter2D(image, -1, kernel_sharpening)\n", 34 | "\n", 35 | "cv2.imshow('Image Sharpening', sharpened)\n", 36 | "\n", 37 | "cv2.waitKey(0)\n", 38 | "cv2.destroyAllWindows()" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 3, 44 | "metadata": { 45 | "collapsed": false 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "import cv2\n", 50 | "import numpy as np\n", 51 | "\n", 52 | "image = cv2.imread('images/Bitmap.bmp')\n", 53 | "cv2.imshow('Original', image)\n", 54 | "\n", 55 | "# Create our shapening kernel, we don't normalize since the \n", 56 | "# the values in the matrix sum to 1\n", 57 | "kernel_sharpening = np.array([[-1,-1,-1], \n", 58 | " [-1,9,-1], \n", 59 | " [-1,-1,-1]])\n", 60 | "\n", 61 | "# applying different kernels to the input image\n", 62 | "sharpened = cv2.filter2D(image, -1, kernel_sharpening)\n", 63 | "\n", 64 | "cv2.imshow('Image Sharpening', sharpened)\n", 65 | "\n", 66 | "cv2.waitKey(0)\n", 67 | "cv2.destroyAllWindows()" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 4, 73 | "metadata": { 74 | "collapsed": false 75 | }, 76 | "outputs": [ 77 | { 78 | "data": { 79 | "text/plain": [ 80 | "True" 81 | ] 82 | }, 83 | "execution_count": 4, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "cv2.imwrite('Seminar.bmp', sharpened)" 90 | ] 91 | } 92 | ], 93 | "metadata": { 94 | "anaconda-cloud": {}, 95 | "kernelspec": { 96 | "display_name": "Python 3", 97 | "language": "python", 98 | "name": "python3" 99 | }, 100 | "language_info": { 101 | "codemirror_mode": { 102 | "name": "ipython", 103 | "version": 3 104 | }, 105 | "file_extension": ".py", 106 | "mimetype": "text/x-python", 107 | "name": "python", 108 | "nbconvert_exporter": "python", 109 | "pygments_lexer": "ipython3", 110 | "version": "3.6.0" 111 | } 112 | }, 113 | "nbformat": 4, 114 | "nbformat_minor": 0 115 | } 116 | -------------------------------------------------------------------------------- /Lecture 3.11 - Thresholding, Binarization & Adaptive Thresholding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Thresholding, Binarization & Adaptive Thresholding\n", 8 | "\n", 9 | "\n", 10 | "In thresholding, we convert a grey scale image to it's binary form" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 3, 16 | "metadata": { 17 | "collapsed": false 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "import cv2\n", 22 | "import numpy as np\n", 23 | "\n", 24 | "# Load our image as greyscale \n", 25 | "image = cv2.imread('images/gradient.jpg',0)\n", 26 | "cv2.imshow('Original', image)\n", 27 | "\n", 28 | "# Values below 127 goes to 0 (black, everything above goes to 255 (white)\n", 29 | "ret,thresh1 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)\n", 30 | "cv2.imshow('1 Threshold Binary', thresh1)\n", 31 | "\n", 32 | "# Values below 127 go to 255 and values above 127 go to 0 (reverse of above)\n", 33 | "ret,thresh2 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)\n", 34 | "cv2.imshow('2 Threshold Binary Inverse', thresh2)\n", 35 | "\n", 36 | "# Values above 127 are truncated (held) at 127 (the 255 argument is unused)\n", 37 | "ret,thresh3 = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC)\n", 38 | "cv2.imshow('3 THRESH TRUNC', thresh3)\n", 39 | "\n", 40 | "# Values below 127 go to 0, above 127 are unchanged \n", 41 | "ret,thresh4 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO)\n", 42 | "cv2.imshow('4 THRESH TOZERO', thresh4)\n", 43 | "\n", 44 | "# Resever of above, below 127 is unchanged, above 127 goes to 0\n", 45 | "ret,thresh5 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO_INV)\n", 46 | "cv2.imshow('5 THRESH TOZERO INV', thresh5)\n", 47 | "cv2.waitKey(0) \n", 48 | " \n", 49 | "cv2.destroyAllWindows()" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### Is there a better way off thresholding?\n", 57 | "\n", 58 | "The biggest downfall of those simple threshold methods is that we need to provide the threshold value (i.e. the 127 value we used previously).\n", 59 | "#### What if there was a smarter way of doing this?\n", 60 | "\n", 61 | "There is with, Adaptive thresholding. \n", 62 | "\n" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "import cv2\n", 74 | "import numpy as np\n", 75 | "\n", 76 | "# Load our new image\n", 77 | "image = cv2.imread('images/Origin_of_Species.jpg', 0)\n", 78 | "\n", 79 | "cv2.imshow('Original', image)\n", 80 | "cv2.waitKey(0) \n", 81 | "\n", 82 | "# Values below 127 goes to 0 (black, everything above goes to 255 (white)\n", 83 | "ret,thresh1 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)\n", 84 | "cv2.imshow('Threshold Binary', thresh1)\n", 85 | "cv2.waitKey(0) \n", 86 | "\n", 87 | "# It's good practice to blur images as it removes noise\n", 88 | "image = cv2.GaussianBlur(image, (3, 3), 0)\n", 89 | "\n", 90 | "# Using adaptiveThreshold\n", 91 | "thresh = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \n", 92 | " cv2.THRESH_BINARY, 3, 5) \n", 93 | "cv2.imshow(\"Adaptive Mean Thresholding\", thresh) \n", 94 | "cv2.waitKey(0) \n", 95 | "\n", 96 | "_, th2 = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n", 97 | "cv2.imshow(\"Otsu's Thresholding\", thresh) \n", 98 | "cv2.waitKey(0) \n", 99 | "\n", 100 | "# Otsu's thresholding after Gaussian filtering\n", 101 | "blur = cv2.GaussianBlur(image, (5,5), 0)\n", 102 | "_, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n", 103 | "cv2.imshow(\"Guassian Otsu's Thresholding\", thresh) \n", 104 | "cv2.waitKey(0) \n", 105 | "\n", 106 | "cv2.destroyAllWindows()" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": { 113 | "collapsed": true 114 | }, 115 | "outputs": [], 116 | "source": [] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [] 126 | } 127 | ], 128 | "metadata": { 129 | "kernelspec": { 130 | "display_name": "Python 2", 131 | "language": "python", 132 | "name": "python2" 133 | }, 134 | "language_info": { 135 | "codemirror_mode": { 136 | "name": "ipython", 137 | "version": 2 138 | }, 139 | "file_extension": ".py", 140 | "mimetype": "text/x-python", 141 | "name": "python", 142 | "nbconvert_exporter": "python", 143 | "pygments_lexer": "ipython2", 144 | "version": "2.7.11" 145 | } 146 | }, 147 | "nbformat": 4, 148 | "nbformat_minor": 0 149 | } 150 | -------------------------------------------------------------------------------- /Lecture 3.12 - Dilation, Erosion, Opening and Closing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Dilation, Erosion, Opening and Closing " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "image = cv2.imread('images/opencv_inv.png', 0)\n", 22 | "\n", 23 | "cv2.imshow('Original', image)\n", 24 | "cv2.waitKey(0)\n", 25 | "\n", 26 | "# Let's define our kernel size\n", 27 | "kernel = np.ones((5,5), np.uint8)\n", 28 | "\n", 29 | "# Now we erode\n", 30 | "erosion = cv2.erode(image, kernel, iterations = 1)\n", 31 | "cv2.imshow('Erosion', erosion)\n", 32 | "cv2.waitKey(0)\n", 33 | "\n", 34 | "# \n", 35 | "dilation = cv2.dilate(image, kernel, iterations = 1)\n", 36 | "cv2.imshow('Dilation', dilation)\n", 37 | "cv2.waitKey(0)\n", 38 | "\n", 39 | "# Opening - Good for removing noise\n", 40 | "opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)\n", 41 | "cv2.imshow('Opening', opening)\n", 42 | "cv2.waitKey(0)\n", 43 | "\n", 44 | "# Closing - Good for removing noise\n", 45 | "closing = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)\n", 46 | "cv2.imshow('Closing', closing)\n", 47 | "cv2.waitKey(0)\n", 48 | "\n", 49 | "\n", 50 | "cv2.destroyAllWindows()" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "### There are some other less popular morphology operations, see the official OpenCV site:\n", 58 | "\n", 59 | "http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": { 75 | "collapsed": true 76 | }, 77 | "outputs": [], 78 | "source": [] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": { 84 | "collapsed": true 85 | }, 86 | "outputs": [], 87 | "source": [] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 2", 93 | "language": "python", 94 | "name": "python2" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 2 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython2", 106 | "version": "2.7.11" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 0 111 | } 112 | -------------------------------------------------------------------------------- /Lecture 3.13 - Edge Detection & Image Gradients.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Edge Detection & Image Gradients" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 8, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "image = cv2.imread('images/input.jpg',0)\n", 22 | "\n", 23 | "height, width = image.shape\n", 24 | "\n", 25 | "# Extract Sobel Edges\n", 26 | "sobel_x = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=5)\n", 27 | "sobel_y = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=5)\n", 28 | "\n", 29 | "cv2.imshow('Original', image)\n", 30 | "cv2.waitKey(0)\n", 31 | "cv2.imshow('Sobel X', sobel_x)\n", 32 | "cv2.waitKey(0)\n", 33 | "cv2.imshow('Sobel Y', sobel_y)\n", 34 | "cv2.waitKey(0)\n", 35 | "\n", 36 | "sobel_OR = cv2.bitwise_or(sobel_x, sobel_y)\n", 37 | "cv2.imshow('sobel_OR', sobel_OR)\n", 38 | "cv2.waitKey(0)\n", 39 | "\n", 40 | "laplacian = cv2.Laplacian(image, cv2.CV_64F)\n", 41 | "cv2.imshow('Laplacian', laplacian)\n", 42 | "cv2.waitKey(0)\n", 43 | "\n", 44 | "\n", 45 | "\n", 46 | "\n", 47 | "\n", 48 | "## Then, we need to provide two values: threshold1 and threshold2. Any gradient value larger than threshold2\n", 49 | "# is considered to be an edge. Any value below threshold1 is considered not to be an edge. \n", 50 | "#Values in between threshold1 and threshold2 are either classified as edges or non-edges based on how their \n", 51 | "#intensities are “connected”. In this case, any gradient values below 60 are considered non-edges\n", 52 | "#whereas any values above 120 are considered edges.\n", 53 | "\n", 54 | "\n", 55 | "# Canny Edge Detection uses gradient values as thresholds\n", 56 | "# The first threshold gradient\n", 57 | "canny = cv2.Canny(image, 50, 120)\n", 58 | "cv2.imshow('Canny', canny)\n", 59 | "cv2.waitKey(0)\n", 60 | "\n", 61 | "cv2.destroyAllWindows()" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": { 68 | "collapsed": true 69 | }, 70 | "outputs": [], 71 | "source": [] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": "Python 2", 77 | "language": "python", 78 | "name": "python2" 79 | }, 80 | "language_info": { 81 | "codemirror_mode": { 82 | "name": "ipython", 83 | "version": 2 84 | }, 85 | "file_extension": ".py", 86 | "mimetype": "text/x-python", 87 | "name": "python", 88 | "nbconvert_exporter": "python", 89 | "pygments_lexer": "ipython2", 90 | "version": "2.7.11" 91 | } 92 | }, 93 | "nbformat": 4, 94 | "nbformat_minor": 0 95 | } 96 | -------------------------------------------------------------------------------- /Lecture 3.14 - Perspective & Affine Transforms.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "## Getting Perpsective Transform" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 4, 14 | "metadata": { 15 | "collapsed": false 16 | }, 17 | "outputs": [], 18 | "source": [ 19 | "import cv2\n", 20 | "import numpy as np\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "\n", 23 | "image = cv2.imread('images/scan.jpg')\n", 24 | "\n", 25 | "cv2.imshow('Original', image)\n", 26 | "cv2.waitKey(0)\n", 27 | "\n", 28 | "# Cordinates of the 4 corners of the original image\n", 29 | "points_A = np.float32([[320,15], [700,215], [85,610], [530,780]])\n", 30 | "\n", 31 | "# Cordinates of the 4 corners of the desired output\n", 32 | "# We use a ratio of an A4 Paper 1 : 1.41\n", 33 | "points_B = np.float32([[0,0], [420,0], [0,594], [420,594]])\n", 34 | " \n", 35 | "# Use the two sets of four points to compute \n", 36 | "# the Perspective Transformation matrix, M \n", 37 | "M = cv2.getPerspectiveTransform(points_A, points_B)\n", 38 | " \n", 39 | "warped = cv2.warpPerspective(image, M, (420,594))\n", 40 | " \n", 41 | "cv2.imshow('warpPerspective', warped)\n", 42 | "cv2.waitKey(0)\n", 43 | "cv2.destroyAllWindows()" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "## In affine transforms you only need 3 coordiantes to obtain the correct transform" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 5, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [], 60 | "source": [ 61 | "import cv2\n", 62 | "import numpy as np\n", 63 | "import matplotlib.pyplot as plt\n", 64 | "\n", 65 | "image = cv2.imread('images/ex2.jpg')\n", 66 | "rows,cols,ch = image.shape\n", 67 | "\n", 68 | "cv2.imshow('Original', image)\n", 69 | "cv2.waitKey(0)\n", 70 | "\n", 71 | "# Cordinates of the 4 corners of the original image\n", 72 | "points_A = np.float32([[320,15], [700,215], [85,610]])\n", 73 | "\n", 74 | "# Cordinates of the 4 corners of the desired output\n", 75 | "# We use a ratio of an A4 Paper 1 : 1.41\n", 76 | "points_B = np.float32([[0,0], [420,0], [0,594]])\n", 77 | " \n", 78 | "# Use the two sets of four points to compute \n", 79 | "# the Perspective Transformation matrix, M \n", 80 | "M = cv2.getAffineTransform(points_A, points_B)\n", 81 | "\n", 82 | "warped = cv2.warpAffine(image, M, (cols, rows))\n", 83 | " \n", 84 | "cv2.imshow('warpPerspective', warped)\n", 85 | "cv2.waitKey(0)\n", 86 | "cv2.destroyAllWindows()" 87 | ] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 2", 93 | "language": "python", 94 | "name": "python2" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 2 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython2", 106 | "version": "2.7.11" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 0 111 | } 112 | -------------------------------------------------------------------------------- /Lecture 3.15 - Mini Project # 1 - Live Sketch Using Webcam.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 1 - Live Sketch Using Webcam" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 2, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Our sketch generating function\n", 22 | "def sketch(image):\n", 23 | " # Convert image to grayscale\n", 24 | " img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 25 | " \n", 26 | " # Clean up image using Guassian Blur\n", 27 | " img_gray_blur = cv2.GaussianBlur(img_gray, (5,5), 0)\n", 28 | " \n", 29 | " # Extract edges\n", 30 | " canny_edges = cv2.Canny(img_gray_blur, 10, 70)\n", 31 | " \n", 32 | " # Do an invert binarize the image \n", 33 | " ret, mask = cv2.threshold(canny_edges, 70, 255, cv2.THRESH_BINARY_INV)\n", 34 | " return mask\n", 35 | "\n", 36 | "\n", 37 | "# Initialize webcam, cap is the object provided by VideoCapture\n", 38 | "# It contains a boolean indicating if it was sucessful (ret)\n", 39 | "# It also contains the images collected from the webcam (frame)\n", 40 | "cap = cv2.VideoCapture(0)\n", 41 | "\n", 42 | "while True:\n", 43 | " ret, frame = cap.read()\n", 44 | " cv2.imshow('Our Live Sketcher', sketch(frame))\n", 45 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 46 | " break\n", 47 | " \n", 48 | "# Release camera and close windows\n", 49 | "cap.release()\n", 50 | "cv2.destroyAllWindows() " 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "collapsed": true 58 | }, 59 | "outputs": [], 60 | "source": [] 61 | } 62 | ], 63 | "metadata": { 64 | "anaconda-cloud": {}, 65 | "kernelspec": { 66 | "display_name": "Python [conda env:Python2.7]", 67 | "language": "python", 68 | "name": "conda-env-Python2.7-py" 69 | }, 70 | "language_info": { 71 | "codemirror_mode": { 72 | "name": "ipython", 73 | "version": 2 74 | }, 75 | "file_extension": ".py", 76 | "mimetype": "text/x-python", 77 | "name": "python", 78 | "nbconvert_exporter": "python", 79 | "pygments_lexer": "ipython2", 80 | "version": "2.7.12" 81 | } 82 | }, 83 | "nbformat": 4, 84 | "nbformat_minor": 0 85 | } 86 | -------------------------------------------------------------------------------- /Lecture 3.2 - Translations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Translations\n", 8 | "\n", 9 | "This an affine transform that simply shifts the position of an image.\n", 10 | "\n", 11 | "We use cv2.warpAffine to implement these transformations.\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 7, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "import cv2\n", 23 | "import numpy as np\n", 24 | "\n", 25 | "image = cv2.imread('images/input.jpg')\n", 26 | "\n", 27 | "# Store height and width of the image\n", 28 | "height, width = image.shape[:2]\n", 29 | "\n", 30 | "quarter_height, quarter_width = height/4, width/4\n", 31 | "\n", 32 | "# | 1 0 Tx |\n", 33 | "# T = | 0 1 Ty |\n", 34 | "# | Stauchung/Dehnung entlang der X-Achse, Drehen um die Kante (0,0) gegen den Uhrzeigersinn, Bewegen entlang der x-Achse |\n", 35 | "# T = | Stauchung/Dehnung entlang der y-Achse ,Drehen um die Kante (0,0) mit den Uhrzeigersinn, Bewegen entlang der y-Achse |\n", 36 | "\n", 37 | "# T is our translation matrix\n", 38 | "T = np.float32([[1, 0, -50], [0, 1,-50]])\n", 39 | "\n", 40 | "# We use warpAffine to transform the image using the matrix, T\n", 41 | "# cv2.warpAffine(Source, Transformation, (Destination)\n", 42 | "img_translation = cv2.warpAffine(image, T, (width/2, height/2))\n", 43 | "cv2.imshow('Translation', img_translation)\n", 44 | "cv2.waitKey()\n", 45 | "cv2.destroyAllWindows()" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": { 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 3, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "[[ 1. 0. 311.]\n", 69 | " [ 0. 1. 207.]]\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "# Let's take a look at T\n", 75 | "\n", 76 | "print T" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": { 83 | "collapsed": true 84 | }, 85 | "outputs": [], 86 | "source": [] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": { 92 | "collapsed": true 93 | }, 94 | "outputs": [], 95 | "source": [] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": { 110 | "collapsed": true 111 | }, 112 | "outputs": [], 113 | "source": [] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [] 123 | } 124 | ], 125 | "metadata": { 126 | "anaconda-cloud": {}, 127 | "kernelspec": { 128 | "display_name": "Python [conda env:Python2.7]", 129 | "language": "python", 130 | "name": "conda-env-Python2.7-py" 131 | }, 132 | "language_info": { 133 | "codemirror_mode": { 134 | "name": "ipython", 135 | "version": 2 136 | }, 137 | "file_extension": ".py", 138 | "mimetype": "text/x-python", 139 | "name": "python", 140 | "nbconvert_exporter": "python", 141 | "pygments_lexer": "ipython2", 142 | "version": "2.7.12" 143 | } 144 | }, 145 | "nbformat": 4, 146 | "nbformat_minor": 0 147 | } 148 | -------------------------------------------------------------------------------- /Lecture 3.3 - Rotations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Rotations\n", 8 | "\n", 9 | "cv2.getRotationMatrix2D(rotation_center_x, rotation_center_y, angle of rotation, scale)\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "image = cv2.imread('images/input.jpg')\n", 24 | "height, width = image.shape[:2]\n", 25 | "\n", 26 | "# Divide by two to rototate the image around its centre\n", 27 | "rotation_matrix = cv2.getRotationMatrix2D((width/2, height/2), 90, .5)\n", 28 | "\n", 29 | "rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height))\n", 30 | "\n", 31 | "cv2.imshow('Rotated Image', rotated_image)\n", 32 | "cv2.waitKey()\n", 33 | "cv2.destroyAllWindows()" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "### Notice all the black space surrounding the image.\n", 41 | "\n", 42 | "We could now crop the image as we can calculate it's new size (we haven't learned cropping yet!).\n", 43 | "\n", 44 | "But here's another method for simple rotations that uses the cv2.transpose function" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 12, 50 | "metadata": { 51 | "collapsed": false 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "#Other Option to Rotate\n", 56 | "img = cv2.imread('images/input.jpg')\n", 57 | "\n", 58 | "rotated_image = cv2.transpose(img)\n", 59 | "\n", 60 | "cv2.imshow('Rotated Image - Method 2', rotated_image)\n", 61 | "cv2.waitKey()\n", 62 | "cv2.destroyAllWindows()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 8, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "# Let's now see how to horizontaly flip.\n", 74 | "flipped = cv2.flip(image, 0)\n", 75 | "cv2.imshow('Horizontal Flip', flipped) \n", 76 | "cv2.waitKey()\n", 77 | "cv2.destroyAllWindows()" 78 | ] 79 | } 80 | ], 81 | "metadata": { 82 | "anaconda-cloud": {}, 83 | "kernelspec": { 84 | "display_name": "Python [conda env:Python2.7]", 85 | "language": "python", 86 | "name": "conda-env-Python2.7-py" 87 | }, 88 | "language_info": { 89 | "codemirror_mode": { 90 | "name": "ipython", 91 | "version": 2 92 | }, 93 | "file_extension": ".py", 94 | "mimetype": "text/x-python", 95 | "name": "python", 96 | "nbconvert_exporter": "python", 97 | "pygments_lexer": "ipython2", 98 | "version": "2.7.12" 99 | } 100 | }, 101 | "nbformat": 4, 102 | "nbformat_minor": 0 103 | } 104 | -------------------------------------------------------------------------------- /Lecture 3.4 - Scaling, re-sizing and interpolations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Scaling, re-sizing and interpolations\n", 8 | "\n", 9 | "Re-sizing is very easy using the cv2.resize function, it's arguments are:\n", 10 | "\n", 11 | "cv2.resize(image, dsize(output image size), x scale, y scale, interpolation)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "import cv2\n", 23 | "import numpy as np\n", 24 | "\n", 25 | "# load our input image\n", 26 | "image = cv2.imread('images/input.jpg')\n", 27 | "\n", 28 | "# Let's make our image 3/4 of it's original size\n", 29 | "image_scaled = cv2.resize(image, None, fx=0.75, fy=0.75)\n", 30 | "cv2.imshow('Scaling - Linear Interpolation', image_scaled) \n", 31 | "cv2.waitKey()\n", 32 | "\n", 33 | "# Let's double the size of our image\n", 34 | "img_scaled = cv2.resize(image, None, fx=2, fy=2, interpolation = cv2.INTER_CUBIC)\n", 35 | "cv2.imshow('Scaling - Cubic Interpolation', img_scaled)\n", 36 | "cv2.waitKey()\n", 37 | "\n", 38 | "# Let's skew the re-sizing by setting exact dimensions\n", 39 | "img_scaled = cv2.resize(image, (900, 400), interpolation = cv2.INTER_AREA)\n", 40 | "cv2.imshow('Scaling - Skewed Size', img_scaled) \n", 41 | "cv2.waitKey()\n", 42 | "\n", 43 | "cv2.destroyAllWindows()" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": { 50 | "collapsed": true 51 | }, 52 | "outputs": [], 53 | "source": [] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": { 59 | "collapsed": true 60 | }, 61 | "outputs": [], 62 | "source": [] 63 | } 64 | ], 65 | "metadata": { 66 | "anaconda-cloud": {}, 67 | "kernelspec": { 68 | "display_name": "Python [conda env:Python2.7]", 69 | "language": "python", 70 | "name": "conda-env-Python2.7-py" 71 | }, 72 | "language_info": { 73 | "codemirror_mode": { 74 | "name": "ipython", 75 | "version": 2 76 | }, 77 | "file_extension": ".py", 78 | "mimetype": "text/x-python", 79 | "name": "python", 80 | "nbconvert_exporter": "python", 81 | "pygments_lexer": "ipython2", 82 | "version": "2.7.12" 83 | } 84 | }, 85 | "nbformat": 4, 86 | "nbformat_minor": 0 87 | } 88 | -------------------------------------------------------------------------------- /Lecture 3.5 - Image Pyramids.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Image Pyramids\n", 8 | "\n", 9 | "Useful when scaling images in object detection." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 3, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "\n", 22 | "image = cv2.imread('images/input.jpg')\n", 23 | "\n", 24 | "smaller = cv2.pyrDown(image)\n", 25 | "larger = cv2.pyrUp(smaller)\n", 26 | "\n", 27 | "cv2.imshow('Original', image )\n", 28 | "\n", 29 | "cv2.imshow('Smaller ', smaller )\n", 30 | "cv2.imshow('Larger ', larger )\n", 31 | "cv2.waitKey(0)\n", 32 | "cv2.destroyAllWindows()" 33 | ] 34 | } 35 | ], 36 | "metadata": { 37 | "kernelspec": { 38 | "display_name": "Python 2", 39 | "language": "python", 40 | "name": "python2" 41 | }, 42 | "language_info": { 43 | "codemirror_mode": { 44 | "name": "ipython", 45 | "version": 2 46 | }, 47 | "file_extension": ".py", 48 | "mimetype": "text/x-python", 49 | "name": "python", 50 | "nbconvert_exporter": "python", 51 | "pygments_lexer": "ipython2", 52 | "version": "2.7.11" 53 | } 54 | }, 55 | "nbformat": 4, 56 | "nbformat_minor": 0 57 | } 58 | -------------------------------------------------------------------------------- /Lecture 3.6 - Cropping.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Cropping\n", 8 | "\n" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 2, 14 | "metadata": { 15 | "collapsed": false 16 | }, 17 | "outputs": [], 18 | "source": [ 19 | "import cv2\n", 20 | "import numpy as np\n", 21 | "\n", 22 | "image = cv2.imread('images/input.jpg')\n", 23 | "height, width = image.shape[:2]\n", 24 | "\n", 25 | "# Let's get the starting pixel coordiantes (top left of cropping rectangle)\n", 26 | "start_row, start_col = int(height * .25), int(width * .25)\n", 27 | "\n", 28 | "# Let's get the ending pixel coordinates (bottom right)\n", 29 | "end_row, end_col = int(height * .75), int(width * .75)\n", 30 | "\n", 31 | "# Simply use indexing to crop out the rectangle we desire\n", 32 | "cropped = image[start_row:end_row , start_col:end_col]\n", 33 | "\n", 34 | "cv2.imshow(\"Original Image\", image)\n", 35 | "cv2.waitKey(0) \n", 36 | "cv2.imshow(\"Cropped Image\", cropped) \n", 37 | "cv2.waitKey(0) \n", 38 | "cv2.destroyAllWindows()" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": { 45 | "collapsed": true 46 | }, 47 | "outputs": [], 48 | "source": [] 49 | } 50 | ], 51 | "metadata": { 52 | "kernelspec": { 53 | "display_name": "Python 2", 54 | "language": "python", 55 | "name": "python2" 56 | }, 57 | "language_info": { 58 | "codemirror_mode": { 59 | "name": "ipython", 60 | "version": 2 61 | }, 62 | "file_extension": ".py", 63 | "mimetype": "text/x-python", 64 | "name": "python", 65 | "nbconvert_exporter": "python", 66 | "pygments_lexer": "ipython2", 67 | "version": "2.7.11" 68 | } 69 | }, 70 | "nbformat": 4, 71 | "nbformat_minor": 0 72 | } 73 | -------------------------------------------------------------------------------- /Lecture 3.7 - Arithmetic Operations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Arithmetic Operations\n", 8 | "\n", 9 | "These are simple operations that allow us to directly add or subract to the color intensity.\n", 10 | "\n", 11 | "Calculates the per-element operation of two arrays. The overall effect is increasing or decreasing brightness." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 7, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "import cv2\n", 23 | "import numpy as np\n", 24 | "\n", 25 | "image = cv2.imread('images/input.jpg')\n", 26 | "\n", 27 | "# Create a matrix of ones, then multiply it by a scaler of 100 \n", 28 | "# This gives a matrix with same dimesions of our image with all values being 100\n", 29 | "M = np.ones(image.shape, dtype = \"uint8\") * 175 \n", 30 | "\n", 31 | "# We use this to add this matrix M, to our image\n", 32 | "# Notice the increase in brightness\n", 33 | "added = cv2.add(image, M)\n", 34 | "cv2.imshow(\"Added\", added)\n", 35 | "\n", 36 | "# Likewise we can also subtract\n", 37 | "# Notice the decrease in brightness\n", 38 | "subtracted = cv2.subtract(image, M)\n", 39 | "cv2.imshow(\"Subtracted\", subtracted)\n", 40 | "\n", 41 | "cv2.waitKey(0)\n", 42 | "cv2.destroyAllWindows()" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 5, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "array([[[75, 75, 75],\n", 56 | " [75, 75, 75],\n", 57 | " [75, 75, 75],\n", 58 | " ..., \n", 59 | " [75, 75, 75],\n", 60 | " [75, 75, 75],\n", 61 | " [75, 75, 75]],\n", 62 | "\n", 63 | " [[75, 75, 75],\n", 64 | " [75, 75, 75],\n", 65 | " [75, 75, 75],\n", 66 | " ..., \n", 67 | " [75, 75, 75],\n", 68 | " [75, 75, 75],\n", 69 | " [75, 75, 75]],\n", 70 | "\n", 71 | " [[75, 75, 75],\n", 72 | " [75, 75, 75],\n", 73 | " [75, 75, 75],\n", 74 | " ..., \n", 75 | " [75, 75, 75],\n", 76 | " [75, 75, 75],\n", 77 | " [75, 75, 75]],\n", 78 | "\n", 79 | " ..., \n", 80 | " [[75, 75, 75],\n", 81 | " [75, 75, 75],\n", 82 | " [75, 75, 75],\n", 83 | " ..., \n", 84 | " [75, 75, 75],\n", 85 | " [75, 75, 75],\n", 86 | " [75, 75, 75]],\n", 87 | "\n", 88 | " [[75, 75, 75],\n", 89 | " [75, 75, 75],\n", 90 | " [75, 75, 75],\n", 91 | " ..., \n", 92 | " [75, 75, 75],\n", 93 | " [75, 75, 75],\n", 94 | " [75, 75, 75]],\n", 95 | "\n", 96 | " [[75, 75, 75],\n", 97 | " [75, 75, 75],\n", 98 | " [75, 75, 75],\n", 99 | " ..., \n", 100 | " [75, 75, 75],\n", 101 | " [75, 75, 75],\n", 102 | " [75, 75, 75]]], dtype=uint8)" 103 | ] 104 | }, 105 | "execution_count": 5, 106 | "metadata": {}, 107 | "output_type": "execute_result" 108 | } 109 | ], 110 | "source": [ 111 | "M = np.ones(image.shape, dtype = \"uint8\") * 75 \n", 112 | "M" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [] 123 | } 124 | ], 125 | "metadata": { 126 | "kernelspec": { 127 | "display_name": "Python 2", 128 | "language": "python", 129 | "name": "python2" 130 | }, 131 | "language_info": { 132 | "codemirror_mode": { 133 | "name": "ipython", 134 | "version": 2 135 | }, 136 | "file_extension": ".py", 137 | "mimetype": "text/x-python", 138 | "name": "python", 139 | "nbconvert_exporter": "python", 140 | "pygments_lexer": "ipython2", 141 | "version": "2.7.11" 142 | } 143 | }, 144 | "nbformat": 4, 145 | "nbformat_minor": 0 146 | } 147 | -------------------------------------------------------------------------------- /Lecture 3.8 - Bitwise Operations and Masking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Bitwise Operations and Masking\n", 8 | "\n", 9 | "To demonstrate these operations let's create some simple images" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 5, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "# If you're wondering why only two dimensions, well this is a grayscale image, \n", 24 | "# if we doing a colored image, we'd use \n", 25 | "# rectangle = np.zeros((300, 300, 3),np.uint8)\n", 26 | "\n", 27 | "# Making a sqare\n", 28 | "square = np.zeros((300, 300), np.uint8)\n", 29 | "cv2.rectangle(square, (50, 50), (250, 250), 255, -2)\n", 30 | "cv2.imshow(\"Square\", square)\n", 31 | "cv2.waitKey(0)\n", 32 | "\n", 33 | "# Making a ellipse\n", 34 | "ellipse = np.zeros((300, 300), np.uint8)\n", 35 | "cv2.ellipse(ellipse, (150, 150), (150, 150), 30, 0, 180, 255, -1)\n", 36 | "cv2.imshow(\"Ellipse\", ellipse)\n", 37 | "cv2.waitKey(0)\n", 38 | "\n", 39 | "cv2.destroyAllWindows()" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "### Experimenting with some bitwise operations" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 6, 52 | "metadata": { 53 | "collapsed": true 54 | }, 55 | "outputs": [], 56 | "source": [ 57 | "# Shows only where they intersect\n", 58 | "And = cv2.bitwise_and(square, ellipse)\n", 59 | "cv2.imshow(\"AND\", And)\n", 60 | "cv2.waitKey(0)\n", 61 | "\n", 62 | "# Shows where either square or ellipse is \n", 63 | "bitwiseOr = cv2.bitwise_or(square, ellipse)\n", 64 | "cv2.imshow(\"OR\", bitwiseOr)\n", 65 | "cv2.waitKey(0) \n", 66 | "\n", 67 | "# Shows where either exist by itself\n", 68 | "bitwiseXor = cv2.bitwise_xor(square, ellipse)\n", 69 | "cv2.imshow(\"XOR\", bitwiseXor)\n", 70 | "cv2.waitKey(0)\n", 71 | "\n", 72 | "# Shows everything that isn't part of the square\n", 73 | "bitwiseNot_sq = cv2.bitwise_not(square)\n", 74 | "cv2.imshow(\"NOT - square\", bitwiseNot_sq)\n", 75 | "cv2.waitKey(0)\n", 76 | "\n", 77 | "### Notice the last operation inverts the image totally\n", 78 | "\n", 79 | "cv2.destroyAllWindows()" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": { 86 | "collapsed": true 87 | }, 88 | "outputs": [], 89 | "source": [ 90 | "\n", 91 | "\n", 92 | "\n", 93 | "\n", 94 | "\n" 95 | ] 96 | } 97 | ], 98 | "metadata": { 99 | "kernelspec": { 100 | "display_name": "Python 2", 101 | "language": "python", 102 | "name": "python2" 103 | }, 104 | "language_info": { 105 | "codemirror_mode": { 106 | "name": "ipython", 107 | "version": 2 108 | }, 109 | "file_extension": ".py", 110 | "mimetype": "text/x-python", 111 | "name": "python", 112 | "nbconvert_exporter": "python", 113 | "pygments_lexer": "ipython2", 114 | "version": "2.7.11" 115 | } 116 | }, 117 | "nbformat": 4, 118 | "nbformat_minor": 0 119 | } 120 | -------------------------------------------------------------------------------- /Lecture 3.9 - Convolutions and Blurring.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Convolutions and Blurring" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "image = cv2.imread('images/elephant.jpg')\n", 22 | "cv2.imshow('Original Image', image)\n", 23 | "cv2.waitKey(0)\n", 24 | "\n", 25 | "# Creating our 3 x 3 kernel\n", 26 | "kernel_3x3 = np.ones((3, 3), np.float32) / 9\n", 27 | "\n", 28 | "# We use the cv2.fitler2D to conovlve the kernal with an image \n", 29 | "blurred = cv2.filter2D(image, -1, kernel_3x3)\n", 30 | "cv2.imshow('3x3 Kernel Blurring', blurred)\n", 31 | "cv2.waitKey(0)\n", 32 | "\n", 33 | "# Creating our 7 x 7 kernel\n", 34 | "kernel_7x7 = np.ones((7, 7), np.float32) / 49\n", 35 | "\n", 36 | "blurred2 = cv2.filter2D(image, -1, kernel_7x7)\n", 37 | "cv2.imshow('7x7 Kernel Blurring', blurred2)\n", 38 | "cv2.waitKey(0)\n", 39 | "cv2.destroyAllWindows()" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": { 46 | "collapsed": true 47 | }, 48 | "outputs": [], 49 | "source": [] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "### Other commonly used blurring methods in OpenCV" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 5, 61 | "metadata": { 62 | "collapsed": false 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "import cv2\n", 67 | "import numpy as np\n", 68 | "\n", 69 | "image = cv2.imread('images/elephant.jpg')\n", 70 | "\n", 71 | "# Averaging done by convolving the image with a normalized box filter. \n", 72 | "# This takes the pixels under the box and replaces the central element\n", 73 | "# Box size needs to odd and positive \n", 74 | "blur = cv2.blur(image, (3,3))\n", 75 | "cv2.imshow('Averaging', blur)\n", 76 | "cv2.waitKey(0)\n", 77 | "\n", 78 | "# Instead of box filter, gaussian kernel\n", 79 | "Gaussian = cv2.GaussianBlur(image, (7,7), 0)\n", 80 | "cv2.imshow('Gaussian Blurring', Gaussian)\n", 81 | "cv2.waitKey(0)\n", 82 | "\n", 83 | "# Takes median of all the pixels under kernel area and central \n", 84 | "# element is replaced with this median value\n", 85 | "median = cv2.medianBlur(image, 5)\n", 86 | "cv2.imshow('Median Blurring', median)\n", 87 | "cv2.waitKey(0)\n", 88 | "\n", 89 | "# Bilateral is very effective in noise removal while keeping edges sharp\n", 90 | "bilateral = cv2.bilateralFilter(image, 9, 75, 75)\n", 91 | "cv2.imshow('Bilateral Blurring', bilateral)\n", 92 | "cv2.waitKey(0)\n", 93 | "cv2.destroyAllWindows()" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "## Image De-noising - Non-Local Means Denoising" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "collapsed": true 108 | }, 109 | "outputs": [], 110 | "source": [ 111 | "import numpy as np\n", 112 | "import cv2\n", 113 | "\n", 114 | "image = cv2.imread('images/elephant.jpg')\n", 115 | "\n", 116 | "# Parameters, after None are - the filter strength 'h' (5-10 is a good range)\n", 117 | "# Next is hForColorComponents, set as same value as h again\n", 118 | "# \n", 119 | "dst = cv2.fastNlMeansDenoisingColored(image, None, 6, 6, 7, 21)\n", 120 | "\n", 121 | "cv2.imshow('Fast Means Denoising', dst)\n", 122 | "cv2.waitKey(0)\n", 123 | "\n", 124 | "cv2.destroyAllWindows()" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "**There are 4 variations of Non-Local Means Denoising:**\n", 132 | "\n", 133 | "- cv2.fastNlMeansDenoising() - works with a single grayscale images\n", 134 | "- cv2.fastNlMeansDenoisingColored() - works with a color image.\n", 135 | "- cv2.fastNlMeansDenoisingMulti() - works with image sequence captured in short period of time (grayscale images)\n", 136 | "- cv2.fastNlMeansDenoisingColoredMulti() - same as above, but for color images." 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": { 143 | "collapsed": true 144 | }, 145 | "outputs": [], 146 | "source": [] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "metadata": { 152 | "collapsed": true 153 | }, 154 | "outputs": [], 155 | "source": [] 156 | } 157 | ], 158 | "metadata": { 159 | "anaconda-cloud": {}, 160 | "kernelspec": { 161 | "display_name": "Python [conda env:Python2.7]", 162 | "language": "python", 163 | "name": "conda-env-Python2.7-py" 164 | }, 165 | "language_info": { 166 | "codemirror_mode": { 167 | "name": "ipython", 168 | "version": 2 169 | }, 170 | "file_extension": ".py", 171 | "mimetype": "text/x-python", 172 | "name": "python", 173 | "nbconvert_exporter": "python", 174 | "pygments_lexer": "ipython2", 175 | "version": "2.7.12" 176 | } 177 | }, 178 | "nbformat": 4, 179 | "nbformat_minor": 0 180 | } 181 | -------------------------------------------------------------------------------- /Lecture 4.1 - Understanding Contours.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Contours" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 6, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "Number of Contours found = 3\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "import cv2\n", 27 | "import numpy as np\n", 28 | "\n", 29 | "# Let's load a simple image with 3 black squares\n", 30 | "image = cv2.imread('images/shapes.jpg')\n", 31 | "cv2.imshow('Input Image', image)\n", 32 | "cv2.waitKey(0)\n", 33 | "\n", 34 | "# Grayscale\n", 35 | "gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n", 36 | "\n", 37 | "# Find Canny edges\n", 38 | "edged = cv2.Canny(gray, 30, 200)\n", 39 | "cv2.imshow('Canny Edges', edged)\n", 40 | "cv2.waitKey(0)\n", 41 | "\n", 42 | "# Finding Contours\n", 43 | "# Use a copy of your image e.g. edged.copy(), since findContours alters the image\n", 44 | "contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", 45 | "cv2.imshow('Canny Edges After Contouring', edged)\n", 46 | "cv2.waitKey(0)\n", 47 | "\n", 48 | "print(\"Number of Contours found = \" + str(len(contours)))\n", 49 | "\n", 50 | "# Draw all contours\n", 51 | "# Use '-1' as the 3rd parameter to draw all\n", 52 | "cv2.drawContours(image, contours, -1, (0,255,0), 3)\n", 53 | "\n", 54 | "cv2.imshow('Contours', image)\n", 55 | "cv2.waitKey(0)\n", 56 | "cv2.destroyAllWindows()" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "**cv2.findContours(image, Retrieval Mode, Approximation Method)**\n", 64 | "\n", 65 | "Returns -> contours, hierarchy\n", 66 | "\n", 67 | "**NOTE** In OpenCV 3.X, findContours returns a 3rd argument which is ret (or a boolean indicating if the function was successfully run). \n", 68 | "\n", 69 | "If you're using OpenCV 3.X replace line 12 with:\n", 70 | "\n", 71 | "_, contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", 72 | "\n", 73 | "The variable 'contours' are stored as a numpy array of (x,y) points that form the contour\n", 74 | "\n", 75 | "While, 'hierarchy' describes the child-parent relationships between contours (i.e. contours within contours)\n", 76 | "\n", 77 | "\n", 78 | "\n", 79 | "#### Approximation Methods\n", 80 | "\n", 81 | "Using cv2.CHAIN_APPROX_NONE stores all the boundary points. But we don't necessarily need all bounding points. If the points form a straight line, we only need the start and ending points of that line.\n", 82 | "\n", 83 | "Using cv2.CHAIN_APPROX_SIMPLE instead only provides these start and end points of bounding contours, thus resulting in much more efficent storage of contour information.." 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [], 93 | "source": [] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": { 99 | "collapsed": true 100 | }, 101 | "outputs": [], 102 | "source": [] 103 | } 104 | ], 105 | "metadata": { 106 | "anaconda-cloud": {}, 107 | "kernelspec": { 108 | "display_name": "Python [conda env:Python2.7]", 109 | "language": "python", 110 | "name": "conda-env-Python2.7-py" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 2 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython2", 122 | "version": "2.7.12" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 0 127 | } 128 | -------------------------------------------------------------------------------- /Lecture 4.2 - Sorting Contours.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Sorting Contours\n", 8 | "\n", 9 | "We can sort contours in many ways." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import cv2\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "# Load our image\n", 24 | "image = cv2.imread('images/GeneralMethod.jpg')\n", 25 | "cv2.imshow('0 - Original Image', image)\n", 26 | "cv2.waitKey(0)\n", 27 | "\n", 28 | "# Create a black image with same dimensions as our loaded image\n", 29 | "blank_image = np.zeros((image.shape[0], image.shape[1], 3))\n", 30 | "\n", 31 | "# Create a copy of our original image\n", 32 | "orginal_image = image\n", 33 | "\n", 34 | "# Grayscale our image\n", 35 | "gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n", 36 | "\n", 37 | "# Find Canny edges\n", 38 | "edged = cv2.Canny(gray, 50, 200)\n", 39 | "cv2.imshow('1 - Canny Edges', edged)\n", 40 | "cv2.waitKey(0)\n", 41 | "\n", 42 | "# Find contours and print how many were found\n", 43 | "contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", 44 | "print (\"Number of contours found = \", len(contours))\n", 45 | "\n", 46 | "#Draw all contours\n", 47 | "cv2.drawContours(blank_image, contours, -1, (0,255,0), 3)\n", 48 | "cv2.imshow('2 - All Contours over blank image', blank_image)\n", 49 | "cv2.waitKey(0)\n", 50 | "\n", 51 | "# Draw all contours over blank image\n", 52 | "cv2.drawContours(image, contours, -1, (0,255,0), 3)\n", 53 | "cv2.imshow('3 - All Contours', image)\n", 54 | "cv2.waitKey(0)\n", 55 | "\n", 56 | "cv2.destroyAllWindows()" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "### Let's now sort by area" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 4, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "Contor Areas before sorting [20587.5, 22901.5, 66579.5, 90222.0]\n", 78 | "Contor Areas after sorting [90222.0, 66579.5, 22901.5, 20587.5]\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "import cv2\n", 84 | "import numpy as np\n", 85 | "\n", 86 | "# Function we'll use to display contour area\n", 87 | "\n", 88 | "def get_contour_areas(contours):\n", 89 | " # returns the areas of all contours as list\n", 90 | " all_areas = []\n", 91 | " for cnt in contours:\n", 92 | " area = cv2.contourArea(cnt)\n", 93 | " all_areas.append(area)\n", 94 | " return all_areas\n", 95 | "\n", 96 | "# Load our image\n", 97 | "image = cv2.imread('images/bunchofshapes.jpg')\n", 98 | "orginal_image = image\n", 99 | "\n", 100 | "# Let's print the areas of the contours before sorting\n", 101 | "print \"Contor Areas before sorting\", \n", 102 | "print get_contour_areas(contours)\n", 103 | "\n", 104 | "# Sort contours large to small\n", 105 | "sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)\n", 106 | "#sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)[:3]\n", 107 | "\n", 108 | "print \"Contor Areas after sorting\", \n", 109 | "print get_contour_areas(sorted_contours)\n", 110 | "\n", 111 | "# Iterate over our contours and draw one at a time\n", 112 | "for c in sorted_contours:\n", 113 | " cv2.drawContours(orginal_image, [c], -1, (255,0,0), 3)\n", 114 | " cv2.waitKey(0)\n", 115 | " cv2.imshow('Contours by area', orginal_image)\n", 116 | "\n", 117 | "cv2.waitKey(0)\n", 118 | "cv2.destroyAllWindows()" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 14, 124 | "metadata": { 125 | "collapsed": false 126 | }, 127 | "outputs": [ 128 | { 129 | "name": "stdout", 130 | "output_type": "stream", 131 | "text": [ 132 | "output_shape_number_1.jpg\n", 133 | "output_shape_number_2.jpg\n", 134 | "output_shape_number_3.jpg\n", 135 | "output_shape_number_4.jpg\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "import cv2\n", 141 | "import numpy as np\n", 142 | "\n", 143 | "# Functions we'll use for sorting by position\n", 144 | "\n", 145 | "def x_cord_contour(contours):\n", 146 | " #Returns the X cordinate for the contour centroid\n", 147 | " if cv2.contourArea(contours) > 10:\n", 148 | " M = cv2.moments(contours)\n", 149 | " return (int(M['m10']/M['m00']))\n", 150 | "\n", 151 | " \n", 152 | "def label_contour_center(image, c):\n", 153 | " # Places a red circle on the centers of contours\n", 154 | " M = cv2.moments(c)\n", 155 | " cx = int(M['m10'] / M['m00'])\n", 156 | " cy = int(M['m01'] / M['m00'])\n", 157 | " \n", 158 | " # Draw the countour number on the image\n", 159 | " cv2.circle(image,(cx,cy), 10, (0,0,255), -1)\n", 160 | " return image\n", 161 | "\n", 162 | "\n", 163 | "# Load our image\n", 164 | "image = cv2.imread('images/bunchofshapes.jpg')\n", 165 | "orginal_image = image.copy()\n", 166 | "\n", 167 | "\n", 168 | "# Computer Center of Mass or centroids and draw them on our image\n", 169 | "for (i, c) in enumerate(contours):\n", 170 | " orig = label_contour_center(image, c)\n", 171 | " \n", 172 | "cv2.imshow(\"4 - Contour Centers \", image)\n", 173 | "cv2.waitKey(0)\n", 174 | "\n", 175 | "# Sort by left to right using our x_cord_contour function\n", 176 | "contours_left_to_right = sorted(contours, key = x_cord_contour, reverse = False)\n", 177 | "\n", 178 | "\n", 179 | "# Labeling Contours left to right\n", 180 | "for (i,c) in enumerate(contours_left_to_right):\n", 181 | " cv2.drawContours(orginal_image, [c], -1, (0,0,255), 3) \n", 182 | " M = cv2.moments(c)\n", 183 | " cx = int(M['m10'] / M['m00'])\n", 184 | " cy = int(M['m01'] / M['m00'])\n", 185 | " cv2.putText(orginal_image, str(i+1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)\n", 186 | " cv2.imshow('6 - Left to Right Contour', orginal_image)\n", 187 | " cv2.waitKey(0)\n", 188 | " (x, y, w, h) = cv2.boundingRect(c) \n", 189 | " \n", 190 | " # Let's now crop each contour and save these images\n", 191 | " cropped_contour = orginal_image[y:y + h, x:x + w]\n", 192 | " image_name = \"output_shape_number_\" + str(i+1) + \".jpg\"\n", 193 | " print image_name\n", 194 | " cv2.imwrite(image_name, cropped_contour)\n", 195 | " \n", 196 | "cv2.destroyAllWindows()\n", 197 | "\n", 198 | "\n" 199 | ] 200 | } 201 | ], 202 | "metadata": { 203 | "anaconda-cloud": {}, 204 | "kernelspec": { 205 | "display_name": "Python [conda env:Python2.7]", 206 | "language": "python", 207 | "name": "conda-env-Python2.7-py" 208 | }, 209 | "language_info": { 210 | "codemirror_mode": { 211 | "name": "ipython", 212 | "version": 2 213 | }, 214 | "file_extension": ".py", 215 | "mimetype": "text/x-python", 216 | "name": "python", 217 | "nbconvert_exporter": "python", 218 | "pygments_lexer": "ipython2", 219 | "version": "2.7.12" 220 | } 221 | }, 222 | "nbformat": 4, 223 | "nbformat_minor": 0 224 | } 225 | -------------------------------------------------------------------------------- /Lecture 4.3 - Approximating Contours and Convex Hull .ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Approximating Contours and Convex Hull \n", 8 | "\n", 9 | "***cv2.approxPolyDP(contour, Approximation Accuracy, Closed)***\n", 10 | "- **contour** – is the individual contour we wish to approximate\n", 11 | "- **Approximation Accuracy** – Important parameter is determining the accuracy of the approximation. Small values give precise- approximations, large values give more generic approximation. A good rule of thumb is less than 5% of the contour perimeter\n", 12 | "- **Closed** – a Boolean value that states whether the approximate contour should be open or closed \n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 5, 18 | "metadata": { 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "import numpy as np\n", 24 | "import cv2\n", 25 | "\n", 26 | "# Load image and keep a copy\n", 27 | "image = cv2.imread('images/house.jpg')\n", 28 | "orig_image = image.copy()\n", 29 | "cv2.imshow('Original Image', orig_image)\n", 30 | "cv2.waitKey(0) \n", 31 | "\n", 32 | "# Grayscale and binarize\n", 33 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 34 | "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)\n", 35 | "\n", 36 | "# Find contours \n", 37 | "contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)\n", 38 | "\n", 39 | "# Iterate through each contour and compute the bounding rectangle\n", 40 | "for c in contours:\n", 41 | " x,y,w,h = cv2.boundingRect(c)\n", 42 | " cv2.rectangle(orig_image,(x,y),(x+w,y+h),(0,0,255),2) \n", 43 | " cv2.imshow('Bounding Rectangle', orig_image)\n", 44 | "\n", 45 | "cv2.waitKey(0) \n", 46 | " \n", 47 | "# Iterate through each contour and compute the approx contour\n", 48 | "for c in contours:\n", 49 | " # Calculate accuracy as a percent of the contour perimeter\n", 50 | " accuracy = 0.03 * cv2.arcLength(c, True)\n", 51 | " approx = cv2.approxPolyDP(c, accuracy, True)\n", 52 | " cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)\n", 53 | " cv2.imshow('Approx Poly DP', image)\n", 54 | " \n", 55 | "cv2.waitKey(0) \n", 56 | "cv2.destroyAllWindows()" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "## Convex Hull\n", 64 | "\n" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 8, 70 | "metadata": { 71 | "collapsed": true 72 | }, 73 | "outputs": [], 74 | "source": [ 75 | "import numpy as np\n", 76 | "import cv2\n", 77 | "\n", 78 | "image = cv2.imread('images/hand.jpg')\n", 79 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 80 | "\n", 81 | "cv2.imshow('Original Image', image)\n", 82 | "cv2.waitKey(0) \n", 83 | "\n", 84 | "# Threshold the image\n", 85 | "ret, thresh = cv2.threshold(gray, 176, 255, 0)\n", 86 | "\n", 87 | "# Find contours \n", 88 | "contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)\n", 89 | " \n", 90 | "# Sort Contors by area and then remove the largest frame contour\n", 91 | "n = len(contours) - 1\n", 92 | "contours = sorted(contours, key=cv2.contourArea, reverse=False)[:n]\n", 93 | "\n", 94 | "# Iterate through contours and draw the convex hull\n", 95 | "for c in contours:\n", 96 | " hull = cv2.convexHull(c)\n", 97 | " cv2.drawContours(image, [hull], 0, (0, 255, 0), 2)\n", 98 | " cv2.imshow('Convex Hull', image)\n", 99 | "\n", 100 | "cv2.waitKey(0) \n", 101 | "cv2.destroyAllWindows()" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "anaconda-cloud": {}, 116 | "kernelspec": { 117 | "display_name": "Python [conda env:Python2.7]", 118 | "language": "python", 119 | "name": "conda-env-Python2.7-py" 120 | }, 121 | "language_info": { 122 | "codemirror_mode": { 123 | "name": "ipython", 124 | "version": 2 125 | }, 126 | "file_extension": ".py", 127 | "mimetype": "text/x-python", 128 | "name": "python", 129 | "nbconvert_exporter": "python", 130 | "pygments_lexer": "ipython2", 131 | "version": "2.7.12" 132 | } 133 | }, 134 | "nbformat": 4, 135 | "nbformat_minor": 0 136 | } 137 | -------------------------------------------------------------------------------- /Lecture 4.4 - Matching Contours Shape.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Shape Matching" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "**cv2.matchShapes(contour template, contour, method, method parameter)**\n", 15 | "\n", 16 | "**Output** – match value (lower values means a closer match)\n", 17 | "\n", 18 | "- Contour Template – This is our reference contour that we’re trying to find in the new image\n", 19 | "- Contour – The individual contour we are checking against\n", 20 | "- Method – Type of contour matching (1, 2, 3)\n", 21 | "- Method Parameter – leave alone as 0.0 (not fully utilized in python OpenCV)\n" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 7, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "0.168183165072\n", 36 | "0.199469102562\n", 37 | "0.189497606273\n", 38 | "0.111010582763\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "import cv2\n", 44 | "import numpy as np\n", 45 | "\n", 46 | "# Load the shape template or reference image\n", 47 | "template = cv2.imread('images/4star.jpg',0)\n", 48 | "cv2.imshow('Template', template)\n", 49 | "cv2.waitKey()\n", 50 | "\n", 51 | "# Load the target image with the shapes we're trying to match\n", 52 | "target = cv2.imread('images/shapestomatch.jpg')\n", 53 | "target_gray = cv2.cvtColor(target,cv2.COLOR_BGR2GRAY)\n", 54 | "\n", 55 | "# Threshold both images first before using cv2.findContours\n", 56 | "ret, thresh1 = cv2.threshold(template, 127, 255, 0)\n", 57 | "ret, thresh2 = cv2.threshold(target_gray, 127, 255, 0)\n", 58 | "\n", 59 | "# Find contours in template\n", 60 | "contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)\n", 61 | "\n", 62 | "# We need to sort the contours by area so that we can remove the largest\n", 63 | "# contour which is the image outline\n", 64 | "sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)\n", 65 | "\n", 66 | "# We extract the second largest contour which will be our template contour\n", 67 | "template_contour = contours[1]\n", 68 | "\n", 69 | "# Extract contours from second target image\n", 70 | "contours, hierarchy = cv2.findContours(thresh2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)\n", 71 | "\n", 72 | "for c in contours:\n", 73 | " # Iterate through each contour in the target image and \n", 74 | " # use cv2.matchShapes to compare contour shapes\n", 75 | " match = cv2.matchShapes(template_contour, c, 1, 0.0)\n", 76 | " print match\n", 77 | " # If the match value is less than 0.15 we\n", 78 | " if match < 0.15:\n", 79 | " closest_contour = c\n", 80 | " else:\n", 81 | " closest_contour = [] \n", 82 | " \n", 83 | "cv2.drawContours(target, [closest_contour], -1, (0,255,0), 3)\n", 84 | "cv2.imshow('Output', target)\n", 85 | "cv2.waitKey()\n", 86 | "cv2.destroyAllWindows()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": { 92 | "collapsed": false 93 | }, 94 | "source": [ 95 | "http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": { 102 | "collapsed": true 103 | }, 104 | "outputs": [], 105 | "source": [] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python [conda env:Python2.7]", 111 | "language": "python", 112 | "name": "conda-env-Python2.7-py" 113 | }, 114 | "language_info": { 115 | "codemirror_mode": { 116 | "name": "ipython", 117 | "version": 2 118 | }, 119 | "file_extension": ".py", 120 | "mimetype": "text/x-python", 121 | "name": "python", 122 | "nbconvert_exporter": "python", 123 | "pygments_lexer": "ipython2", 124 | "version": "2.7.12" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 0 129 | } 130 | -------------------------------------------------------------------------------- /Lecture 4.5 - Mini Project # 2 - Identifying Contours by Shape.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project 2 - Identifiy Contours by Shape" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import cv2\n", 20 | "\n", 21 | "# Load and then gray scale image\n", 22 | "\n", 23 | "image = cv2.imread('images/someshapes.jpg')\n", 24 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 25 | "\n", 26 | "cv2.imshow('Identifying Shapes',image)\n", 27 | "cv2.waitKey(0)\n", 28 | "\n", 29 | "ret, thresh = cv2.threshold(gray, 127, 255, 1)\n", 30 | "\n", 31 | "# Extract Contours\n", 32 | "contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)\n", 33 | "\n", 34 | "for cnt in contours:\n", 35 | " \n", 36 | " # Get approximate polygons\n", 37 | " approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt,True),True)\n", 38 | " \n", 39 | " if len(approx) == 3:\n", 40 | " shape_name = \"Triangle\"\n", 41 | " cv2.drawContours(image,[cnt],0,(0,255,0),-1)\n", 42 | " \n", 43 | " # Find contour center to place text at the center\n", 44 | " M = cv2.moments(cnt)\n", 45 | " cx = int(M['m10'] / M['m00'])\n", 46 | " cy = int(M['m01'] / M['m00'])\n", 47 | " cv2.putText(image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)\n", 48 | " \n", 49 | " elif len(approx) == 4:\n", 50 | " x,y,w,h = cv2.boundingRect(cnt)\n", 51 | " M = cv2.moments(cnt)\n", 52 | " cx = int(M['m10'] / M['m00'])\n", 53 | " cy = int(M['m01'] / M['m00'])\n", 54 | " \n", 55 | " # Check to see if 4-side polygon is square or rectangle\n", 56 | " # cv2.boundingRect returns the top left and then width and \n", 57 | " if abs(w-h) <= 3:\n", 58 | " shape_name = \"Square\"\n", 59 | " \n", 60 | " # Find contour center to place text at the center\n", 61 | " cv2.drawContours(image, [cnt], 0, (0, 125 ,255), -1)\n", 62 | " cv2.putText(image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)\n", 63 | " else:\n", 64 | " shape_name = \"Rectangle\"\n", 65 | " \n", 66 | " # Find contour center to place text at the center\n", 67 | " cv2.drawContours(image, [cnt], 0, (0, 0, 255), -1)\n", 68 | " M = cv2.moments(cnt)\n", 69 | " cx = int(M['m10'] / M['m00'])\n", 70 | " cy = int(M['m01'] / M['m00'])\n", 71 | " cv2.putText(image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)\n", 72 | " \n", 73 | " elif len(approx) == 10:\n", 74 | " shape_name = \"Star\"\n", 75 | " cv2.drawContours(image, [cnt], 0, (255, 255, 0), -1)\n", 76 | " M = cv2.moments(cnt)\n", 77 | " cx = int(M['m10'] / M['m00'])\n", 78 | " cy = int(M['m01'] / M['m00'])\n", 79 | " cv2.putText(image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)\n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " elif len(approx) >= 15:\n", 84 | " shape_name = \"Circle\"\n", 85 | " cv2.drawContours(image, [cnt], 0, (0, 255, 255), -1)\n", 86 | " M = cv2.moments(cnt)\n", 87 | " cx = int(M['m10'] / M['m00'])\n", 88 | " cy = int(M['m01'] / M['m00'])\n", 89 | " cv2.putText(image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)\n", 90 | "\n", 91 | " cv2.imshow('Identifying Shapes',image)\n", 92 | " cv2.waitKey(0)\n", 93 | " \n", 94 | "cv2.destroyAllWindows()" 95 | ] 96 | } 97 | ], 98 | "metadata": { 99 | "kernelspec": { 100 | "display_name": "Python 2", 101 | "language": "python", 102 | "name": "python2" 103 | }, 104 | "language_info": { 105 | "codemirror_mode": { 106 | "name": "ipython", 107 | "version": 2 108 | }, 109 | "file_extension": ".py", 110 | "mimetype": "text/x-python", 111 | "name": "python", 112 | "nbconvert_exporter": "python", 113 | "pygments_lexer": "ipython2", 114 | "version": "2.7.11" 115 | } 116 | }, 117 | "nbformat": 4, 118 | "nbformat_minor": 0 119 | } 120 | -------------------------------------------------------------------------------- /Lecture 4.6 - Line Detection using Hough Lines.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | " ## Line Detection - Using Hough Lines\n", 8 | " \n", 9 | "**cv2.HoughLines**(binarized/thresholded image, 𝜌 accuracy, 𝜃 accuracy, threshold)\n", 10 | "- Threshold here is the minimum vote for it to be considered a line\n" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 12, 16 | "metadata": { 17 | "collapsed": false 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "import cv2\n", 22 | "import numpy as np\n", 23 | "\n", 24 | "image = cv2.imread('images/soduku.jpg')\n", 25 | "\n", 26 | "# Grayscale and Canny Edges extracted\n", 27 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 28 | "edges = cv2.Canny(gray, 100, 170, apertureSize = 3)\n", 29 | "#cv2.imshow(\"Canny\",edges)\n", 30 | "\n", 31 | "# Run HoughLines using a rho accuracy of 1 pixel\n", 32 | "# theta accuracy of np.pi / 180 which is 1 degree\n", 33 | "# Our line threshold is set to 240 (number of points on line)\n", 34 | "lines = cv2.HoughLines(edges, 1, np.pi / 180, 225)\n", 35 | "\n", 36 | "# We iterate through each line and convert it to the format\n", 37 | "# required by cv.lines (i.e. requiring end points)\n", 38 | "for rho, theta in lines[0]:\n", 39 | " a = np.cos(theta)\n", 40 | " b = np.sin(theta)\n", 41 | " x0 = a * rho\n", 42 | " y0 = b * rho\n", 43 | " x1 = int(x0 + 1000 * (-b))\n", 44 | " y1 = int(y0 + 1000 * (a))\n", 45 | " x2 = int(x0 - 1000 * (-b))\n", 46 | " y2 = int(y0 - 1000 * (a))\n", 47 | " cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)\n", 48 | "\n", 49 | "cv2.imshow('Hough Lines', image)\n", 50 | "cv2.waitKey(0)\n", 51 | "cv2.destroyAllWindows()" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "### Probabilistic Hough Lines\n", 59 | "\n", 60 | "**cv2.HoughLinesP(binarized image, 𝜌 accuracy, 𝜃 accuracy, threshold, minimum line length, max line gap)\n", 61 | "\n", 62 | "\n" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 19, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "(1L, 167L, 4L)\n" 77 | ] 78 | } 79 | ], 80 | "source": [ 81 | "import cv2\n", 82 | "import numpy as np\n", 83 | "\n", 84 | "# Grayscale and Canny Edges extracted\n", 85 | "image = cv2.imread('images/soduku.jpg')\n", 86 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 87 | "edges = cv2.Canny(gray, 100, 170, apertureSize = 3)\n", 88 | "\n", 89 | "# Again we use the same rho and theta accuracies\n", 90 | "# However, we specific a minimum vote (pts along line) of 100\n", 91 | "# and Min line length of 5 pixels and max gap between lines of 10 pixels\n", 92 | "lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 200, 5, 10)\n", 93 | "print lines.shape\n", 94 | "\n", 95 | "for x1, y1, x2, y2 in lines[0]:\n", 96 | " cv2.line(image, (x1, y1), (x2, y2),(0, 255, 0), 3)\n", 97 | "\n", 98 | "cv2.imshow('Probabilistic Hough Lines', image)\n", 99 | "cv2.waitKey(0)\n", 100 | "cv2.destroyAllWindows()" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "http://cmp.felk.cvut.cz/~matas/papers/matas-bmvc98.pdf" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "collapsed": true 115 | }, 116 | "outputs": [], 117 | "source": [] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": { 122 | "collapsed": false 123 | }, 124 | "source": [ 125 | "\n", 126 | "\n" 127 | ] 128 | } 129 | ], 130 | "metadata": { 131 | "anaconda-cloud": {}, 132 | "kernelspec": { 133 | "display_name": "Python [conda env:Python2.7]", 134 | "language": "python", 135 | "name": "conda-env-Python2.7-py" 136 | }, 137 | "language_info": { 138 | "codemirror_mode": { 139 | "name": "ipython", 140 | "version": 2 141 | }, 142 | "file_extension": ".py", 143 | "mimetype": "text/x-python", 144 | "name": "python", 145 | "nbconvert_exporter": "python", 146 | "pygments_lexer": "ipython2", 147 | "version": "2.7.12" 148 | } 149 | }, 150 | "nbformat": 4, 151 | "nbformat_minor": 0 152 | } 153 | -------------------------------------------------------------------------------- /Lecture 4.7 - Circle Detection using Hough Cirlces.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Circle Detection - Hough Cirlces\n", 8 | "\n", 9 | "**cv2.HoughCircles**(image, method, dp, MinDist, param1, param2, minRadius, MaxRadius)\n", 10 | "\n", 11 | "\n", 12 | "- Method - currently only cv2.HOUGH_GRADIENT available\n", 13 | "- dp - Inverse ratio of accumulator resolution\n", 14 | "- MinDist - the minimum distance between the center of detected circles\n", 15 | "- param1 - Gradient value used in the edge detection\n", 16 | "- param2 - Accumulator threshold for the HOUGH_GRADIENT method (lower allows more circles to be detected (false positives))\n", 17 | "- minRadius - limits the smallest circle to this size (via radius)\n", 18 | "- MaxRadius - similarly sets the limit for the largest circles\n", 19 | "\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 45, 25 | "metadata": { 26 | "collapsed": false 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "import cv2\n", 31 | "import numpy as np\n", 32 | "import cv2.cv as cv\n", 33 | "\n", 34 | "image = cv2.imread('images/bottlecaps.jpg')\n", 35 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 36 | "blur = cv2.medianBlur(gray, 5)\n", 37 | "\n", 38 | "\n", 39 | "circles = cv2.HoughCircles(blur, cv.CV_HOUGH_GRADIENT, 2, 50,minRadius=30,maxRadius=55)\n", 40 | "#circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 2, 50,minRadius=30,maxRadius=70)\n", 41 | "\n", 42 | "#circles = np.uint8(np.around(circles))\n", 43 | "\n", 44 | "for i in circles[0,:]:\n", 45 | " # draw the outer circle\n", 46 | " cv2.circle(image,(i[0], i[1]), i[2], (255, 0, 0), 2)\n", 47 | " \n", 48 | " # draw the center of the circle\n", 49 | " cv2.circle(image, (i[0], i[1]), 2, (0, 255, 0), 5)\n", 50 | "\n", 51 | "cv2.imshow('detected circles', image)\n", 52 | "cv2.waitKey(0)\n", 53 | "cv2.destroyAllWindows()" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 21, 59 | "metadata": { 60 | "collapsed": false 61 | }, 62 | "outputs": [], 63 | "source": [] 64 | } 65 | ], 66 | "metadata": { 67 | "anaconda-cloud": {}, 68 | "kernelspec": { 69 | "display_name": "Python [conda env:Python2.7]", 70 | "language": "python", 71 | "name": "conda-env-Python2.7-py" 72 | }, 73 | "language_info": { 74 | "codemirror_mode": { 75 | "name": "ipython", 76 | "version": 2 77 | }, 78 | "file_extension": ".py", 79 | "mimetype": "text/x-python", 80 | "name": "python", 81 | "nbconvert_exporter": "python", 82 | "pygments_lexer": "ipython2", 83 | "version": "2.7.12" 84 | } 85 | }, 86 | "nbformat": 4, 87 | "nbformat_minor": 0 88 | } 89 | -------------------------------------------------------------------------------- /Lecture 4.8 - Blob Detection.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Blob Detection" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 9, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "# Standard imports\n", 19 | "import cv2\n", 20 | "import numpy as np;\n", 21 | " \n", 22 | "# Read image\n", 23 | "image = cv2.imread(\"images/Sunflowers.jpg\")\n", 24 | " \n", 25 | "# Set up the detector with default parameters.\n", 26 | "detector = cv2.SimpleBlobDetector()\n", 27 | " \n", 28 | "# Detect blobs.\n", 29 | "keypoints = detector.detect(image)\n", 30 | " \n", 31 | "# Draw detected blobs as red circles.\n", 32 | "# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of\n", 33 | "# the circle corresponds to the size of blob\n", 34 | "blank = np.zeros((1,1)) \n", 35 | "blobs = cv2.drawKeypoints(image, keypoints, blank, (0,255,255),\n", 36 | " cv2.DRAW_MATCHES_FLAGS_DEFAULT)\n", 37 | " \n", 38 | "# Show keypoints\n", 39 | "cv2.imshow(\"Blobs\", blobs)\n", 40 | "cv2.waitKey(0)\n", 41 | "cv2.destroyAllWindows()" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "collapsed": true 48 | }, 49 | "source": [ 50 | "The function **cv2.drawKeypoints** takes the following arguments:\n", 51 | "\n", 52 | "**cv2.drawKeypoints**(input image, keypoints, blank_output_array, color, flags)\n", 53 | "\n", 54 | "flags:\n", 55 | "- cv2.DRAW_MATCHES_FLAGS_DEFAULT\n", 56 | "- cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS\n", 57 | "- cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG\n", 58 | "- cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [] 74 | } 75 | ], 76 | "metadata": { 77 | "kernelspec": { 78 | "display_name": "Python 2", 79 | "language": "python", 80 | "name": "python2" 81 | }, 82 | "language_info": { 83 | "codemirror_mode": { 84 | "name": "ipython", 85 | "version": 2 86 | }, 87 | "file_extension": ".py", 88 | "mimetype": "text/x-python", 89 | "name": "python", 90 | "nbconvert_exporter": "python", 91 | "pygments_lexer": "ipython2", 92 | "version": "2.7.11" 93 | } 94 | }, 95 | "nbformat": 4, 96 | "nbformat_minor": 0 97 | } 98 | -------------------------------------------------------------------------------- /Lecture 4.9 - Mini Project # 3 - Counting Circles and Ellipses .ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 3 - Counting Circles and Ellipses " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Load image\n", 22 | "image = cv2.imread(\"images/blobs.jpg\", 0)\n", 23 | "cv2.imshow('Original Image',image)\n", 24 | "cv2.waitKey(0)\n", 25 | "\n", 26 | "# Intialize the detector using the default parameters\n", 27 | "detector = cv2.SimpleBlobDetector()\n", 28 | " \n", 29 | "# Detect blobs\n", 30 | "keypoints = detector.detect(image)\n", 31 | " \n", 32 | "# Draw blobs on our image as red circles\n", 33 | "blank = np.zeros((1,1)) \n", 34 | "blobs = cv2.drawKeypoints(image, keypoints, blank, (0,0,255),\n", 35 | " cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 36 | "\n", 37 | "number_of_blobs = len(keypoints)\n", 38 | "text = \"Total Number of Blobs: \" + str(len(keypoints))\n", 39 | "cv2.putText(blobs, text, (20, 550), cv2.FONT_HERSHEY_SIMPLEX, 1, (100, 0, 255), 2)\n", 40 | "\n", 41 | "# Display image with blob keypoints\n", 42 | "cv2.imshow(\"Blobs using default parameters\", blobs)\n", 43 | "cv2.waitKey(0)\n", 44 | "\n", 45 | "\n", 46 | "# Set our filtering parameters\n", 47 | "# Initialize parameter settiing using cv2.SimpleBlobDetector\n", 48 | "params = cv2.SimpleBlobDetector_Params()\n", 49 | "\n", 50 | "# Set Area filtering parameters\n", 51 | "params.filterByArea = True\n", 52 | "params.minArea = 100\n", 53 | "\n", 54 | "# Set Circularity filtering parameters\n", 55 | "params.filterByCircularity = True \n", 56 | "params.minCircularity = 0.9\n", 57 | "\n", 58 | "# Set Convexity filtering parameters\n", 59 | "params.filterByConvexity = False\n", 60 | "params.minConvexity = 0.2\n", 61 | " \n", 62 | "# Set inertia filtering parameters\n", 63 | "params.filterByInertia = True\n", 64 | "params.minInertiaRatio = 0.01\n", 65 | "\n", 66 | "# Create a detector with the parameters\n", 67 | "detector = cv2.SimpleBlobDetector(params)\n", 68 | " \n", 69 | "# Detect blobs\n", 70 | "keypoints = detector.detect(image)\n", 71 | "\n", 72 | "# Draw blobs on our image as red circles\n", 73 | "blank = np.zeros((1,1)) \n", 74 | "blobs = cv2.drawKeypoints(image, keypoints, blank, (0,255,0),\n", 75 | " cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 76 | "\n", 77 | "number_of_blobs = len(keypoints)\n", 78 | "text = \"Number of Circular Blobs: \" + str(len(keypoints))\n", 79 | "cv2.putText(blobs, text, (20, 550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 100, 255), 2)\n", 80 | "\n", 81 | "# Show blobs\n", 82 | "cv2.imshow(\"Filtering Circular Blobs Only\", blobs)\n", 83 | "cv2.waitKey(0)\n", 84 | "cv2.destroyAllWindows()" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": { 91 | "collapsed": true 92 | }, 93 | "outputs": [], 94 | "source": [] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [], 103 | "source": [] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "**NOTE** OpenCV 3.XX, use this line of code for intializing our blob detector\n", 110 | "\n", 111 | "`detector = cv2.SimpleBlobDetector_create(params)`\n", 112 | "\n", 113 | "OpenCV 2.4.X users use this:\n", 114 | "\n", 115 | "`detector = cv2.SimpleBlobDetector()`" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": { 131 | "collapsed": true 132 | }, 133 | "outputs": [], 134 | "source": [] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "metadata": { 140 | "collapsed": true 141 | }, 142 | "outputs": [], 143 | "source": [] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": { 149 | "collapsed": true 150 | }, 151 | "outputs": [], 152 | "source": [] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 2", 158 | "language": "python", 159 | "name": "python2" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 2 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython2", 171 | "version": "2.7.11" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 0 176 | } 177 | -------------------------------------------------------------------------------- /Lecture 5.2 - Mini Project # 4 - Finding Waldo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 4 - Finding Waldo" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Load input image and convert to grayscale\n", 22 | "image = cv2.imread('images/WaldoBeach.jpg')\n", 23 | "cv2.imshow('Where is Waldo?', image)\n", 24 | "cv2.waitKey(0)\n", 25 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 26 | "\n", 27 | "# Load Template image\n", 28 | "template = cv2.imread('images/waldo.jpg',0)\n", 29 | "\n", 30 | "result = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF)\n", 31 | "min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)\n", 32 | "\n", 33 | "#Create Bounding Box\n", 34 | "top_left = max_loc\n", 35 | "bottom_right = (top_left[0] + 50, top_left[1] + 50)\n", 36 | "cv2.rectangle(image, top_left, bottom_right, (0,0,255), 5)\n", 37 | "\n", 38 | "cv2.imshow('Where is Waldo?', image)\n", 39 | "cv2.waitKey(0)\n", 40 | "cv2.destroyAllWindows()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### Notes on Template Matching\n", 48 | "\n", 49 | "There are a variety of methods to perform template matching, but in this case we are using the correlation coefficient which is specified by the flag **cv2.TM_CCOEFF.**\n", 50 | "\n", 51 | "So what exactly is the cv2.matchTemplate function doing?\n", 52 | "Essentially, this function takes a “sliding window” of our waldo query image and slides it across our puzzle image from left to right and top to bottom, one pixel at a time. Then, for each of these locations, we compute the correlation coefficient to determine how “good” or “bad” the match is. \n", 53 | "\n", 54 | "Regions with sufficiently high correlation can be considered “matches” for our waldo template.\n", 55 | "From there, all we need is a call to cv2.minMaxLoc on Line 22 to find where our “good” matches are.\n", 56 | "That’s really all there is to template matching!\n", 57 | "\n", 58 | "http://docs.opencv.org/2.4/modules/imgproc/doc/object_detection.html " 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": { 65 | "collapsed": true 66 | }, 67 | "outputs": [], 68 | "source": [] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": { 74 | "collapsed": true 75 | }, 76 | "outputs": [], 77 | "source": [] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": { 83 | "collapsed": true 84 | }, 85 | "outputs": [], 86 | "source": [] 87 | } 88 | ], 89 | "metadata": { 90 | "anaconda-cloud": {}, 91 | "kernelspec": { 92 | "display_name": "Python [conda env:Python2.7]", 93 | "language": "python", 94 | "name": "conda-env-Python2.7-py" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 2 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython2", 106 | "version": "2.7.12" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 0 111 | } 112 | -------------------------------------------------------------------------------- /Lecture 5.4 - Finding Corners.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Finding Corners" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 7, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Load image then grayscale\n", 22 | "image = cv2.imread('images/chess.jpg')\n", 23 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 24 | "\n", 25 | "# The cornerHarris function requires the array datatype to be float32\n", 26 | "gray = np.float32(gray)\n", 27 | "\n", 28 | "harris_corners = cv2.cornerHarris(gray, 3, 3, 0.05)\n", 29 | "\n", 30 | "#We use dilation of the corner points to enlarge them\\\n", 31 | "kernel = np.ones((7,7),np.uint8)\n", 32 | "harris_corners = cv2.dilate(harris_corners, kernel, iterations = 2)\n", 33 | "\n", 34 | "# Threshold for an optimal value, it may vary depending on the image.\n", 35 | "image[harris_corners > 0.025 * harris_corners.max() ] = [255, 127, 127]\n", 36 | "\n", 37 | "cv2.imshow('Harris Corners', image)\n", 38 | "cv2.waitKey(0)\n", 39 | "cv2.destroyAllWindows()" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "#### Harris Corner Detection is an algorithm developed in 1998 for corner detection (http://www.bmva.org/bmvc/1988/avc-88-023.pdf) and works fairly well.\n", 47 | "\n", 48 | "**cv2.cornerHarris**(input image, block size, ksize, k)\n", 49 | "- Input image - should be grayscale and float32 type.\n", 50 | "- blockSize - the size of neighborhood considered for corner detection\n", 51 | "- ksize - aperture parameter of Sobel derivative used.\n", 52 | "- k - harris detector free parameter in the equation\n", 53 | "- **Output** – array of corner locations (x,y)\n", 54 | "\n", 55 | "\n" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## Improved Corner Detection using - Good Features to Track" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 13, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "import cv2\n", 74 | "import numpy as np\n", 75 | "\n", 76 | "img = cv2.imread('images/chess.jpg')\n", 77 | "gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n", 78 | "\n", 79 | "# We specific the top 50 corners\n", 80 | "corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 150)\n", 81 | "\n", 82 | "for corner in corners:\n", 83 | " x, y = corner[0]\n", 84 | " x = int(x)\n", 85 | " y = int(y)\n", 86 | " cv2.rectangle(img,(x-10,y-10),(x+10,y+10),(0,255,0), 2)\n", 87 | " \n", 88 | "cv2.imshow(\"Corners Found\", img)\n", 89 | "cv2.waitKey()\n", 90 | "cv2.destroyAllWindows()" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "**cv2.goodFeaturesToTrack**(input image, maxCorners, qualityLevel, minDistance)\n", 98 | "\n", 99 | "- Input Image - 8-bit or floating-point 32-bit, single-channel image.\n", 100 | "- maxCorners – Maximum number of corners to return. If there are more corners than are found, the strongest of them is returned.\n", 101 | "- qualityLevel – Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure (smallest eigenvalue). The corners with the quality measure less than the product are rejected. For example, if the best corner has the quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality - - measure less than 15 are rejected.\n", 102 | "- minDistance – Minimum possible Euclidean distance between the returned corners.\n" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": { 109 | "collapsed": true 110 | }, 111 | "outputs": [], 112 | "source": [] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "metadata": { 118 | "collapsed": true 119 | }, 120 | "outputs": [], 121 | "source": [] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "metadata": { 127 | "collapsed": true 128 | }, 129 | "outputs": [], 130 | "source": [] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "metadata": { 136 | "collapsed": true 137 | }, 138 | "outputs": [], 139 | "source": [] 140 | } 141 | ], 142 | "metadata": { 143 | "kernelspec": { 144 | "display_name": "Python [conda env:Python2.7]", 145 | "language": "python", 146 | "name": "conda-env-Python2.7-py" 147 | }, 148 | "language_info": { 149 | "codemirror_mode": { 150 | "name": "ipython", 151 | "version": 2 152 | }, 153 | "file_extension": ".py", 154 | "mimetype": "text/x-python", 155 | "name": "python", 156 | "nbconvert_exporter": "python", 157 | "pygments_lexer": "ipython2", 158 | "version": "2.7.12" 159 | } 160 | }, 161 | "nbformat": 4, 162 | "nbformat_minor": 0 163 | } 164 | -------------------------------------------------------------------------------- /Lecture 5.5 - SIFT, SURF, FAST, BRIEF & ORB.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Feature Detection" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "#### The SIFT & SURF algorithms are patented by their respective creators, and while they are free to use in academic and research settings, you should technically be obtaining a license/permission from the creators if you are using them in a commercial (i.e. for-profit) application." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## SIFT\n", 22 | "\n", 23 | "http://www.inf.fu-berlin.de/lehre/SS09/CV/uebungen/uebung09/SIFT.pdf" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 4, 29 | "metadata": { 30 | "collapsed": false 31 | }, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "('Number of keypoints Detected: ', 1890)\n" 38 | ] 39 | } 40 | ], 41 | "source": [ 42 | "import cv2\n", 43 | "import numpy as np\n", 44 | "\n", 45 | "image = cv2.imread('images/input.jpg')\n", 46 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 47 | "\n", 48 | "#Create SIFT Feature Detector object\n", 49 | "sift = cv2.SIFT()\n", 50 | "\n", 51 | "#Detect key points\n", 52 | "keypoints = sift.detect(gray, None)\n", 53 | "print(\"Number of keypoints Detected: \", len(keypoints))\n", 54 | "\n", 55 | "# Draw rich key points on input image\n", 56 | "image = cv2.drawKeypoints(image, keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 57 | "\n", 58 | "cv2.imshow('Feature Method - SIFT', image)\n", 59 | "cv2.waitKey(0)\n", 60 | "cv2.destroyAllWindows()" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "## SURF\n", 68 | "\n", 69 | "http://www.vision.ee.ethz.ch/~surf/eccv06.pdf" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 7, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "Number of keypoints Detected: 1543\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "import cv2\n", 89 | "import numpy as np\n", 90 | "\n", 91 | "image = cv2.imread('images/input.jpg')\n", 92 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 93 | "\n", 94 | "#Create SURF Feature Detector object\n", 95 | "surf = cv2.SURF()\n", 96 | "\n", 97 | "# Only features, whose hessian is larger than hessianThreshold are retained by the detector\n", 98 | "surf.hessianThreshold = 500\n", 99 | "keypoints, descriptors = surf.detectAndCompute(gray, None)\n", 100 | "print \"Number of keypoints Detected: \", len(keypoints)\n", 101 | "\n", 102 | "# Draw rich key points on input image\n", 103 | "image = cv2.drawKeypoints(image, keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 104 | "\n", 105 | "cv2.imshow('Feature Method - SURF', image)\n", 106 | "cv2.waitKey()\n", 107 | "cv2.destroyAllWindows()" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "## FAST\n", 115 | "\n", 116 | "https://www.edwardrosten.com/work/rosten_2006_machine.pdf\n", 117 | "http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/AV1011/AV1FeaturefromAcceleratedSegmentTest.pdf" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 8, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "Number of keypoints Detected: 8963\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "import cv2\n", 137 | "import numpy as np\n", 138 | "\n", 139 | "image = cv2.imread('images/input.jpg')\n", 140 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 141 | "\n", 142 | "# Create FAST Detector object\n", 143 | "fast = cv2.FastFeatureDetector()\n", 144 | "\n", 145 | "# Obtain Key points, by default non max suppression is On\n", 146 | "# to turn off set fast.setBool('nonmaxSuppression', False)\n", 147 | "keypoints = fast.detect(gray, None)\n", 148 | "print \"Number of keypoints Detected: \", len(keypoints)\n", 149 | "\n", 150 | "# Draw rich keypoints on input image\n", 151 | "image = cv2.drawKeypoints(image, keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 152 | "\n", 153 | "cv2.imshow('Feature Method - FAST', image)\n", 154 | "cv2.waitKey()\n", 155 | "cv2.destroyAllWindows()" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "## BRIEF\n", 163 | "\n", 164 | "http://cvlabwww.epfl.ch/~lepetit/papers/calonder_pami11.pdf" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 9, 170 | "metadata": { 171 | "collapsed": false 172 | }, 173 | "outputs": [ 174 | { 175 | "name": "stdout", 176 | "output_type": "stream", 177 | "text": [ 178 | "Number of keypoints Detected: 8738\n" 179 | ] 180 | } 181 | ], 182 | "source": [ 183 | "import cv2\n", 184 | "import numpy as np\n", 185 | "\n", 186 | "image = cv2.imread('images/input.jpg')\n", 187 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 188 | "\n", 189 | "# Create FAST detector object\n", 190 | "fast = cv2.FastFeatureDetector()\n", 191 | "\n", 192 | "# Create BRIEF extractor object\n", 193 | "brief = cv2.DescriptorExtractor_create(\"BRIEF\")\n", 194 | "\n", 195 | "# Determine key points\n", 196 | "keypoints = fast.detect(gray, None)\n", 197 | "\n", 198 | "# Obtain descriptors and new final keypoints using BRIEF\n", 199 | "keypoints, descriptors = brief.compute(gray, keypoints)\n", 200 | "print \"Number of keypoints Detected: \", len(keypoints)\n", 201 | "\n", 202 | "# Draw rich keypoints on input image\n", 203 | "image = cv2.drawKeypoints(image, keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 204 | " \n", 205 | "cv2.imshow('Feature Method - BRIEF', image)\n", 206 | "cv2.waitKey()\n", 207 | "cv2.destroyAllWindows()" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "## Oriented FAST and Rotated BRIEF (ORB)\n", 215 | "http://www.willowgarage.com/sites/default/files/orb_final.pdf" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": 17, 221 | "metadata": { 222 | "collapsed": false 223 | }, 224 | "outputs": [ 225 | { 226 | "name": "stdout", 227 | "output_type": "stream", 228 | "text": [ 229 | "('Number of keypoints Detected: ', 500)\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "import cv2\n", 235 | "import numpy as np\n", 236 | "\n", 237 | "image = cv2.imread('images/input.jpg')\n", 238 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 239 | "\n", 240 | "# Create ORB object, we can specify the number of key points we desire\n", 241 | "orb = cv2.ORB()\n", 242 | "\n", 243 | "# Determine key points\n", 244 | "keypoints = orb.detect(gray, None)\n", 245 | "\n", 246 | "# Obtain the descriptors\n", 247 | "keypoints, descriptors = orb.compute(gray, keypoints)\n", 248 | "print(\"Number of keypoints Detected: \", len(keypoints))\n", 249 | "\n", 250 | "# Draw rich keypoints on input image\n", 251 | "image = cv2.drawKeypoints(image, keypoints,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n", 252 | "\n", 253 | "cv2.imshow('Feature Method - ORB', image)\n", 254 | "cv2.waitKey()\n", 255 | "cv2.destroyAllWindows()" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": null, 261 | "metadata": { 262 | "collapsed": true 263 | }, 264 | "outputs": [], 265 | "source": [] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "metadata": { 271 | "collapsed": true 272 | }, 273 | "outputs": [], 274 | "source": [] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": null, 279 | "metadata": { 280 | "collapsed": true 281 | }, 282 | "outputs": [], 283 | "source": [] 284 | } 285 | ], 286 | "metadata": { 287 | "kernelspec": { 288 | "display_name": "Python 2", 289 | "language": "python", 290 | "name": "python2" 291 | }, 292 | "language_info": { 293 | "codemirror_mode": { 294 | "name": "ipython", 295 | "version": 2 296 | }, 297 | "file_extension": ".py", 298 | "mimetype": "text/x-python", 299 | "name": "python", 300 | "nbconvert_exporter": "python", 301 | "pygments_lexer": "ipython2", 302 | "version": "2.7.11" 303 | } 304 | }, 305 | "nbformat": 4, 306 | "nbformat_minor": 0 307 | } 308 | -------------------------------------------------------------------------------- /Lecture 5.6 - Mini Project # 5 - Object Detection using SIFT & ORB.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project #5 - Object Detection using SIFT" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "\n", 22 | "def sift_detector(new_image, image_template):\n", 23 | " # Function that compares input image to template\n", 24 | " # It then returns the number of SIFT matches between them\n", 25 | " \n", 26 | " image1 = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)\n", 27 | " image2 = image_template\n", 28 | " \n", 29 | " # Create SIFT detector object\n", 30 | " sift = cv2.SIFT()\n", 31 | "\n", 32 | " # Obtain the keypoints and descriptors using SIFT\n", 33 | " keypoints_1, descriptors_1 = sift.detectAndCompute(image1, None)\n", 34 | " keypoints_2, descriptors_2 = sift.detectAndCompute(image2, None)\n", 35 | "\n", 36 | " # Define parameters for our Flann Matcher\n", 37 | " FLANN_INDEX_KDTREE = 0\n", 38 | " index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 3)\n", 39 | " search_params = dict(checks = 100)\n", 40 | "\n", 41 | " # Create the Flann Matcher object\n", 42 | " flann = cv2.FlannBasedMatcher(index_params, search_params)\n", 43 | "\n", 44 | " # Obtain matches using K-Nearest Neighbor Method\n", 45 | " # the result 'matchs' is the number of similar matches found in both images\n", 46 | " matches = flann.knnMatch(descriptors_1, descriptors_2, k=2)\n", 47 | "\n", 48 | " # Store good matches using Lowe's ratio test\n", 49 | " good_matches = []\n", 50 | " for m,n in matches:\n", 51 | " if m.distance < 0.7 * n.distance:\n", 52 | " good_matches.append(m) \n", 53 | "\n", 54 | " return len(good_matches)\n", 55 | "\n", 56 | "\n", 57 | "cap = cv2.VideoCapture(0)\n", 58 | "\n", 59 | "# Load our image template, this is our reference image\n", 60 | "image_template = cv2.imread('images/iphone4.jpg', 0) \n", 61 | "\n", 62 | "while True:\n", 63 | "\n", 64 | " # Get webcam images\n", 65 | " ret, frame = cap.read()\n", 66 | "\n", 67 | " # Get height and width of webcam frame\n", 68 | " height, width = frame.shape[:2]\n", 69 | "\n", 70 | " # Define ROI Box Dimensions\n", 71 | " top_left_x = width / 3\n", 72 | " top_left_y = (height / 2) + (height / 4)\n", 73 | " bottom_right_x = (width / 3) * 2\n", 74 | " bottom_right_y = (height / 2) - (height / 4)\n", 75 | " \n", 76 | " # Draw rectangular window for our region of interest \n", 77 | " cv2.rectangle(frame, (top_left_x,top_left_y), (bottom_right_x,bottom_right_y), 255, 3)\n", 78 | " \n", 79 | " # Crop window of observation we defined above\n", 80 | " cropped = frame[bottom_right_y:top_left_y , top_left_x:bottom_right_x]\n", 81 | " \n", 82 | " # Flip frame orientation horizontally\n", 83 | " frame = cv2.flip(frame,1)\n", 84 | " \n", 85 | " # Get number of SIFT matches\n", 86 | " matches = sift_detector(cropped, image_template)\n", 87 | "\n", 88 | " # Display status string showing the current no. of matches \n", 89 | " cv2.putText(frame,str(matches),(450,450), cv2.FONT_HERSHEY_COMPLEX, 2,(0,255,0),1)\n", 90 | " \n", 91 | " # Our threshold to indicate object deteciton\n", 92 | " # We use 10 since the SIFT detector returns little false positves\n", 93 | " threshold = 10\n", 94 | " \n", 95 | " # If matches exceed our threshold then object has been detected\n", 96 | " if matches > threshold:\n", 97 | " cv2.rectangle(frame, (top_left_x,top_left_y), (bottom_right_x,bottom_right_y), (0,255,0), 3)\n", 98 | " cv2.putText(frame,'Object Found',(50,50), cv2.FONT_HERSHEY_COMPLEX, 2 ,(0,255,0), 2)\n", 99 | " \n", 100 | " cv2.imshow('Object Detector using SIFT', frame)\n", 101 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 102 | " break\n", 103 | "\n", 104 | "cap.release()\n", 105 | "cv2.destroyAllWindows() " 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "#### Flannbased matching is quite fast, but not the most accurate. Other matching methods include:\n", 113 | "\n", 114 | "- BruteForce\n", 115 | "- BruteForce-SL2 (not in the documentation, BUT this is the one that skeeps the squared root !)\n", 116 | "- BruteForce-L1\n", 117 | "- BruteForce-Hamming\n", 118 | "- BruteForce-Hamming(2)\n" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "## Object Detection using ORB" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 22, 131 | "metadata": { 132 | "collapsed": true 133 | }, 134 | "outputs": [], 135 | "source": [ 136 | "import cv2\n", 137 | "import numpy as np\n", 138 | "\n", 139 | "\n", 140 | "def ORB_detector(new_image, image_template):\n", 141 | " # Function that compares input image to template\n", 142 | " # It then returns the number of ORB matches between them\n", 143 | " \n", 144 | " image1 = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)\n", 145 | "\n", 146 | " # Create ORB detector with 1000 keypoints with a scaling pyramid factor of 1.2\n", 147 | " orb = cv2.ORB(1000, 1.2)\n", 148 | "\n", 149 | " # Detect keypoints of original image\n", 150 | " (kp1, des1) = orb.detectAndCompute(image1, None)\n", 151 | "\n", 152 | " # Detect keypoints of rotated image\n", 153 | " (kp2, des2) = orb.detectAndCompute(image_template, None)\n", 154 | "\n", 155 | " # Create matcher \n", 156 | " # Note we're no longer using Flannbased matching\n", 157 | " bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)\n", 158 | "\n", 159 | " # Do matching\n", 160 | " matches = bf.match(des1,des2)\n", 161 | "\n", 162 | " # Sort the matches based on distance. Least distance\n", 163 | " # is better\n", 164 | " matches = sorted(matches, key=lambda val: val.distance)\n", 165 | "\n", 166 | " return len(matches)\n", 167 | "\n", 168 | "cap = cv2.VideoCapture(0)\n", 169 | "\n", 170 | "# Load our image template, this is our reference image\n", 171 | "image_template = cv2.imread('images/box_in_scene.png', 0) \n", 172 | "# image_template = cv2.imread('images/kitkat.jpg', 0) \n", 173 | "\n", 174 | "while True:\n", 175 | "\n", 176 | " # Get webcam images\n", 177 | " ret, frame = cap.read()\n", 178 | " \n", 179 | " # Get height and width of webcam frame\n", 180 | " height, width = frame.shape[:2]\n", 181 | "\n", 182 | " # Define ROI Box Dimensions (Note some of these things should be outside the loop)\n", 183 | " top_left_x = width / 3\n", 184 | " top_left_y = (height / 2) + (height / 4)\n", 185 | " bottom_right_x = (width / 3) * 2\n", 186 | " bottom_right_y = (height / 2) - (height / 4)\n", 187 | " \n", 188 | " # Draw rectangular window for our region of interest\n", 189 | " cv2.rectangle(frame, (top_left_x,top_left_y), (bottom_right_x,bottom_right_y), 255, 3)\n", 190 | " \n", 191 | " # Crop window of observation we defined above\n", 192 | " cropped = frame[bottom_right_y:top_left_y , top_left_x:bottom_right_x]\n", 193 | "\n", 194 | " # Flip frame orientation horizontally\n", 195 | " frame = cv2.flip(frame,1)\n", 196 | " \n", 197 | " # Get number of ORB matches \n", 198 | " matches = ORB_detector(cropped, image_template)\n", 199 | " \n", 200 | " # Display status string showing the current no. of matches \n", 201 | " output_string = \"Matches = \" + str(matches)\n", 202 | " cv2.putText(frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2)\n", 203 | " \n", 204 | " # Our threshold to indicate object deteciton\n", 205 | " # For new images or lightening conditions you may need to experiment a bit \n", 206 | " # Note: The ORB detector to get the top 1000 matches, 350 is essentially a min 35% match\n", 207 | " threshold = 350\n", 208 | " \n", 209 | " # If matches exceed our threshold then object has been detected\n", 210 | " if matches > threshold:\n", 211 | " cv2.rectangle(frame, (top_left_x,top_left_y), (bottom_right_x,bottom_right_y), (0,255,0), 3)\n", 212 | " cv2.putText(frame,'Object Found',(50,50), cv2.FONT_HERSHEY_COMPLEX, 2 ,(0,255,0), 2)\n", 213 | " \n", 214 | " cv2.imshow('Object Detector using ORB', frame)\n", 215 | " \n", 216 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 217 | " break\n", 218 | "\n", 219 | "cap.release()\n", 220 | "cv2.destroyAllWindows() " 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": null, 226 | "metadata": { 227 | "collapsed": false 228 | }, 229 | "outputs": [], 230 | "source": [] 231 | } 232 | ], 233 | "metadata": { 234 | "anaconda-cloud": {}, 235 | "kernelspec": { 236 | "display_name": "Python [conda env:Python2.7]", 237 | "language": "python", 238 | "name": "conda-env-Python2.7-py" 239 | }, 240 | "language_info": { 241 | "codemirror_mode": { 242 | "name": "ipython", 243 | "version": 2 244 | }, 245 | "file_extension": ".py", 246 | "mimetype": "text/x-python", 247 | "name": "python", 248 | "nbconvert_exporter": "python", 249 | "pygments_lexer": "ipython2", 250 | "version": "2.7.12" 251 | } 252 | }, 253 | "nbformat": 4, 254 | "nbformat_minor": 0 255 | } 256 | -------------------------------------------------------------------------------- /Lecture 5.7 Histogram of Oriented Gradients.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Histogram of Oriented Gradients\n", 8 | "\n", 9 | "- http://stackoverflow.com/questions/6090399/get-hog-image-features-from-opencv-python\n", 10 | "- http://www.juergenwiki.de/work/wiki/doku.php?id=public:hog_descriptor_computation_and_visualization" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "metadata": { 17 | "collapsed": false 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "import numpy as np\n", 22 | "import cv2\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "\n", 25 | "# Load image then grayscale\n", 26 | "image = cv2.imread('images/elephant.jpg')\n", 27 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 28 | "\n", 29 | "# Show original Image\n", 30 | "cv2.imshow('Input Image', image)\n", 31 | "cv2.waitKey(0)\n", 32 | "\n", 33 | "# h x w in pixels\n", 34 | "cell_size = (8, 8) \n", 35 | "\n", 36 | " # h x w in cells\n", 37 | "block_size = (2, 2) \n", 38 | "\n", 39 | "# number of orientation bins\n", 40 | "nbins = 9\n", 41 | "\n", 42 | "# Using OpenCV's HOG Descriptor\n", 43 | "# winSize is the size of the image cropped to a multiple of the cell size\n", 44 | "hog = cv2.HOGDescriptor(_winSize=(gray.shape[1] // cell_size[1] * cell_size[1],\n", 45 | " gray.shape[0] // cell_size[0] * cell_size[0]),\n", 46 | " _blockSize=(block_size[1] * cell_size[1],\n", 47 | " block_size[0] * cell_size[0]),\n", 48 | " _blockStride=(cell_size[1], cell_size[0]),\n", 49 | " _cellSize=(cell_size[1], cell_size[0]),\n", 50 | " _nbins=nbins)\n", 51 | "\n", 52 | "# Create numpy array shape which we use to create hog_feats\n", 53 | "n_cells = (gray.shape[0] // cell_size[0], gray.shape[1] // cell_size[1])\n", 54 | "\n", 55 | "# We index blocks by rows first.\n", 56 | "# hog_feats now contains the gradient amplitudes for each direction,\n", 57 | "# for each cell of its group for each group. Indexing is by rows then columns.\n", 58 | "hog_feats = hog.compute(gray).reshape(n_cells[1] - block_size[1] + 1,\n", 59 | " n_cells[0] - block_size[0] + 1,\n", 60 | " block_size[0], block_size[1], nbins).transpose((1, 0, 2, 3, 4)) \n", 61 | "\n", 62 | "# Create our gradients array with nbin dimensions to store gradient orientations \n", 63 | "gradients = np.zeros((n_cells[0], n_cells[1], nbins))\n", 64 | "\n", 65 | "# Create array of dimensions \n", 66 | "cell_count = np.full((n_cells[0], n_cells[1], 1), 0, dtype=int)\n", 67 | "\n", 68 | "# Block Normalization\n", 69 | "for off_y in range(block_size[0]):\n", 70 | " for off_x in range(block_size[1]):\n", 71 | " gradients[off_y:n_cells[0] - block_size[0] + off_y + 1,\n", 72 | " off_x:n_cells[1] - block_size[1] + off_x + 1] += \\\n", 73 | " hog_feats[:, :, off_y, off_x, :]\n", 74 | " cell_count[off_y:n_cells[0] - block_size[0] + off_y + 1,\n", 75 | " off_x:n_cells[1] - block_size[1] + off_x + 1] += 1\n", 76 | "\n", 77 | "# Average gradients\n", 78 | "gradients /= cell_count\n", 79 | "\n", 80 | "# Plot HOGs using Matplotlib\n", 81 | "# angle is 360 / nbins * direction\n", 82 | "color_bins = 5\n", 83 | "plt.pcolor(gradients[:, :, color_bins])\n", 84 | "plt.gca().invert_yaxis()\n", 85 | "plt.gca().set_aspect('equal', adjustable='box')\n", 86 | "plt.colorbar()\n", 87 | "plt.show()\n", 88 | "cv2.destroyAllWindows()" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": { 95 | "collapsed": true 96 | }, 97 | "outputs": [], 98 | "source": [] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": null, 103 | "metadata": { 104 | "collapsed": true 105 | }, 106 | "outputs": [], 107 | "source": [] 108 | } 109 | ], 110 | "metadata": { 111 | "kernelspec": { 112 | "display_name": "Python 2", 113 | "language": "python", 114 | "name": "python2" 115 | }, 116 | "language_info": { 117 | "codemirror_mode": { 118 | "name": "ipython", 119 | "version": 2 120 | }, 121 | "file_extension": ".py", 122 | "mimetype": "text/x-python", 123 | "name": "python", 124 | "nbconvert_exporter": "python", 125 | "pygments_lexer": "ipython2", 126 | "version": "2.7.11" 127 | } 128 | }, 129 | "nbformat": 4, 130 | "nbformat_minor": 0 131 | } 132 | -------------------------------------------------------------------------------- /Lecture 6.2 - Face & Eye Detection.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Face & Eye Detection using HAAR Cascade Classifiers" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import cv2\n", 20 | "\n", 21 | "# We point OpenCV's CascadeClassifier function to where our \n", 22 | "# classifier (XML file format) is stored\n", 23 | "face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')\n", 24 | "\n", 25 | "# Load our image then convert it to grayscale\n", 26 | "image = cv2.imread('images/Trump.jpg')\n", 27 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 28 | "\n", 29 | "# Our classifier returns the ROI of the detected face as a tuple\n", 30 | "# It stores the top left coordinate and the bottom right coordiantes\n", 31 | "faces = face_classifier.detectMultiScale(gray, 1.3, 5)\n", 32 | "\n", 33 | "# When no faces detected, face_classifier returns and empty tuple\n", 34 | "if faces is ():\n", 35 | " print(\"No faces found\")\n", 36 | "\n", 37 | "# We iterate through our faces array and draw a rectangle\n", 38 | "# over each face in faces\n", 39 | "for (x,y,w,h) in faces:\n", 40 | " cv2.rectangle(image, (x,y), (x+w,y+h), (127,0,255), 2)\n", 41 | " cv2.imshow('Face Detection', image)\n", 42 | " cv2.waitKey(0)\n", 43 | " \n", 44 | "cv2.destroyAllWindows()" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Let's combine face and eye detection" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 2, 57 | "metadata": { 58 | "collapsed": true 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "import numpy as np\n", 63 | "import cv2\n", 64 | " \n", 65 | "face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')\n", 66 | "eye_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_eye.xml')\n", 67 | " \n", 68 | "img = cv2.imread('images/Trump.jpg')\n", 69 | "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n", 70 | "\n", 71 | "faces = face_classifier.detectMultiScale(gray, 1.3, 5)\n", 72 | "\n", 73 | "# When no faces detected, face_classifier returns and empty tuple\n", 74 | "if faces is ():\n", 75 | " print(\"No Face Found\")\n", 76 | "\n", 77 | "for (x,y,w,h) in faces:\n", 78 | " cv2.rectangle(img,(x,y),(x+w,y+h),(127,0,255),2)\n", 79 | " cv2.imshow('img',img)\n", 80 | " cv2.waitKey(0)\n", 81 | " roi_gray = gray[y:y+h, x:x+w]\n", 82 | " roi_color = img[y:y+h, x:x+w]\n", 83 | " eyes = eye_classifier.detectMultiScale(roi_gray)\n", 84 | " for (ex,ey,ew,eh) in eyes:\n", 85 | " cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(255,255,0),2)\n", 86 | " cv2.imshow('img',img)\n", 87 | " cv2.waitKey(0)\n", 88 | " \n", 89 | "cv2.destroyAllWindows()" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "### Let's make a live face & eye detection, keeping the face inview at all times" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 3, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "import cv2\n", 108 | "import numpy as np\n", 109 | "\n", 110 | "face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')\n", 111 | "eye_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_eye.xml')\n", 112 | "\n", 113 | "def face_detector(img, size=0.5):\n", 114 | " # Convert image to grayscale\n", 115 | " gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n", 116 | " faces = face_classifier.detectMultiScale(gray, 1.3, 5)\n", 117 | " if faces is ():\n", 118 | " return img\n", 119 | " \n", 120 | " for (x,y,w,h) in faces:\n", 121 | " x = x - 50\n", 122 | " w = w + 50\n", 123 | " y = y - 50\n", 124 | " h = h + 50\n", 125 | " cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)\n", 126 | " roi_gray = gray[y:y+h, x:x+w]\n", 127 | " roi_color = img[y:y+h, x:x+w]\n", 128 | " eyes = eye_classifier.detectMultiScale(roi_gray)\n", 129 | " \n", 130 | " for (ex,ey,ew,eh) in eyes:\n", 131 | " cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,0,255),2) \n", 132 | " \n", 133 | " roi_color = cv2.flip(roi_color,1)\n", 134 | " return roi_color\n", 135 | "\n", 136 | "cap = cv2.VideoCapture(0)\n", 137 | "\n", 138 | "while True:\n", 139 | "\n", 140 | " ret, frame = cap.read()\n", 141 | " cv2.imshow('Our Face Extractor', face_detector(frame))\n", 142 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 143 | " break\n", 144 | " \n", 145 | "cap.release()\n", 146 | "cv2.destroyAllWindows() " 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": { 152 | "collapsed": true 153 | }, 154 | "source": [ 155 | "### Tuning Cascade Classifiers\n", 156 | "\n", 157 | "*ourClassifier*.**detectMultiScale**(input image, **Scale Factor** , **Min Neighbors**)\n", 158 | "\n", 159 | "- **Scale Factor**\n", 160 | "Specifies how much we reduce the image size each time we scale. E.g. in face detection we typically use 1.3. This means we reduce the image by 30% each time it’s scaled. Smaller values, like 1.05 will take longer to compute, but will increase the rate of detection.\n", 161 | "\n", 162 | "\n", 163 | "\n", 164 | "- **Min Neighbors**\n", 165 | "Specifies the number of neighbors each potential window should have in order to consider it a positive detection. Typically set between 3-6. \n", 166 | "It acts as sensitivity setting, low values will sometimes detect multiples faces over a single face. High values will ensure less false positives, but you may miss some faces. \n" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": { 173 | "collapsed": true 174 | }, 175 | "outputs": [], 176 | "source": [] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "metadata": { 182 | "collapsed": true 183 | }, 184 | "outputs": [], 185 | "source": [] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": { 191 | "collapsed": true 192 | }, 193 | "outputs": [], 194 | "source": [] 195 | } 196 | ], 197 | "metadata": { 198 | "anaconda-cloud": {}, 199 | "kernelspec": { 200 | "display_name": "Python [conda env:Python2.7]", 201 | "language": "python", 202 | "name": "conda-env-Python2.7-py" 203 | }, 204 | "language_info": { 205 | "codemirror_mode": { 206 | "name": "ipython", 207 | "version": 2 208 | }, 209 | "file_extension": ".py", 210 | "mimetype": "text/x-python", 211 | "name": "python", 212 | "nbconvert_exporter": "python", 213 | "pygments_lexer": "ipython2", 214 | "version": "2.7.12" 215 | } 216 | }, 217 | "nbformat": 4, 218 | "nbformat_minor": 0 219 | } 220 | -------------------------------------------------------------------------------- /Lecture 6.3 - Mini Project # 6 - Car & Pedestrian Detection.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 6 - Car & Pedestrian Detection\n", 8 | "\n", 9 | "**NOTE** \n", 10 | "- If no video loads after running code, you may need to copy your *opencv_ffmpeg.dll* \n", 11 | "- From: *C:\\opencv2413\\opencv\\sources\\3rdparty\\ffmpeg*\n", 12 | "- To: Where your python is installed e.g. *C:\\Anaconda2\\* \\\n", 13 | "- Once it's copied you'll need to rename the file according to the version of OpenCV you're using.\n", 14 | "- e.g. if you're using OpenCV 2.4.13 then rename the file as:\n", 15 | "- **opencv_ffmpeg2413_64.dll** or opencv_ffmpeg2413.dll (if you're using an X86 machine)\n", 16 | "- **opencv_ffmpeg310_64.dll** or opencv_ffmpeg310.dll (if you're using an X86 machine)\n", 17 | "\n", 18 | "To find out where you python.exe is installed, just run these two lines of code:" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | "#from cv2 import __version__\n", 38 | "import sys\n", 39 | "#print(__version__)\n", 40 | "print(sys.version_info)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### Pedistrian Detection" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "import cv2\n", 59 | "import numpy as np\n", 60 | "\n", 61 | "# Create our body classifier\n", 62 | "body_classifier = cv2.CascadeClassifier('Haarcascades\\haarcascade_fullbody.xml')\n", 63 | "\n", 64 | "# Initiate video capture for video file\n", 65 | "cap = cv2.VideoCapture('images/walking.avi')\n", 66 | "\n", 67 | "# Loop once video is successfully loaded\n", 68 | "while cap.isOpened():\n", 69 | " \n", 70 | " # Read first frame\n", 71 | " ret, frame = cap.read()\n", 72 | " frame = cv2.resize(frame, None,fx=0.5, fy=0.5, interpolation = cv2.INTER_LINEAR)\n", 73 | "\n", 74 | " gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", 75 | " # Pass frame to our body classifier\n", 76 | " bodies = body_classifier.detectMultiScale(gray, 1.2, 3)\n", 77 | " \n", 78 | " # Extract bounding boxes for any bodies identified\n", 79 | " for (x,y,w,h) in bodies:\n", 80 | " cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)\n", 81 | " cv2.imshow('Pedestrians', frame)\n", 82 | "\n", 83 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 84 | " break\n", 85 | "\n", 86 | "cap.release()\n", 87 | "cv2.destroyAllWindows()" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Car Detection\n" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 7, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "import cv2\n", 106 | "import time\n", 107 | "import numpy as np\n", 108 | "\n", 109 | "# Create our body classifier\n", 110 | "car_classifier = cv2.CascadeClassifier('Haarcascades\\haarcascade_car.xml')\n", 111 | "\n", 112 | "# Initiate video capture for video file\n", 113 | "cap = cv2.VideoCapture('images/cars.avi')\n", 114 | "\n", 115 | "\n", 116 | "# Loop once video is successfully loaded\n", 117 | "while cap.isOpened():\n", 118 | " \n", 119 | " time.sleep(.05)\n", 120 | " # Read first frame\n", 121 | " ret, frame = cap.read()\n", 122 | " gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", 123 | " \n", 124 | " # Pass frame to our car classifier\n", 125 | " cars = car_classifier.detectMultiScale(gray, 1.4, 2)\n", 126 | " \n", 127 | " # Extract bounding boxes for any bodies identified\n", 128 | " for (x,y,w,h) in cars:\n", 129 | " cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)\n", 130 | " cv2.imshow('Cars', frame)\n", 131 | "\n", 132 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 133 | " break\n", 134 | "\n", 135 | "cap.release()\n", 136 | "cv2.destroyAllWindows()" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "- **Full Body / Pedestrian Classifier ** - https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_fullbody.xml\n", 144 | "- **Car Classifier ** - http://www.codeforge.com/read/241845/cars3.xml__html\n" 145 | ] 146 | } 147 | ], 148 | "metadata": { 149 | "anaconda-cloud": {}, 150 | "kernelspec": { 151 | "display_name": "Python [conda env:Python2.7]", 152 | "language": "python", 153 | "name": "conda-env-Python2.7-py" 154 | }, 155 | "language_info": { 156 | "codemirror_mode": { 157 | "name": "ipython", 158 | "version": 2 159 | }, 160 | "file_extension": ".py", 161 | "mimetype": "text/x-python", 162 | "name": "python", 163 | "nbconvert_exporter": "python", 164 | "pygments_lexer": "ipython2", 165 | "version": "2.7.12" 166 | } 167 | }, 168 | "nbformat": 4, 169 | "nbformat_minor": 0 170 | } 171 | -------------------------------------------------------------------------------- /Lecture 7.1 - Facial Landmarks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Facial Landmarks" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "C:\\Users\\Klaus\\Anaconda3\\envs\\Python2.7\\python.exe\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "import sys\n", 27 | "print(sys.executable)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "See blog post here - https://matthewearl.github.io/2015/07/28/switching-eds-with-python/\n", 35 | "\n", 36 | "\n", 37 | "#### Install Instructions for dlib\n", 38 | "\n", 39 | "- Download and Install Dlib\n", 40 | "\n", 41 | "https://sourceforge.net/projects/dclib/\n", 42 | "\n", 43 | "- Extract files in C:/dlib \n", 44 | "- Use command prompt to Cd to folder and run “python setup.py install”\n", 45 | "\n", 46 | "#### Download the pre-trained model here \n", 47 | "\n", 48 | "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2\n", 49 | "\n", 50 | "- Place this file in your default ipython notebook folder\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 6, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [ 60 | { 61 | "ename": "ImportError", 62 | "evalue": "No module named dlib", 63 | "output_type": "error", 64 | "traceback": [ 65 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 66 | "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", 67 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mcv2\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[1;32mimport\u001b[0m \u001b[0mdlib\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mPREDICTOR_PATH\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"shape_predictor_68_face_landmarks.dat\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 68 | "\u001b[0;31mImportError\u001b[0m: No module named dlib" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "import cv2\n", 74 | "import dlib\n", 75 | "import numpy \n", 76 | "\n", 77 | "PREDICTOR_PATH = \"shape_predictor_68_face_landmarks.dat\"\n", 78 | "predictor = dlib.shape_predictor(PREDICTOR_PATH)\n", 79 | "detector = dlib.get_frontal_face_detector()\n", 80 | "\n", 81 | "\n", 82 | "class TooManyFaces(Exception):\n", 83 | " pass\n", 84 | "\n", 85 | "class NoFaces(Exception):\n", 86 | " pass\n", 87 | "\n", 88 | "def get_landmarks(im):\n", 89 | " rects = detector(im, 1)\n", 90 | "\n", 91 | " if len(rects) > 1:\n", 92 | " raise TooManyFaces\n", 93 | " if len(rects) == 0:\n", 94 | " raise NoFaces\n", 95 | "\n", 96 | " return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])\n", 97 | "\n", 98 | "def annotate_landmarks(im, landmarks):\n", 99 | " im = im.copy()\n", 100 | " for idx, point in enumerate(landmarks):\n", 101 | " pos = (point[0, 0], point[0, 1])\n", 102 | " cv2.putText(im, str(idx), pos,\n", 103 | " fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,\n", 104 | " fontScale=0.4,\n", 105 | " \n", 106 | " color=(0, 0, 255))\n", 107 | " cv2.circle(im, pos, 3, color=(0, 255, 255))\n", 108 | " return im\n", 109 | "\n", 110 | "image = cv2.imread('Obama.jpg')\n", 111 | "landmarks = get_landmarks(image)\n", 112 | "image_with_landmarks = annotate_landmarks(image, landmarks)\n", 113 | "\n", 114 | "cv2.imshow('Result', image_with_landmarks)\n", 115 | "cv2.imwrite('image_with_landmarks.jpg',image_with_landmarks)\n", 116 | "cv2.waitKey(0)\n", 117 | "cv2.destroyAllWindows()" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "metadata": { 124 | "collapsed": true 125 | }, 126 | "outputs": [], 127 | "source": [] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": { 133 | "collapsed": true 134 | }, 135 | "outputs": [], 136 | "source": [] 137 | } 138 | ], 139 | "metadata": { 140 | "anaconda-cloud": {}, 141 | "kernelspec": { 142 | "display_name": "Python [conda env:Python2.7]", 143 | "language": "python", 144 | "name": "conda-env-Python2.7-py" 145 | }, 146 | "language_info": { 147 | "codemirror_mode": { 148 | "name": "ipython", 149 | "version": 2 150 | }, 151 | "file_extension": ".py", 152 | "mimetype": "text/x-python", 153 | "name": "python", 154 | "nbconvert_exporter": "python", 155 | "pygments_lexer": "ipython2", 156 | "version": "2.7.12" 157 | } 158 | }, 159 | "nbformat": 4, 160 | "nbformat_minor": 0 161 | } 162 | -------------------------------------------------------------------------------- /Lecture 7.4 - Mini Project # 8 – Yawn Detector and Counting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 8 – Yawn Detector and Counting" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "#!/usr/bin/python\n", 19 | "\n", 20 | "# Copyright (c) 2015 Matthew Earl\n", 21 | "# \n", 22 | "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", 23 | "# of this software and associated documentation files (the \"Software\"), to deal\n", 24 | "# in the Software without restriction, including without limitation the rights\n", 25 | "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", 26 | "# copies of the Software, and to permit persons to whom the Software is\n", 27 | "# furnished to do so, subject to the following conditions:\n", 28 | "# \n", 29 | "# The above copyright notice and this permission notice shall be included\n", 30 | "# in all copies or substantial portions of the Software.\n", 31 | "# \n", 32 | "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n", 33 | "# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n", 34 | "# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n", 35 | "# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n", 36 | "# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n", 37 | "# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n", 38 | "# USE OR OTHER DEALINGS IN THE SOFTWARE.\n", 39 | "\n", 40 | "\"\"\"\n", 41 | "This is the code behind the Switching Eds blog post:\n", 42 | " http://matthewearl.github.io/2015/07/28/switching-eds-with-python/\n", 43 | "See the above for an explanation of the code below.\n", 44 | "To run the script you'll need to install dlib (http://dlib.net) including its\n", 45 | "Python bindings, and OpenCV. You'll also need to obtain the trained model from\n", 46 | "sourceforge:\n", 47 | " http://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2\n", 48 | "Unzip with `bunzip2` and change `PREDICTOR_PATH` to refer to this file. The\n", 49 | "script is run like so:\n", 50 | " ./faceswap.py \n", 51 | "If successful, a file `output.jpg` will be produced with the facial features\n", 52 | "from `` replaced with the facial features from ``.\n", 53 | "\"\"\"" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 1, 59 | "metadata": { 60 | "collapsed": false 61 | }, 62 | "outputs": [ 63 | { 64 | "name": "stderr", 65 | "output_type": "stream", 66 | "text": [ 67 | "C:\\Anaconda2\\lib\\site-packages\\ipykernel\\__main__.py:57: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "import cv2\n", 73 | "import dlib\n", 74 | "import numpy as np\n", 75 | "\n", 76 | "\n", 77 | "PREDICTOR_PATH = \"shape_predictor_68_face_landmarks.dat\"\n", 78 | "predictor = dlib.shape_predictor(PREDICTOR_PATH)\n", 79 | "#cascade_path='haarcascade_frontalface_default.xml'\n", 80 | "#cascade = cv2.CascadeClassifier(cascade_path)\n", 81 | "detector = dlib.get_frontal_face_detector()\n", 82 | "\n", 83 | "\n", 84 | "def get_landmarks(im):\n", 85 | " rects = detector(im, 1)\n", 86 | "\n", 87 | " if len(rects) > 1:\n", 88 | " return \"error\"\n", 89 | " if len(rects) == 0:\n", 90 | " return \"error\"\n", 91 | " return np.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])\n", 92 | "\n", 93 | "\n", 94 | "def annotate_landmarks(im, landmarks):\n", 95 | " im = im.copy()\n", 96 | " for idx, point in enumerate(landmarks):\n", 97 | " pos = (point[0, 0], point[0, 1])\n", 98 | " cv2.putText(im, str(idx), pos,\n", 99 | " fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,\n", 100 | " fontScale=0.4,\n", 101 | " color=(0, 0, 255))\n", 102 | " cv2.circle(im, pos, 3, color=(0, 255, 255))\n", 103 | " return im\n", 104 | "\n", 105 | "def top_lip(landmarks):\n", 106 | " top_lip_pts = []\n", 107 | " for i in range(50,53):\n", 108 | " top_lip_pts.append(landmarks[i])\n", 109 | " for i in range(61,64):\n", 110 | " top_lip_pts.append(landmarks[i])\n", 111 | " top_lip_all_pts = np.squeeze(np.asarray(top_lip_pts))\n", 112 | " top_lip_mean = np.mean(top_lip_pts, axis=0)\n", 113 | " return int(top_lip_mean[:,1])\n", 114 | "\n", 115 | "def bottom_lip(landmarks):\n", 116 | " bottom_lip_pts = []\n", 117 | " for i in range(65,68):\n", 118 | " bottom_lip_pts.append(landmarks[i])\n", 119 | " for i in range(56,59):\n", 120 | " bottom_lip_pts.append(landmarks[i])\n", 121 | " bottom_lip_all_pts = np.squeeze(np.asarray(bottom_lip_pts))\n", 122 | " bottom_lip_mean = np.mean(bottom_lip_pts, axis=0)\n", 123 | " return int(bottom_lip_mean[:,1])\n", 124 | "\n", 125 | "def mouth_open(image):\n", 126 | " landmarks = get_landmarks(image)\n", 127 | " \n", 128 | " if landmarks == \"error\":\n", 129 | " return image, 0\n", 130 | " \n", 131 | " image_with_landmarks = annotate_landmarks(image, landmarks)\n", 132 | " top_lip_center = top_lip(landmarks)\n", 133 | " bottom_lip_center = bottom_lip(landmarks)\n", 134 | " lip_distance = abs(top_lip_center - bottom_lip_center)\n", 135 | " return image_with_landmarks, lip_distance\n", 136 | "\n", 137 | " #cv2.imshow('Result', image_with_landmarks)\n", 138 | " #cv2.imwrite('image_with_landmarks.jpg',image_with_landmarks)\n", 139 | " #cv2.waitKey(0)\n", 140 | " #cv2.destroyAllWindows()\n", 141 | "\n", 142 | "cap = cv2.VideoCapture(0)\n", 143 | "yawns = 0\n", 144 | "yawn_status = False \n", 145 | "\n", 146 | "while True:\n", 147 | " ret, frame = cap.read() \n", 148 | " image_landmarks, lip_distance = mouth_open(frame)\n", 149 | " \n", 150 | " prev_yawn_status = yawn_status \n", 151 | " \n", 152 | " if lip_distance > 25:\n", 153 | " yawn_status = True \n", 154 | " \n", 155 | " cv2.putText(frame, \"Subject is Yawning\", (50,450), \n", 156 | " cv2.FONT_HERSHEY_COMPLEX, 1,(0,0,255),2)\n", 157 | " \n", 158 | "\n", 159 | " output_text = \" Yawn Count: \" + str(yawns + 1)\n", 160 | "\n", 161 | " cv2.putText(frame, output_text, (50,50),\n", 162 | " cv2.FONT_HERSHEY_COMPLEX, 1,(0,255,127),2)\n", 163 | " \n", 164 | " else:\n", 165 | " yawn_status = False \n", 166 | " \n", 167 | " if prev_yawn_status == True and yawn_status == False:\n", 168 | " yawns += 1\n", 169 | "\n", 170 | " cv2.imshow('Live Landmarks', image_landmarks )\n", 171 | " cv2.imshow('Yawn Detection', frame )\n", 172 | " \n", 173 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 174 | " break\n", 175 | " \n", 176 | "cap.release()\n", 177 | "cv2.destroyAllWindows() " 178 | ] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 2", 184 | "language": "python", 185 | "name": "python2" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 2 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython2", 197 | "version": "2.7.11" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 0 202 | } 203 | -------------------------------------------------------------------------------- /Lecture 8.2 - Mini Project # 9 - Handwritten Digit Recognition.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 9 - Handwritten Digit Recognition" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Data Prep, Training and Evaluation" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "The shape of our cells array: (50L, 100L, 20L, 20L)\n", 29 | "Accuracy is = 93.47%\n" 30 | ] 31 | } 32 | ], 33 | "source": [ 34 | "import numpy as np\n", 35 | "import cv2\n", 36 | "\n", 37 | "# Let's take a look at our digits dataset\n", 38 | "image = cv2.imread('images/digits.png')\n", 39 | "gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n", 40 | "small = cv2.pyrDown(image)\n", 41 | "cv2.imshow('Digits Image', small)\n", 42 | "cv2.waitKey(0)\n", 43 | "cv2.destroyAllWindows()\n", 44 | "\n", 45 | "# Split the image to 5000 cells, each 20x20 size\n", 46 | "# This gives us a 4-dim array: 50 x 100 x 20 x 20\n", 47 | "cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]\n", 48 | "\n", 49 | "# Convert the List data type to Numpy Array of shape (50,100,20,20)\n", 50 | "x = np.array(cells)\n", 51 | "print (\"The shape of our cells array: \" + str(x.shape))\n", 52 | "\n", 53 | "# Split the full data set into two segments\n", 54 | "# One will be used fro Training the model, the other as a test data set\n", 55 | "train = x[:,:70].reshape(-1,400).astype(np.float32) # Size = (3500,400)\n", 56 | "test = x[:,70:100].reshape(-1,400).astype(np.float32) # Size = (1500,400)\n", 57 | "\n", 58 | "# Create labels for train and test data\n", 59 | "k = [0,1,2,3,4,5,6,7,8,9]\n", 60 | "train_labels = np.repeat(k,350)[:,np.newaxis]\n", 61 | "test_labels = np.repeat(k,150)[:,np.newaxis]\n", 62 | "\n", 63 | "# Initiate kNN, train the data, then test it with test data for k=3\n", 64 | "knn = cv2.KNearest()\n", 65 | "knn.train(train, train_labels)\n", 66 | "ret, result, neighbors, distance = knn.find_nearest(test, k=3)\n", 67 | "\n", 68 | "# Now we check the accuracy of classification\n", 69 | "# For that, compare the result with test_labels and check which are wrong\n", 70 | "matches = result == test_labels\n", 71 | "correct = np.count_nonzero(matches)\n", 72 | "accuracy = correct * (100.0 / result.size)\n", 73 | "print(\"Accuracy is = %.2f\" % accuracy + \"%\")\n" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "### Defining some functions we will use to prepare an input image" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 3, 86 | "metadata": { 87 | "collapsed": true 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "import numpy as np\n", 92 | "import cv2\n", 93 | "\n", 94 | "# Define our functions\n", 95 | "\n", 96 | "def x_cord_contour(contour):\n", 97 | " # This function take a contour from findContours\n", 98 | " # it then outputs the x centroid coordinates\n", 99 | " \n", 100 | " if cv2.contourArea(contour) > 10:\n", 101 | " M = cv2.moments(contour)\n", 102 | " return (int(M['m10']/M['m00']))\n", 103 | "\n", 104 | "def makeSquare(not_square):\n", 105 | " # This function takes an image and makes the dimenions square\n", 106 | " # It adds black pixels as the padding where needed\n", 107 | " \n", 108 | " BLACK = [0,0,0]\n", 109 | " img_dim = not_square.shape\n", 110 | " height = img_dim[0]\n", 111 | " width = img_dim[1]\n", 112 | " #print(\"Height = \", height, \"Width = \", width)\n", 113 | " if (height == width):\n", 114 | " square = not_square\n", 115 | " return square\n", 116 | " else:\n", 117 | " doublesize = cv2.resize(not_square,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)\n", 118 | " height = height * 2\n", 119 | " width = width * 2\n", 120 | " #print(\"New Height = \", height, \"New Width = \", width)\n", 121 | " if (height > width):\n", 122 | " pad = (height - width)/2\n", 123 | " #print(\"Padding = \", pad)\n", 124 | " doublesize_square = cv2.copyMakeBorder(doublesize,0,0,pad,\\\n", 125 | " pad,cv2.BORDER_CONSTANT,value=BLACK)\n", 126 | " else:\n", 127 | " pad = (width - height)/2\n", 128 | " #print(\"Padding = \", pad)\n", 129 | " doublesize_square = cv2.copyMakeBorder(doublesize,pad,pad,0,0,\\\n", 130 | " cv2.BORDER_CONSTANT,value=BLACK)\n", 131 | " doublesize_square_dim = doublesize_square.shape\n", 132 | " #print(\"Sq Height = \", doublesize_square_dim[0], \"Sq Width = \", doublesize_square_dim[1])\n", 133 | " return doublesize_square\n", 134 | "\n", 135 | "\n", 136 | "def resize_to_pixel(dimensions, image):\n", 137 | " # This function then re-sizes an image to the specificied dimenions\n", 138 | " \n", 139 | " buffer_pix = 4\n", 140 | " dimensions = dimensions - buffer_pix\n", 141 | " squared = image\n", 142 | " r = float(dimensions) / squared.shape[1]\n", 143 | " dim = (dimensions, int(squared.shape[0] * r))\n", 144 | " resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)\n", 145 | " img_dim2 = resized.shape\n", 146 | " height_r = img_dim2[0]\n", 147 | " width_r = img_dim2[1]\n", 148 | " BLACK = [0,0,0]\n", 149 | " if (height_r > width_r):\n", 150 | " resized = cv2.copyMakeBorder(resized,0,0,0,1,cv2.BORDER_CONSTANT,value=BLACK)\n", 151 | " if (height_r < width_r):\n", 152 | " resized = cv2.copyMakeBorder(resized,1,0,0,0,cv2.BORDER_CONSTANT,value=BLACK)\n", 153 | " p = 2\n", 154 | " ReSizedImg = cv2.copyMakeBorder(resized,p,p,p,p,cv2.BORDER_CONSTANT,value=BLACK)\n", 155 | " img_dim = ReSizedImg.shape\n", 156 | " height = img_dim[0]\n", 157 | " width = img_dim[1]\n", 158 | " #print(\"Padded Height = \", height, \"Width = \", width)\n", 159 | " return ReSizedImg" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "## Loading a new image, preprocessing it and classifying the digits" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 5, 172 | "metadata": { 173 | "collapsed": false 174 | }, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "The number is: 13540\n" 181 | ] 182 | } 183 | ], 184 | "source": [ 185 | "import numpy as np\n", 186 | "import cv2\n", 187 | "\n", 188 | "image = cv2.imread('images/numbers.jpg')\n", 189 | "gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n", 190 | "cv2.imshow(\"image\", image)\n", 191 | "cv2.imshow(\"gray\", gray)\n", 192 | "cv2.waitKey(0)\n", 193 | "\n", 194 | "# Blur image then find edges using Canny \n", 195 | "blurred = cv2.GaussianBlur(gray, (5, 5), 0)\n", 196 | "cv2.imshow(\"blurred\", blurred)\n", 197 | "cv2.waitKey(0)\n", 198 | "\n", 199 | "edged = cv2.Canny(blurred, 30, 150)\n", 200 | "cv2.imshow(\"edged\", edged)\n", 201 | "cv2.waitKey(0)\n", 202 | "\n", 203 | "# Fint Contours\n", 204 | "contours, _ = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", 205 | "\n", 206 | "#Sort out contours left to right by using their x cordinates\n", 207 | "contours = sorted(contours, key = x_cord_contour, reverse = False)\n", 208 | "\n", 209 | "# Create empty array to store entire number\n", 210 | "full_number = []\n", 211 | "\n", 212 | "# loop over the contours\n", 213 | "for c in contours:\n", 214 | " # compute the bounding box for the rectangle\n", 215 | " (x, y, w, h) = cv2.boundingRect(c) \n", 216 | " \n", 217 | " #cv2.drawContours(image, contours, -1, (0,255,0), 3)\n", 218 | " #cv2.imshow(\"Contours\", image)\n", 219 | "\n", 220 | " if w >= 5 and h >= 25:\n", 221 | " roi = blurred[y:y + h, x:x + w]\n", 222 | " ret, roi = cv2.threshold(roi, 127, 255,cv2.THRESH_BINARY_INV)\n", 223 | " squared = makeSquare(roi)\n", 224 | " final = resize_to_pixel(20, squared)\n", 225 | " cv2.imshow(\"final\", final)\n", 226 | " final_array = final.reshape((1,400))\n", 227 | " final_array = final_array.astype(np.float32)\n", 228 | " ret, result, neighbours, dist = knn.find_nearest(final_array, k=1)\n", 229 | " number = str(int(float(result[0])))\n", 230 | " full_number.append(number)\n", 231 | " # draw a rectangle around the digit, the show what the\n", 232 | " # digit was classified as\n", 233 | " cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)\n", 234 | " cv2.putText(image, number, (x , y + 155),\n", 235 | " cv2.FONT_HERSHEY_COMPLEX, 2, (255, 0, 0), 2)\n", 236 | " cv2.imshow(\"image\", image)\n", 237 | " cv2.waitKey(0) \n", 238 | " \n", 239 | "cv2.destroyAllWindows()\n", 240 | "print (\"The number is: \" + ''.join(full_number))" 241 | ] 242 | } 243 | ], 244 | "metadata": { 245 | "kernelspec": { 246 | "display_name": "Python 2", 247 | "language": "python", 248 | "name": "python2" 249 | }, 250 | "language_info": { 251 | "codemirror_mode": { 252 | "name": "ipython", 253 | "version": 2 254 | }, 255 | "file_extension": ".py", 256 | "mimetype": "text/x-python", 257 | "name": "python", 258 | "nbconvert_exporter": "python", 259 | "pygments_lexer": "ipython2", 260 | "version": "2.7.11" 261 | } 262 | }, 263 | "nbformat": 4, 264 | "nbformat_minor": 0 265 | } 266 | -------------------------------------------------------------------------------- /Lecture 8.3 - Mini Project # 10 Face Recognition – Unlock Your Computer With Your Face!.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Face Recognition – Unlock Your Computer With Your Face!" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "\n", 15 | "### Step 1 - Create Training Data" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": { 22 | "collapsed": false 23 | }, 24 | "outputs": [ 25 | { 26 | "name": "stdout", 27 | "output_type": "stream", 28 | "text": [ 29 | "Face not found\n", 30 | "Face not found\n", 31 | "Face not found\n", 32 | "Face not found\n", 33 | "Face not found\n", 34 | "Face not found\n", 35 | "Face not found\n", 36 | "Face not found\n", 37 | "Face not found\n", 38 | "Face not found\n", 39 | "Face not found\n", 40 | "Face not found\n", 41 | "Face not found\n", 42 | "Face not found\n", 43 | "Face not found\n", 44 | "Face not found\n", 45 | "Face not found\n", 46 | "Face not found\n", 47 | "Face not found\n", 48 | "Face not found\n", 49 | "Face not found\n", 50 | "Face not found\n", 51 | "Face not found\n", 52 | "Face not found\n", 53 | "Face not found\n", 54 | "Face not found\n", 55 | "Face not found\n", 56 | "Face not found\n", 57 | "Face not found\n", 58 | "Face not found\n", 59 | "Face not found\n", 60 | "Face not found\n", 61 | "Face not found\n", 62 | "Face not found\n", 63 | "Face not found\n", 64 | "Face not found\n", 65 | "Face not found\n", 66 | "Face not found\n", 67 | "Face not found\n", 68 | "Face not found\n", 69 | "Face not found\n", 70 | "Face not found\n", 71 | "Face not found\n", 72 | "Face not found\n", 73 | "Face not found\n", 74 | "Face not found\n", 75 | "Face not found\n", 76 | "Face not found\n", 77 | "Face not found\n", 78 | "Face not found\n", 79 | "Collecting Samples Complete\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "import cv2\n", 85 | "import numpy as np\n", 86 | "\n", 87 | "# Load HAAR face classifier\n", 88 | "face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')\n", 89 | "\n", 90 | "# Load functions\n", 91 | "def face_extractor(img):\n", 92 | " # Function detects faces and returns the cropped face\n", 93 | " # If no face detected, it returns the input image\n", 94 | " \n", 95 | " gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n", 96 | " faces = face_classifier.detectMultiScale(gray, 1.3, 5)\n", 97 | " \n", 98 | " if faces is ():\n", 99 | " return None\n", 100 | " \n", 101 | " # Crop all faces found\n", 102 | " for (x,y,w,h) in faces:\n", 103 | " cropped_face = img[y:y+h, x:x+w]\n", 104 | "\n", 105 | " return cropped_face\n", 106 | "\n", 107 | "# Initialize Webcam\n", 108 | "cap = cv2.VideoCapture(0)\n", 109 | "count = 0\n", 110 | "\n", 111 | "# Collect 100 samples of your face from webcam input\n", 112 | "while True:\n", 113 | "\n", 114 | " ret, frame = cap.read()\n", 115 | " if face_extractor(frame) is not None:\n", 116 | " count += 1\n", 117 | " face = cv2.resize(face_extractor(frame), (200, 200))\n", 118 | " face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)\n", 119 | "\n", 120 | " # Save file in specified directory with unique name\n", 121 | " file_name_path = './faces/user/' + str(count) + '.jpg'\n", 122 | " cv2.imwrite(file_name_path, face)\n", 123 | "\n", 124 | " # Put count on images and display live count\n", 125 | " cv2.putText(face, str(count), (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2)\n", 126 | " cv2.imshow('Face Cropper', face)\n", 127 | " \n", 128 | " else:\n", 129 | " print(\"Face not found\")\n", 130 | " pass\n", 131 | "\n", 132 | " if cv2.waitKey(1) == 13 or count == 100: #13 is the Enter Key\n", 133 | " break\n", 134 | " \n", 135 | "cap.release()\n", 136 | "cv2.destroyAllWindows() \n", 137 | "print(\"Collecting Samples Complete\")" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "### Step 2 - Train Model" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 1, 150 | "metadata": { 151 | "collapsed": false 152 | }, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "Model trained sucessefully\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "import cv2\n", 164 | "import numpy as np\n", 165 | "from os import listdir\n", 166 | "from os.path import isfile, join\n", 167 | "\n", 168 | "# Get the training data we previously made\n", 169 | "data_path = './faces/user/'\n", 170 | "onlyfiles = [f for f in listdir(data_path) if isfile(join(data_path, f))]\n", 171 | "\n", 172 | "# Create arrays for training data and labels\n", 173 | "Training_Data, Labels = [], []\n", 174 | "\n", 175 | "# Open training images in our datapath\n", 176 | "# Create a numpy array for training data\n", 177 | "for i, files in enumerate(onlyfiles):\n", 178 | " image_path = data_path + onlyfiles[i]\n", 179 | " images = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n", 180 | " Training_Data.append(np.asarray(images, dtype=np.uint8))\n", 181 | " Labels.append(i)\n", 182 | "\n", 183 | "# Create a numpy array for both training data and labels\n", 184 | "Labels = np.asarray(Labels, dtype=np.int32)\n", 185 | "\n", 186 | "# Initialize facial recognizer\n", 187 | "model = cv2.createLBPHFaceRecognizer()\n", 188 | "# NOTE: For OpenCV 3.0 use cv2.face.createLBPHFaceRecognizer()\n", 189 | "\n", 190 | "# Let's train our model \n", 191 | "model.train(np.asarray(Training_Data), np.asarray(Labels))\n", 192 | "print(\"Model trained sucessefully\")\n" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": {}, 198 | "source": [ 199 | "### Step 3 - Run Our Facial Recognition" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 2, 205 | "metadata": { 206 | "collapsed": false 207 | }, 208 | "outputs": [], 209 | "source": [ 210 | "import cv2\n", 211 | "import numpy as np\n", 212 | "\n", 213 | "\n", 214 | "face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')\n", 215 | "\n", 216 | "def face_detector(img, size=0.5):\n", 217 | " \n", 218 | " # Convert image to grayscale\n", 219 | " gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n", 220 | " faces = face_classifier.detectMultiScale(gray, 1.3, 5)\n", 221 | " if faces is ():\n", 222 | " return img, []\n", 223 | " \n", 224 | " for (x,y,w,h) in faces:\n", 225 | " cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,255),2)\n", 226 | " roi = img[y:y+h, x:x+w]\n", 227 | " roi = cv2.resize(roi, (200, 200))\n", 228 | " return img, roi\n", 229 | "\n", 230 | "\n", 231 | "# Open Webcam\n", 232 | "cap = cv2.VideoCapture(0)\n", 233 | "\n", 234 | "while True:\n", 235 | "\n", 236 | " ret, frame = cap.read()\n", 237 | " \n", 238 | " image, face = face_detector(frame)\n", 239 | " \n", 240 | " try:\n", 241 | " face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)\n", 242 | "\n", 243 | " # Pass face to prediction model\n", 244 | " # \"results\" comprises of a tuple containing the label and the confidence value\n", 245 | " results = model.predict(face)\n", 246 | " \n", 247 | " if results[1] < 500:\n", 248 | " confidence = int( 100 * (1 - (results[1])/400) )\n", 249 | " display_string = str(confidence) + '% Confident it is User'\n", 250 | " \n", 251 | " cv2.putText(image, display_string, (100, 120), cv2.FONT_HERSHEY_COMPLEX, 1, (255,120,150), 2)\n", 252 | " \n", 253 | " if confidence > 75:\n", 254 | " cv2.putText(image, \"Unlocked\", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2)\n", 255 | " cv2.imshow('Face Recognition', image )\n", 256 | " else:\n", 257 | " cv2.putText(image, \"Locked\", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (0,0,255), 2)\n", 258 | " cv2.imshow('Face Recognition', image )\n", 259 | "\n", 260 | " except:\n", 261 | " cv2.putText(image, \"No Face Found\", (220, 120) , cv2.FONT_HERSHEY_COMPLEX, 1, (0,0,255), 2)\n", 262 | " cv2.putText(image, \"Locked\", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (0,0,255), 2)\n", 263 | " cv2.imshow('Face Recognition', image )\n", 264 | " pass\n", 265 | " \n", 266 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 267 | " break\n", 268 | " \n", 269 | "cap.release()\n", 270 | "cv2.destroyAllWindows() " 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": { 277 | "collapsed": false 278 | }, 279 | "outputs": [], 280 | "source": [] 281 | } 282 | ], 283 | "metadata": { 284 | "anaconda-cloud": {}, 285 | "kernelspec": { 286 | "display_name": "Python [conda env:Python2.7]", 287 | "language": "python", 288 | "name": "conda-env-Python2.7-py" 289 | }, 290 | "language_info": { 291 | "codemirror_mode": { 292 | "name": "ipython", 293 | "version": 2 294 | }, 295 | "file_extension": ".py", 296 | "mimetype": "text/x-python", 297 | "name": "python", 298 | "nbconvert_exporter": "python", 299 | "pygments_lexer": "ipython2", 300 | "version": "2.7.12" 301 | } 302 | }, 303 | "nbformat": 4, 304 | "nbformat_minor": 0 305 | } 306 | -------------------------------------------------------------------------------- /Lecture 9.1 - Filtering by Color.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Filtering by Color" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 11, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Initialize webcam\n", 22 | "cap = cv2.VideoCapture(0)\n", 23 | "\n", 24 | "# define range of PURPLE color in HSV\n", 25 | "lower_purple = np.array([125,0,0])\n", 26 | "upper_purple = np.array([175,255,255])\n", 27 | "\n", 28 | "# loop until break statement is exectured\n", 29 | "while True:\n", 30 | " \n", 31 | " # Read webcam image\n", 32 | " ret, frame = cap.read()\n", 33 | " \n", 34 | " # Convert image from RBG/BGR to HSV so we easily filter\n", 35 | " hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)\n", 36 | "\n", 37 | "\n", 38 | " # Use inRange to capture only the values between lower & upper_blue\n", 39 | " mask = cv2.inRange(hsv_img, lower_blue, upper_blue)\n", 40 | "\n", 41 | " # Perform Bitwise AND on mask and our original frame\n", 42 | " res = cv2.bitwise_and(frame, frame, mask=mask)\n", 43 | "\n", 44 | " cv2.imshow('Original', frame) \n", 45 | " cv2.imshow('mask', mask)\n", 46 | " cv2.imshow('Filtered Color Only', res)\n", 47 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 48 | " break\n", 49 | " \n", 50 | "cap.release()\n", 51 | "cv2.destroyAllWindows()" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": { 58 | "collapsed": false 59 | }, 60 | "outputs": [], 61 | "source": [] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": { 67 | "collapsed": true 68 | }, 69 | "outputs": [], 70 | "source": [] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "collapsed": true 77 | }, 78 | "outputs": [], 79 | "source": [] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": { 85 | "collapsed": true 86 | }, 87 | "outputs": [], 88 | "source": [] 89 | } 90 | ], 91 | "metadata": { 92 | "kernelspec": { 93 | "display_name": "Python 2", 94 | "language": "python", 95 | "name": "python2" 96 | }, 97 | "language_info": { 98 | "codemirror_mode": { 99 | "name": "ipython", 100 | "version": 2 101 | }, 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython2", 107 | "version": "2.7.11" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 0 112 | } 113 | -------------------------------------------------------------------------------- /Lecture 9.2 - Background Subtraction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Background Subtraction" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### 1. Gaussian Mixture-based Background/Foreground Segmentation Algorithm" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "# OpenCV 2.4.13 only\n", 26 | "import numpy as np\n", 27 | "import cv2\n", 28 | "\n", 29 | "cap = cv2.VideoCapture('walking.avi')\n", 30 | "\n", 31 | "# Initlaize background subtractor\n", 32 | "foreground_background = cv2.BackgroundSubtractorMOG()\n", 33 | "\n", 34 | "while True:\n", 35 | " \n", 36 | " ret, frame = cap.read()\n", 37 | "\n", 38 | " # Apply background subtractor to get our foreground mask\n", 39 | " foreground_mask = foreground_background.apply(frame)\n", 40 | "\n", 41 | " cv2.imshow('Output', foreground_mask)\n", 42 | " if cv2.waitKey(1) == 13: \n", 43 | " break\n", 44 | "\n", 45 | "cap.release()\n", 46 | "cv2.destroyAllWindows()" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### What about using this on our webcam input?" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": { 60 | "collapsed": true 61 | }, 62 | "outputs": [], 63 | "source": [ 64 | "# OpenCV 2.4.13 only\n", 65 | "import numpy as np\n", 66 | "import cv2\n", 67 | "\n", 68 | "# Intialize Webcam\n", 69 | "cap = cv2.VideoCapture(0)\n", 70 | "\n", 71 | "# Initlaize background subtractor\n", 72 | "foreground_background = cv2.BackgroundSubtractorMOG()\n", 73 | "\n", 74 | "while True:\n", 75 | " \n", 76 | " ret, frame = cap.read()\n", 77 | "\n", 78 | " # Apply background subtractor to get our foreground mask\n", 79 | " foreground_mask = foreground_background.apply(frame)\n", 80 | "\n", 81 | " cv2.imshow('Output', foreground_mask)\n", 82 | " if cv2.waitKey(1) == 13: \n", 83 | " break\n", 84 | "\n", 85 | "cap.release()\n", 86 | "cv2.destroyAllWindows()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "### Let's try the Improved adaptive Gausian mixture model for background subtraction" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "# OpenCV 2.4.13\n", 105 | "import numpy as np\n", 106 | "import cv2\n", 107 | "\n", 108 | "cap = cv2.VideoCapture('walking.avi')\n", 109 | "\n", 110 | "# Initlaize background subtractor\n", 111 | "foreground_background = cv2.BackgroundSubtractorMOG2()\n", 112 | "\n", 113 | "while True:\n", 114 | " ret, frame = cap.read()\n", 115 | "\n", 116 | " # Apply background subtractor to get our foreground mask\n", 117 | " foreground_mask = foreground_background.apply(frame)\n", 118 | "\n", 119 | " cv2.imshow('Output', foreground_mask)\n", 120 | " if cv2.waitKey(1) == 13: \n", 121 | " break\n", 122 | "\n", 123 | "cap.release()\n", 124 | "cv2.destroyAllWindows()" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "### Applying it to our webcam stream" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": { 138 | "collapsed": false 139 | }, 140 | "outputs": [], 141 | "source": [ 142 | "# OpenCV 2.4.13\n", 143 | "import numpy as np\n", 144 | "import cv2\n", 145 | "\n", 146 | "# Intialize Webcam\n", 147 | "cap = cv2.VideoCapture(0)\n", 148 | "\n", 149 | "# Initlaize background subtractor\n", 150 | "foreground_background = cv2.BackgroundSubtractorMOG2()\n", 151 | "\n", 152 | "while True:\n", 153 | " ret, frame = cap.read()\n", 154 | " \n", 155 | " # Apply background subtractor to get our foreground mask\n", 156 | " foreground_mask = foreground_background.apply(frame)\n", 157 | "\n", 158 | " cv2.imshow('Output', foreground_mask)\n", 159 | " if cv2.waitKey(1) == 13: \n", 160 | " break\n", 161 | "\n", 162 | "cap.release()\n", 163 | "cv2.destroyAllWindows()" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "collapsed": true 171 | }, 172 | "outputs": [], 173 | "source": [] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "## What about foreground substraction?" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 1, 185 | "metadata": { 186 | "collapsed": false 187 | }, 188 | "outputs": [], 189 | "source": [ 190 | "import cv2\n", 191 | "import numpy as np\n", 192 | "\n", 193 | "# Initalize webacam and store first frame\n", 194 | "cap = cv2.VideoCapture(0)\n", 195 | "ret, frame = cap.read()\n", 196 | "\n", 197 | "# Create a flaot numpy array with frame values\n", 198 | "average = np.float32(frame)\n", 199 | "\n", 200 | "while True:\n", 201 | " # Get webcam frmae\n", 202 | " ret, frame = cap.read()\n", 203 | " \n", 204 | " # 0.01 is the weight of image, play around to see how it changes\n", 205 | " cv2.accumulateWeighted(frame, average, 0.01)\n", 206 | " \n", 207 | " # Scales, calculates absolute values, and converts the result to 8-bit\n", 208 | " background = cv2.convertScaleAbs(average)\n", 209 | "\n", 210 | " cv2.imshow('Input', frame)\n", 211 | " cv2.imshow('Disapearing Background', background)\n", 212 | " \n", 213 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 214 | " break\n", 215 | "\n", 216 | "cv2.destroyAllWindows()\n", 217 | "cap.release()" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "### Background Substraction KKN\n", 225 | "#### OpenCV 3.X only!" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 1, 231 | "metadata": { 232 | "collapsed": false 233 | }, 234 | "outputs": [], 235 | "source": [ 236 | "# OpenCV 3.1.0\n", 237 | "import numpy as np\n", 238 | "import cv2\n", 239 | "\n", 240 | "cap = cv2.VideoCapture(0)\n", 241 | "\n", 242 | "kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))\n", 243 | "fgbg = cv2.createBackgroundSubtractorKNN()\n", 244 | "\n", 245 | "while(1):\n", 246 | " ret, frame = cap.read()\n", 247 | "\n", 248 | " fgmask = fgbg.apply(frame)\n", 249 | " fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)\n", 250 | "\n", 251 | " cv2.imshow('frame',fgmask)\n", 252 | " \n", 253 | " if cv2.waitKey(1) == 13: \n", 254 | " break\n", 255 | "\n", 256 | "cap.release()\n", 257 | "cv2.destroyAllWindows()" 258 | ] 259 | } 260 | ], 261 | "metadata": { 262 | "kernelspec": { 263 | "display_name": "Python 2", 264 | "language": "python", 265 | "name": "python2" 266 | }, 267 | "language_info": { 268 | "codemirror_mode": { 269 | "name": "ipython", 270 | "version": 2 271 | }, 272 | "file_extension": ".py", 273 | "mimetype": "text/x-python", 274 | "name": "python", 275 | "nbconvert_exporter": "python", 276 | "pygments_lexer": "ipython2", 277 | "version": "2.7.11" 278 | } 279 | }, 280 | "nbformat": 4, 281 | "nbformat_minor": 0 282 | } 283 | -------------------------------------------------------------------------------- /Lecture 9.3 - Meanshift Object Tracking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Meanshift Object Tracking" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import cv2\n", 20 | "\n", 21 | "# Initialize webcam\n", 22 | "cap = cv2.VideoCapture(0)\n", 23 | "\n", 24 | "# take first frame of the video\n", 25 | "ret, frame = cap.read()\n", 26 | "print type(frame)\n", 27 | "\n", 28 | "# setup default location of window\n", 29 | "r, h, c, w = 240, 100, 400, 160 \n", 30 | "track_window = (c, r, w, h)\n", 31 | "\n", 32 | "# Crop region of interest for tracking\n", 33 | "roi = frame[r:r+h, c:c+w]\n", 34 | "\n", 35 | "# Convert cropped window to HSV color space\n", 36 | "hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)\n", 37 | "\n", 38 | "# Create a mask between the HSV bounds\n", 39 | "lower_purple = np.array([125,0,0])\n", 40 | "upper_purple = np.array([175,255,255])\n", 41 | "mask = cv2.inRange(hsv_roi, lower_purple, upper_purple)\n", 42 | "\n", 43 | "# Obtain the color histogram of the ROI\n", 44 | "roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0,180])\n", 45 | "\n", 46 | "# Normalize values to lie between the range 0, 255\n", 47 | "cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)\n", 48 | "\n", 49 | "# Setup the termination criteria\n", 50 | "# We stop calculating the centroid shift after ten iterations \n", 51 | "# or if the centroid has moved at least 1 pixel\n", 52 | "term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )\n", 53 | "\n", 54 | "while True:\n", 55 | " \n", 56 | " # Read webcam frame\n", 57 | " ret, frame = cap.read()\n", 58 | "\n", 59 | " if ret == True:\n", 60 | " \n", 61 | " # Convert to HSV\n", 62 | " hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)\n", 63 | " \n", 64 | " # Calculate the histogram back projection \n", 65 | " # Each pixel's value is it's probability\n", 66 | " dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)\n", 67 | "\n", 68 | " # apply meanshift to get the new location\n", 69 | " ret, track_window = cv2.meanShift(dst, track_window, term_crit)\n", 70 | "\n", 71 | " # Draw it on image\n", 72 | " x, y, w, h = track_window\n", 73 | " img2 = cv2.rectangle(frame, (x,y), (x+w, y+h), 255, 2) \n", 74 | "\n", 75 | " cv2.imshow('Meansift Tracking', img2)\n", 76 | " \n", 77 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 78 | " break\n", 79 | "\n", 80 | " else:\n", 81 | " break\n", 82 | "\n", 83 | "cv2.destroyAllWindows()\n", 84 | "cap.release()" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "### What are cv2.calcHist and cv2.calcBackProject?" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "**cv2.calcHist ** is simply a function calculates the color histograms for an array of images.\n", 99 | "\n", 100 | "**calcBackProject** is a somewhat more complicated function, that calculates the histogram back projection.\n", 101 | "\n", 102 | "In this case, the histogram back projection gives a probability estimate an image is equal to the image the original histogram was generated. \n", 103 | "\n", 104 | "Confused yet?\n", 105 | "\n", 106 | "calcBackProject takes the histogram generated by calcHist and projects it back onto an image. The result is the probability that each pixel belongs to the image that originally generated the histogram.\n" 107 | ] 108 | } 109 | ], 110 | "metadata": { 111 | "kernelspec": { 112 | "display_name": "Python 2", 113 | "language": "python", 114 | "name": "python2" 115 | }, 116 | "language_info": { 117 | "codemirror_mode": { 118 | "name": "ipython", 119 | "version": 2 120 | }, 121 | "file_extension": ".py", 122 | "mimetype": "text/x-python", 123 | "name": "python", 124 | "nbconvert_exporter": "python", 125 | "pygments_lexer": "ipython2", 126 | "version": "2.7.11" 127 | } 128 | }, 129 | "nbformat": 4, 130 | "nbformat_minor": 0 131 | } 132 | -------------------------------------------------------------------------------- /Lecture 9.4 - Camshift Object Tracking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Camshift Object Tracking" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import cv2\n", 20 | "\n", 21 | "# Initialize webcam\n", 22 | "cap = cv2.VideoCapture(0)\n", 23 | "\n", 24 | "# take first frame of the video\n", 25 | "ret, frame = cap.read()\n", 26 | "\n", 27 | "# setup default location of window\n", 28 | "r, h, c, w = 240, 100, 400, 160 \n", 29 | "track_window = (c, r, w, h)\n", 30 | "\n", 31 | "# Crop region of interest for tracking\n", 32 | "roi = frame[r:r+h, c:c+w]\n", 33 | "\n", 34 | "# Convert cropped window to HSV color space\n", 35 | "hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)\n", 36 | "\n", 37 | "# Create a mask between the HSV bounds\n", 38 | "lower_purple = np.array([130,60,60])\n", 39 | "upper_purple = np.array([175,255,255])\n", 40 | "mask = cv2.inRange(hsv_roi, lower_purple, upper_purple)\n", 41 | "\n", 42 | "# Obtain the color histogram of the ROI\n", 43 | "roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0,180])\n", 44 | "\n", 45 | "# Normalize values to lie between the range 0, 255\n", 46 | "cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)\n", 47 | "\n", 48 | "# Setup the termination criteria\n", 49 | "# We stop calculating the centroid shift after ten iterations \n", 50 | "# or if the centroid has moved at least 1 pixel\n", 51 | "term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )\n", 52 | "\n", 53 | "while True:\n", 54 | " \n", 55 | " # Read webcam frame\n", 56 | " ret, frame = cap.read()\n", 57 | "\n", 58 | " if ret == True:\n", 59 | " # Convert to HSV\n", 60 | " hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)\n", 61 | " \n", 62 | " # Calculate the histogram back projection \n", 63 | " # Each pixel's value is it's probability\n", 64 | " dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)\n", 65 | "\n", 66 | " # apply Camshift to get the new location\n", 67 | " ret, track_window = cv2.CamShift(dst, track_window, term_crit)\n", 68 | "\n", 69 | " # Draw it on image \n", 70 | " # We use polylines to represent Adaptive box \n", 71 | " pts = cv2.boxPoints(ret)\n", 72 | " pts = np.int0(pts)\n", 73 | " img2 = cv2.polylines(frame,[pts],True, 255,2)\n", 74 | " \n", 75 | " cv2.imshow('Camshift Tracking', img2)\n", 76 | " \n", 77 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 78 | " break\n", 79 | "\n", 80 | " else:\n", 81 | " break\n", 82 | "\n", 83 | "cv2.destroyAllWindows()\n", 84 | "cap.release()" 85 | ] 86 | } 87 | ], 88 | "metadata": { 89 | "kernelspec": { 90 | "display_name": "Python 2", 91 | "language": "python", 92 | "name": "python2" 93 | }, 94 | "language_info": { 95 | "codemirror_mode": { 96 | "name": "ipython", 97 | "version": 2 98 | }, 99 | "file_extension": ".py", 100 | "mimetype": "text/x-python", 101 | "name": "python", 102 | "nbconvert_exporter": "python", 103 | "pygments_lexer": "ipython2", 104 | "version": "2.7.11" 105 | } 106 | }, 107 | "nbformat": 4, 108 | "nbformat_minor": 0 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenCV-with-Python 2 | 3 | A lot of Python Notebooks for Jupyter. 4 | 5 | All code was created during a course for OpenCV with Python. 6 | -------------------------------------------------------------------------------- /images/4star.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/4star.jpg -------------------------------------------------------------------------------- /images/Bitmap.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/Bitmap.bmp -------------------------------------------------------------------------------- /images/GeneralMethod.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/GeneralMethod.jpg -------------------------------------------------------------------------------- /images/Hillary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/Hillary.jpg -------------------------------------------------------------------------------- /images/IMG_7539.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/IMG_7539.jpg -------------------------------------------------------------------------------- /images/IMG_8295.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/IMG_8295.JPG -------------------------------------------------------------------------------- /images/Origin_of_Species.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/Origin_of_Species.jpg -------------------------------------------------------------------------------- /images/Sunflowers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/Sunflowers.jpg -------------------------------------------------------------------------------- /images/Trump.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/Trump.jpg -------------------------------------------------------------------------------- /images/WaldoBeach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/WaldoBeach.jpg -------------------------------------------------------------------------------- /images/abraham.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/abraham.jpg -------------------------------------------------------------------------------- /images/abraham_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/abraham_mask.png -------------------------------------------------------------------------------- /images/beatle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/beatle.jpg -------------------------------------------------------------------------------- /images/blobs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/blobs.jpg -------------------------------------------------------------------------------- /images/bottlecaps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/bottlecaps.jpg -------------------------------------------------------------------------------- /images/box_in_scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/box_in_scene.png -------------------------------------------------------------------------------- /images/bunchofshapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/bunchofshapes.jpg -------------------------------------------------------------------------------- /images/candy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/candy.jpg -------------------------------------------------------------------------------- /images/cars.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/cars.avi -------------------------------------------------------------------------------- /images/chess.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/chess.JPG -------------------------------------------------------------------------------- /images/chihuahua.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/chihuahua.jpg -------------------------------------------------------------------------------- /images/coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/coffee.jpg -------------------------------------------------------------------------------- /images/contours.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/contours.jpg -------------------------------------------------------------------------------- /images/digits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/digits.png -------------------------------------------------------------------------------- /images/domino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/domino.png -------------------------------------------------------------------------------- /images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/download.png -------------------------------------------------------------------------------- /images/eigenface_reconstruction_opencv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/eigenface_reconstruction_opencv.png -------------------------------------------------------------------------------- /images/elephant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/elephant.jpg -------------------------------------------------------------------------------- /images/ex2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/ex2.jpg -------------------------------------------------------------------------------- /images/faceswap.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/faceswap.JPG -------------------------------------------------------------------------------- /images/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/gradient.jpg -------------------------------------------------------------------------------- /images/hand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/hand.jpg -------------------------------------------------------------------------------- /images/house.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/house.jpg -------------------------------------------------------------------------------- /images/input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/input.jpg -------------------------------------------------------------------------------- /images/input33.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/input33.JPG -------------------------------------------------------------------------------- /images/iphone4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/iphone4.jpg -------------------------------------------------------------------------------- /images/kim.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/kim.jpg -------------------------------------------------------------------------------- /images/lourve_noise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/lourve_noise.jpg -------------------------------------------------------------------------------- /images/marsface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/marsface.jpg -------------------------------------------------------------------------------- /images/mask.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/mask.jpg -------------------------------------------------------------------------------- /images/numbers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/numbers.jpg -------------------------------------------------------------------------------- /images/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/obama.jpg -------------------------------------------------------------------------------- /images/obamafacerecog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/obamafacerecog.jpg -------------------------------------------------------------------------------- /images/opencv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/opencv.png -------------------------------------------------------------------------------- /images/opencv_inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/opencv_inv.png -------------------------------------------------------------------------------- /images/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/output.jpg -------------------------------------------------------------------------------- /images/photorestore.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/photorestore.JPG -------------------------------------------------------------------------------- /images/rot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/rot.jpg -------------------------------------------------------------------------------- /images/scan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/scan.jpg -------------------------------------------------------------------------------- /images/shapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/shapes.jpg -------------------------------------------------------------------------------- /images/shapes_donut.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/shapes_donut.jpg -------------------------------------------------------------------------------- /images/shapestomatch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/shapestomatch.jpg -------------------------------------------------------------------------------- /images/soduku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/soduku.jpg -------------------------------------------------------------------------------- /images/someshapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/someshapes.jpg -------------------------------------------------------------------------------- /images/tobago.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/tobago.jpg -------------------------------------------------------------------------------- /images/truck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/truck.jpg -------------------------------------------------------------------------------- /images/waldo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/waldo.jpg -------------------------------------------------------------------------------- /images/walking.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chewbacca89/OpenCV-with-Python/3e4c5f8ae52cf2ad20351a9cd2ef757ad1463ff8/images/walking.avi --------------------------------------------------------------------------------