├── Haarcascades ├── haarcascade_car.xml ├── haarcascade_eye.xml ├── haarcascade_frontalface_default.xml └── haarcascade_fullbody.xml ├── Lecture 10.2 - Photo Denoising.ipynb ├── Lecture 10.3 - Mini Project #12 - Photo Restoration using inpainting.ipynb ├── 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 ├── Lecture 9.5 - Optical Flow Object Tracking.ipynb ├── Lecture 9.6 - Mini Project # 11 - Ball Tracking.ipynb ├── README.md └── images ├── 4star.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 ├── 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 /Lecture 10.3 - Mini Project #12 - Photo Restoration using inpainting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Photo Restoration using inpainting" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 14, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import cv2\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "\n", 22 | "# Load our damaged photo\n", 23 | "image = cv2.imread('images/abraham.jpg')\n", 24 | "cv2.imshow('Original Damaged Photo', image)\n", 25 | "cv2.waitKey(0)\n", 26 | "\n", 27 | "# Load the photo where we've marked the damaged areas\n", 28 | "marked_damages = cv2.imread('images/mask.jpg', 0)\n", 29 | "cv2.imshow('Marked Damages', marked_damages)\n", 30 | "cv2.waitKey(0)\n", 31 | "\n", 32 | "# Let's make a mask out of our marked image be changing all colors \n", 33 | "# that are not white, to black\n", 34 | "ret, thresh1 = cv2.threshold(marked_damages, 254, 255, cv2.THRESH_BINARY)\n", 35 | "cv2.imshow('Threshold Binary', thresh1)\n", 36 | "cv2.waitKey(0)\n", 37 | "\n", 38 | "# Let's dilate (make thicker) our the marks w made\n", 39 | "# since thresholding has narrowed it slightly\n", 40 | "kernel = np.ones((7,7), np.uint8)\n", 41 | "mask = cv2.dilate(thresh1, kernel, iterations = 1)\n", 42 | "cv2.imshow('Dilated Mask', mask)\n", 43 | "cv2.imwrite(\"images/abraham_mask.png\", mask)\n", 44 | "\n", 45 | "cv2.waitKey(0)\n", 46 | "restored = cv2.inpaint(image, mask, 3, cv2.INPAINT_TELEA)\n", 47 | "\n", 48 | "cv2.imshow('Restored', restored)\n", 49 | "cv2.waitKey(0)\n", 50 | "cv2.destroyAllWindows()\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [], 60 | "source": [] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "**Inpainting** is the process of reconstructing lost or deteriorated parts of images and videos. It is an advanced form of interpolation that can be used to replace lost or corrupted parts of the image data." 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "**cv2.inpaint**(input image, mask, inpaintRadius, Inpaint Method)\n", 74 | "\n", 75 | "**inpaintRadius** – Radius of a circular neighborhood of each point inpainted that is considered by the algorithm. Smaller values look less blurred, while larger values look more pixelated or blurred. \n", 76 | "\n", 77 | "**Inpaint Methods**\n", 78 | "- INPAINT_NS - Navier-Stokes based method [Navier01]\n", 79 | "- INPAINT_TELEA - Method by Alexandru Telea [Telea04] - Better as it integrates more seamlessley into the image." 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": { 86 | "collapsed": true 87 | }, 88 | "outputs": [], 89 | "source": [] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": { 95 | "collapsed": true 96 | }, 97 | "outputs": [], 98 | "source": [] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": "Python 2", 104 | "language": "python", 105 | "name": "python2" 106 | }, 107 | "language_info": { 108 | "codemirror_mode": { 109 | "name": "ipython", 110 | "version": 2 111 | }, 112 | "file_extension": ".py", 113 | "mimetype": "text/x-python", 114 | "name": "python", 115 | "nbconvert_exporter": "python", 116 | "pygments_lexer": "ipython2", 117 | "version": "2.7.11" 118 | } 119 | }, 120 | "nbformat": 4, 121 | "nbformat_minor": 0 122 | } 123 | -------------------------------------------------------------------------------- /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 | "outputs": [], 24 | "source": [ 25 | "# Press CTRL + ENTER to run this line\n", 26 | "# You should see an * between the [ ] on the left\n", 27 | "# OpenCV takes a couple seconds to import the first time\n", 28 | "\n", 29 | "import cv2" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": { 36 | "collapsed": true 37 | }, 38 | "outputs": [], 39 | "source": [] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": { 45 | "collapsed": true 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "# Now let's import numpy\n", 50 | "# We use as np, so that everything we call on numpy, we can type np instead\n", 51 | "# It's short and looks neater\n", 52 | "\n", 53 | "import numpy as np " 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "Let's now load our first image" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 2, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "# We don't need to do this again, but it's a good habit\n", 70 | "import cv2 \n", 71 | "\n", 72 | "# Load an image using 'imread' specifying the path to image\n", 73 | "input = cv2.imread('./images/input.jpg')\n", 74 | "\n", 75 | "# Our file 'input.jpg' is now loaded and stored in python \n", 76 | "# as a varaible we named 'image'\n", 77 | "\n", 78 | "# To display our image variable, we use 'imshow'\n", 79 | "# The first parameter will be title shown on image window\n", 80 | "# The second parameter is the image varialbe\n", 81 | "cv2.imshow('Hello World', input)\n", 82 | "\n", 83 | "# 'waitKey' allows us to input information when a image window is open\n", 84 | "# By leaving it blank it just waits for anykey to be pressed before \n", 85 | "# continuing. By placing numbers (except 0), we can specify a delay for\n", 86 | "# how long you keep the window open (time is in milliseconds here)\n", 87 | "cv2.waitKey()\n", 88 | "\n", 89 | "# This closes all open windows \n", 90 | "# Failure to place this will cause your program to hang\n", 91 | "cv2.destroyAllWindows()" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 3, 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "# Same as above without the extraneous comments\n", 101 | "\n", 102 | "import cv2 \n", 103 | "\n", 104 | "input = cv2.imread('./images/input.jpg')\n", 105 | "\n", 106 | "cv2.imshow('Hello World', input)\n", 107 | "cv2.waitKey(0)\n", 108 | "cv2.destroyAllWindows()" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 4, 114 | "metadata": {}, 115 | "outputs": [ 116 | { 117 | "ename": "TabError", 118 | "evalue": "inconsistent use of tabs and spaces in indentation (, line 6)", 119 | "output_type": "error", 120 | "traceback": [ 121 | "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m6\u001b[0m\n\u001b[1;33m min_rect=cv2.minAreaRect(cnt)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mTabError\u001b[0m\u001b[1;31m:\u001b[0m inconsistent use of tabs and spaces in indentation\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "def cleanAndRead(img,contours):\n", 127 | " text=\"\"\n", 128 | "\t#count=0\n", 129 | " \n", 130 | " for i,cnt in enumerate(contours): \n", 131 | "\t\tmin_rect=cv2.minAreaRect(cnt)\n", 132 | " \n", 133 | "\t\tif validateRotationAndRatio(min_rect):\n", 134 | "\n", 135 | "\t\t\tx,y,w,h=cv2.boundingRect(cnt)\n", 136 | "\t\t\tplate_img=img[y:y+h,x:x+w]\n", 137 | "\n", 138 | "\n", 139 | "\t\t\tif(isMaxWhite(plate_img)):\n", 140 | "\t\t\t\t#count+=1\n", 141 | "\t\t\t\tclean_plate, rect = cleanPlate(plate_img)\n", 142 | "\n", 143 | "\t\t\t\tif rect:\n", 144 | "\t\t\t\t\tx1,y1,w1,h1 = rect\n", 145 | "\t\t\t\t\tx,y,w,h = x+x1,y+y1,w1,h1\n", 146 | "\t\t\t\t\tplate_im = Image.fromarray(clean_plate)\n", 147 | "\t\t\t\t\ttext = tess.image_to_string(plate_im, lang='eng')\n", 148 | "\t\t\t\t\tprint(\"Detected Text : \",text)\n", 149 | " return text" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "### Let's take a closer look at how images are stored" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 16, 162 | "metadata": { 163 | "collapsed": true 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "# Import numpy\n", 168 | "import numpy as np" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 15, 174 | "metadata": {}, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "(830L, 1245L, 3L)\n" 181 | ] 182 | } 183 | ], 184 | "source": [ 185 | "print input.shape" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "#### Shape gives the dimensions of the image array\n", 193 | "\n", 194 | "The 2D dimensions are 830 pixels in high bv 1245 pixels wide.\n", 195 | "The '3L' means that there are 3 other components (RGB) that make up this image." 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 17, 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "name": "stdout", 205 | "output_type": "stream", 206 | "text": [ 207 | "Height of Image: 830 pixels\n", 208 | "Width of Image: 1245 pixels\n" 209 | ] 210 | } 211 | ], 212 | "source": [ 213 | "# Let's print each dimension of the image\n", 214 | "\n", 215 | "print 'Height of Image:', int(input.shape[0]), 'pixels'\n", 216 | "print 'Width of Image: ', int(input.shape[1]), 'pixels'" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "### How do we save images we edit in OpenCV?" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 18, 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "data": { 233 | "text/plain": [ 234 | "True" 235 | ] 236 | }, 237 | "execution_count": 18, 238 | "metadata": {}, 239 | "output_type": "execute_result" 240 | } 241 | ], 242 | "source": [ 243 | "# Simply use 'imwrite' specificing the file name and the image to be saved\n", 244 | "cv2.imwrite('output.jpg', input)\n", 245 | "cv2.imwrite('output.png', input)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "metadata": { 252 | "collapsed": true 253 | }, 254 | "outputs": [], 255 | "source": [] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "metadata": { 261 | "collapsed": true 262 | }, 263 | "outputs": [], 264 | "source": [] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "metadata": { 270 | "collapsed": true 271 | }, 272 | "outputs": [], 273 | "source": [] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "metadata": { 279 | "collapsed": true 280 | }, 281 | "outputs": [], 282 | "source": [] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "metadata": { 288 | "collapsed": true 289 | }, 290 | "outputs": [], 291 | "source": [] 292 | } 293 | ], 294 | "metadata": { 295 | "kernelspec": { 296 | "display_name": "Python 3", 297 | "language": "python", 298 | "name": "python3" 299 | }, 300 | "language_info": { 301 | "codemirror_mode": { 302 | "name": "ipython", 303 | "version": 3 304 | }, 305 | "file_extension": ".py", 306 | "mimetype": "text/x-python", 307 | "name": "python", 308 | "nbconvert_exporter": "python", 309 | "pygments_lexer": "ipython3", 310 | "version": "3.6.6" 311 | } 312 | }, 313 | "nbformat": 4, 314 | "nbformat_minor": 1 315 | } 316 | -------------------------------------------------------------------------------- /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 | "outputs": [], 21 | "source": [ 22 | "import cv2\n", 23 | "\n", 24 | "# Load our input image\n", 25 | "image = cv2.imread('./images/input.jpg')\n", 26 | "cv2.imshow('Original', image)\n", 27 | "cv2.waitKey()\n", 28 | "\n", 29 | "# We use cvtColor, to convert to grayscale\n", 30 | "gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 31 | "\n", 32 | "cv2.imshow('Grayscale', gray_image)\n", 33 | "cv2.waitKey()\n", 34 | "cv2.destroyAllWindows()" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "#Another method faster method\n", 44 | "img = cv2.imread('./images/input.jpg',0)\n", 45 | "\n", 46 | "cv2.imshow('Grayscale', img)\n", 47 | "cv2.waitKey()\n", 48 | "cv2.destroyAllWindows()" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [] 55 | } 56 | ], 57 | "metadata": { 58 | "kernelspec": { 59 | "display_name": "Python 3", 60 | "language": "python", 61 | "name": "python3" 62 | }, 63 | "language_info": { 64 | "codemirror_mode": { 65 | "name": "ipython", 66 | "version": 3 67 | }, 68 | "file_extension": ".py", 69 | "mimetype": "text/x-python", 70 | "name": "python", 71 | "nbconvert_exporter": "python", 72 | "pygments_lexer": "ipython3", 73 | "version": "3.6.6" 74 | } 75 | }, 76 | "nbformat": 4, 77 | "nbformat_minor": 1 78 | } 79 | -------------------------------------------------------------------------------- /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": 5, 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": 7, 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": 8, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [ 103 | { 104 | "data": { 105 | "text/plain": [ 106 | "21" 107 | ] 108 | }, 109 | "execution_count": 8, 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": 11, 129 | "metadata": { 130 | "collapsed": true 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "#H: 0 - 180, S: 0 - 255, V: 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 | "cv2.imshow('Hue channel', hsv_image[:, :, 0])\n", 142 | "cv2.imshow('Saturation channel', hsv_image[:, :, 1])\n", 143 | "cv2.imshow('Value channel', hsv_image[:, :, 2])\n", 144 | "\n", 145 | "cv2.waitKey()\n", 146 | "cv2.destroyAllWindows()" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "### Let's now explore lookng at individual channels in an RGB image" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 12, 159 | "metadata": { 160 | "collapsed": false 161 | }, 162 | "outputs": [ 163 | { 164 | "name": "stdout", 165 | "output_type": "stream", 166 | "text": [ 167 | "(830L, 1245L)\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "image = cv2.imread('./images/input.jpg')\n", 173 | "\n", 174 | "# OpenCV's 'split' function splites the image into each color index\n", 175 | "B, G, R = cv2.split(image)\n", 176 | "\n", 177 | "print B.shape\n", 178 | "cv2.imshow(\"Red\", R)\n", 179 | "cv2.imshow(\"Green\", G)\n", 180 | "cv2.imshow(\"Blue\", B)\n", 181 | "cv2.waitKey(0)\n", 182 | "cv2.destroyAllWindows()\n", 183 | "\n", 184 | "# Let's re-make the original image, \n", 185 | "merged = cv2.merge([B, G, R]) \n", 186 | "cv2.imshow(\"Merged\", merged) \n", 187 | "\n", 188 | "# Let's amplify the blue color\n", 189 | "merged = cv2.merge([B+100, G, R])\n", 190 | "cv2.imshow(\"Merged with Blue Amplified\", merged) \n", 191 | "\n", 192 | "cv2.waitKey(0)\n", 193 | "cv2.destroyAllWindows()" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 20, 199 | "metadata": { 200 | "collapsed": false 201 | }, 202 | "outputs": [], 203 | "source": [ 204 | "import cv2\n", 205 | "import numpy as np\n", 206 | "\n", 207 | "B, G, R = cv2.split(image)\n", 208 | "\n", 209 | "# Let's create a matrix of zeros \n", 210 | "# with dimensions of the image h x w \n", 211 | "zeros = np.zeros(image.shape[:2], dtype = \"uint8\")\n", 212 | "\n", 213 | "cv2.imshow(\"Red\", cv2.merge([zeros, zeros, R]))\n", 214 | "cv2.imshow(\"Green\", cv2.merge([zeros, G, zeros]))\n", 215 | "cv2.imshow(\"Blue\", cv2.merge([B, zeros, zeros]))\n", 216 | "\n", 217 | "cv2.waitKey(0)\n", 218 | "cv2.destroyAllWindows()" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 19, 224 | "metadata": { 225 | "collapsed": false 226 | }, 227 | "outputs": [ 228 | { 229 | "data": { 230 | "text/plain": [ 231 | "(830L, 1245L)" 232 | ] 233 | }, 234 | "execution_count": 19, 235 | "metadata": {}, 236 | "output_type": "execute_result" 237 | } 238 | ], 239 | "source": [ 240 | "image.shape[:2]" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "#### You can view a list of color converisons here, but keep in mind you won't ever use or need many of these\n", 248 | "\n", 249 | "http://docs.opencv.org/trunk/d7/d1b/group__imgproc__misc.html#ga4e0972be5de079fed4e3a10e24ef5ef0" 250 | ] 251 | } 252 | ], 253 | "metadata": { 254 | "kernelspec": { 255 | "display_name": "Python 2", 256 | "language": "python", 257 | "name": "python2" 258 | }, 259 | "language_info": { 260 | "codemirror_mode": { 261 | "name": "ipython", 262 | "version": 2 263 | }, 264 | "file_extension": ".py", 265 | "mimetype": "text/x-python", 266 | "name": "python", 267 | "nbconvert_exporter": "python", 268 | "pygments_lexer": "ipython2", 269 | "version": "2.7.11" 270 | } 271 | }, 272 | "nbformat": 4, 273 | "nbformat_minor": 0 274 | } 275 | -------------------------------------------------------------------------------- /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": 22, 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 | "image = np.zeros((512,512,3), np.uint8)\n", 25 | "\n", 26 | "# Can we make this in black and white?\n", 27 | "image_bw = np.zeros((512,512), np.uint8)\n", 28 | "\n", 29 | "cv2.imshow(\"Black Rectangle (Color)\", image)\n", 30 | "cv2.imshow(\"Black Rectangle (B&W)\", image_bw)\n", 31 | "\n", 32 | "cv2.waitKey(0)\n", 33 | "cv2.destroyAllWindows()" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "### Let's draw a line over our black sqare\n", 41 | "\n", 42 | "cv2.line(image, starting cordinates, ending cordinates, color, thickness)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 23, 48 | "metadata": { 49 | "collapsed": true 50 | }, 51 | "outputs": [], 52 | "source": [ 53 | "# Draw a diagonal blue line of thickness of 5 pixels\n", 54 | "image = np.zeros((512,512,3), np.uint8)\n", 55 | "cv2.line(image, (0,0), (511,511), (255,127,0), 5)\n", 56 | "cv2.imshow(\"Blue Line\", image)\n", 57 | "\n", 58 | "cv2.waitKey(0)\n", 59 | "cv2.destroyAllWindows()" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### Let's now draw a rectangle\n", 67 | "\n", 68 | "cv2.rectangle(image, starting vertex, opposite vertex, color, thickness)" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 25, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "# Draw a Rectangle in\n", 80 | "image = np.zeros((512,512,3), np.uint8)\n", 81 | "\n", 82 | "cv2.rectangle(image, (100,100), (300,250), (127,50,127), -1)\n", 83 | "cv2.imshow(\"Rectangle\", image)\n", 84 | "cv2.waitKey(0)\n", 85 | "cv2.destroyAllWindows()" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### How about cirlcles?\n", 93 | "\n", 94 | "cv2.cirlce(image, center, radius, color, fill)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 26, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "image = np.zeros((512,512,3), np.uint8)\n", 106 | "\n", 107 | "cv2.circle(image, (350, 350), 100, (15,75,50), -1) \n", 108 | "cv2.imshow(\"Circle\", image)\n", 109 | "cv2.waitKey(0)\n", 110 | "cv2.destroyAllWindows()" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "## And polygons?" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 27, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [], 127 | "source": [ 128 | "image = np.zeros((512,512,3), np.uint8)\n", 129 | "\n", 130 | "# Let's define four points\n", 131 | "pts = np.array( [[10,50], [400,50], [90,200], [50,500]], np.int32)\n", 132 | "\n", 133 | "# Let's now reshape our points in form required by polylines\n", 134 | "pts = pts.reshape((-1,1,2))\n", 135 | "\n", 136 | "cv2.polylines(image, [pts], True, (0,0,255), 3)\n", 137 | "cv2.imshow(\"Polygon\", image)\n", 138 | "cv2.waitKey(0)\n", 139 | "cv2.destroyAllWindows()" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "### Let's even add text with cv2.putText\n", 147 | "\n", 148 | "cv2.putText(image, 'Text to Display', bottom left starting point, Font, Font Size, Color, Thickness)\n", 149 | "\n", 150 | "- FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN\n", 151 | "- FONT_HERSHEY_DUPLEX,FONT_HERSHEY_COMPLEX \n", 152 | "- FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL\n", 153 | "- FONT_HERSHEY_SCRIPT_SIMPLEX\n", 154 | "- FONT_HERSHEY_SCRIPT_COMPLEX" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 28, 160 | "metadata": { 161 | "collapsed": false 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "image = np.zeros((512,512,3), np.uint8)\n", 166 | "\n", 167 | "cv2.putText(image, 'Hello World!', (75,290), cv2.FONT_HERSHEY_COMPLEX, 2, (100,170,0), 3)\n", 168 | "cv2.imshow(\"Hello World!\", image)\n", 169 | "cv2.waitKey(0)\n", 170 | "cv2.destroyAllWindows()" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": { 177 | "collapsed": true 178 | }, 179 | "outputs": [], 180 | "source": [] 181 | } 182 | ], 183 | "metadata": { 184 | "kernelspec": { 185 | "display_name": "Python 2", 186 | "language": "python", 187 | "name": "python2" 188 | }, 189 | "language_info": { 190 | "codemirror_mode": { 191 | "name": "ipython", 192 | "version": 2 193 | }, 194 | "file_extension": ".py", 195 | "mimetype": "text/x-python", 196 | "name": "python", 197 | "nbconvert_exporter": "python", 198 | "pygments_lexer": "ipython2", 199 | "version": "2.7.11" 200 | } 201 | }, 202 | "nbformat": 4, 203 | "nbformat_minor": 0 204 | } 205 | -------------------------------------------------------------------------------- /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": null, 44 | "metadata": { 45 | "collapsed": false 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.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 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "\n", 20 | "\n", 21 | "\n", 22 | "\n", 23 | "\n", 24 | "\n", 25 | "\n", 26 | "\n", 27 | "\n", 28 | "\n", 29 | "\n", 30 | "\n", 31 | "\n", 32 | "\n", 33 | "\n", 34 | "\n", 35 | "\n", 36 | "\n", 37 | "\n", 38 | "\n", 39 | "\n", 40 | "\n", 41 | "\n", 42 | "\n", 43 | "\n", 44 | "\n", 45 | "\n", 46 | "\n", 47 | "\n", 48 | "\n", 49 | "\n", 50 | "\n", 51 | "\n", 52 | "\n", 53 | "\n", 54 | "\n", 55 | "\n", 56 | "\n", 57 | "\n", 58 | "\n", 59 | "\n", 60 | "\n", 61 | "\n", 62 | "\n", 63 | "\n", 64 | "\n", 65 | "\n", 66 | "\n", 67 | "\n", 68 | "\n", 69 | "\n", 70 | "\n", 71 | "\n", 72 | "\n", 73 | "\n", 74 | "\n", 75 | "\n", 76 | "\n", 77 | "\n", 78 | "\n", 79 | "\n", 80 | "\n", 81 | "\n", 82 | "\n", 83 | "\n", 84 | "\n", 85 | "\n", 86 | "\n", 87 | "\n", 88 | "\n", 89 | "\n", 90 | "\n", 91 | "\n", 92 | "\n", 93 | "\n", 94 | "\n", 95 | "\n", 96 | "\n", 97 | "\n", 98 | "\n", 99 | "\n", 100 | "\n", 101 | "\n", 102 | "\n", 103 | "\n", 104 | "\n", 105 | "\n", 106 | "\n", 107 | "\n", 108 | "\n", 109 | "\n", 110 | "\n", 111 | "\n", 112 | "\n", 113 | "\n", 114 | "\n", 115 | "\n", 116 | "\n", 117 | "\n", 118 | "\n", 119 | "\n", 120 | "\n", 121 | "\n", 122 | "\n", 123 | "\n", 124 | "\n", 125 | "\n", 126 | "\n", 127 | "\n", 128 | "\n", 129 | "\n", 130 | "\n", 131 | "\n", 132 | "\n", 133 | "\n", 134 | "\n", 135 | "\n", 136 | "\n", 137 | "\n", 138 | "\n", 139 | "\n", 140 | "\n", 141 | "\n", 142 | "\n", 143 | "\n", 144 | "\n", 145 | "\n" 146 | ] 147 | } 148 | ], 149 | "source": [ 150 | "import cv2\n", 151 | "import numpy as np\n", 152 | "\n", 153 | "# Our sketch generating function\n", 154 | "def sketch(image):\n", 155 | " # Convert image to grayscale\n", 156 | " img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 157 | " \n", 158 | " # Clean up image using Guassian Blur\n", 159 | " img_gray_blur = cv2.GaussianBlur(img_gray, (5,5), 0)\n", 160 | " \n", 161 | " # Extract edges\n", 162 | " canny_edges = cv2.Canny(img_gray_blur, 10, 70)\n", 163 | " \n", 164 | " # Do an invert binarize the image \n", 165 | " ret, mask = cv2.threshold(canny_edges, 70, 255, cv2.THRESH_BINARY_INV)\n", 166 | " print(type(mask))\n", 167 | " return mask\n", 168 | "\n", 169 | "\n", 170 | "# Initialize webcam, cap is the object provided by VideoCapture\n", 171 | "# It contains a boolean indicating if it was sucessful (ret)\n", 172 | "# It also contains the images collected from the webcam (frame)\n", 173 | "cap = cv2.VideoCapture(0)\n", 174 | "\n", 175 | "while True:\n", 176 | " ret, frame = cap.read()\n", 177 | " cv2.imshow('Our Live Sketcher', sketch(frame))\n", 178 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 179 | " break\n", 180 | " \n", 181 | "# Release camera and close windows\n", 182 | "cap.release()\n", 183 | "cv2.destroyAllWindows() " 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "collapsed": true 191 | }, 192 | "outputs": [], 193 | "source": [] 194 | } 195 | ], 196 | "metadata": { 197 | "kernelspec": { 198 | "display_name": "Python 3", 199 | "language": "python", 200 | "name": "python3" 201 | }, 202 | "language_info": { 203 | "codemirror_mode": { 204 | "name": "ipython", 205 | "version": 3 206 | }, 207 | "file_extension": ".py", 208 | "mimetype": "text/x-python", 209 | "name": "python", 210 | "nbconvert_exporter": "python", 211 | "pygments_lexer": "ipython3", 212 | "version": "3.5.6" 213 | }, 214 | "widgets": { 215 | "state": {}, 216 | "version": "1.1.2" 217 | } 218 | }, 219 | "nbformat": 4, 220 | "nbformat_minor": 1 221 | } 222 | -------------------------------------------------------------------------------- /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": 1, 17 | "metadata": {}, 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 | "\n", 25 | "# Store height and width of the image\n", 26 | "height, width = image.shape[:2]\n", 27 | "\n", 28 | "quarter_height, quarter_width = height/4, width/4\n", 29 | "\n", 30 | "# | 1 0 Tx |\n", 31 | "# T = | 0 1 Ty |\n", 32 | "\n", 33 | "# T is our translation matrix\n", 34 | "T = np.float32([[1, 0, quarter_width], [0, 1,quarter_height]])\n", 35 | "\n", 36 | "# We use warpAffine to transform the image using the matrix, T\n", 37 | "img_translation = cv2.warpAffine(image, T, (width, height))\n", 38 | "cv2.imshow('Translation', img_translation)\n", 39 | "cv2.waitKey()\n", 40 | "cv2.destroyAllWindows()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "data": { 50 | "text/plain": [ 51 | "(830, 1245, 3)" 52 | ] 53 | }, 54 | "execution_count": 2, 55 | "metadata": {}, 56 | "output_type": "execute_result" 57 | } 58 | ], 59 | "source": [ 60 | "image.shape" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "[[ 1. 0. 311.]\n", 73 | " [ 0. 1. 207.]]\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "# Let's take a look at T\n", 79 | "\n", 80 | "print T" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": { 87 | "collapsed": true 88 | }, 89 | "outputs": [], 90 | "source": [] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": { 96 | "collapsed": true 97 | }, 98 | "outputs": [], 99 | "source": [] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": { 105 | "collapsed": true 106 | }, 107 | "outputs": [], 108 | "source": [] 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": "code", 121 | "execution_count": null, 122 | "metadata": { 123 | "collapsed": true 124 | }, 125 | "outputs": [], 126 | "source": [] 127 | } 128 | ], 129 | "metadata": { 130 | "kernelspec": { 131 | "display_name": "Python 3", 132 | "language": "python", 133 | "name": "python3" 134 | }, 135 | "language_info": { 136 | "codemirror_mode": { 137 | "name": "ipython", 138 | "version": 3 139 | }, 140 | "file_extension": ".py", 141 | "mimetype": "text/x-python", 142 | "name": "python", 143 | "nbconvert_exporter": "python", 144 | "pygments_lexer": "ipython3", 145 | "version": "3.5.6" 146 | }, 147 | "widgets": { 148 | "state": {}, 149 | "version": "1.1.2" 150 | } 151 | }, 152 | "nbformat": 4, 153 | "nbformat_minor": 1 154 | } 155 | -------------------------------------------------------------------------------- /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": 4, 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": 6, 50 | "metadata": { 51 | "collapsed": true 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": null, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 7, 77 | "metadata": { 78 | "collapsed": true 79 | }, 80 | "outputs": [], 81 | "source": [ 82 | "# Let's now to a horizontal flip.\n", 83 | "flipped = cv2.flip(image, 1)\n", 84 | "cv2.imshow('Horizontal Flip', flipped) \n", 85 | "cv2.waitKey()\n", 86 | "cv2.destroyAllWindows()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": { 93 | "collapsed": true 94 | }, 95 | "outputs": [], 96 | "source": [] 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 2", 111 | "language": "python", 112 | "name": "python2" 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.11" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 0 129 | } 130 | -------------------------------------------------------------------------------- /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 | "kernelspec": { 67 | "display_name": "Python 2", 68 | "language": "python", 69 | "name": "python2" 70 | }, 71 | "language_info": { 72 | "codemirror_mode": { 73 | "name": "ipython", 74 | "version": 2 75 | }, 76 | "file_extension": ".py", 77 | "mimetype": "text/x-python", 78 | "name": "python", 79 | "nbconvert_exporter": "python", 80 | "pygments_lexer": "ipython2", 81 | "version": "2.7.11" 82 | } 83 | }, 84 | "nbformat": 4, 85 | "nbformat_minor": 0 86 | } 87 | -------------------------------------------------------------------------------- /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": 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/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 | "\n", 40 | "cv2.destroyAllWindows()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": { 47 | "collapsed": true 48 | }, 49 | "outputs": [], 50 | "source": [] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### Other commonly used blurring methods in OpenCV" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 5, 62 | "metadata": { 63 | "collapsed": false 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "import cv2\n", 68 | "import numpy as np\n", 69 | "\n", 70 | "image = cv2.imread('images/elephant.jpg')\n", 71 | "\n", 72 | "# Averaging done by convolving the image with a normalized box filter. \n", 73 | "# This takes the pixels under the box and replaces the central element\n", 74 | "# Box size needs to odd and positive \n", 75 | "blur = cv2.blur(image, (3,3))\n", 76 | "cv2.imshow('Averaging', blur)\n", 77 | "cv2.waitKey(0)\n", 78 | "\n", 79 | "# Instead of box filter, gaussian kernel\n", 80 | "Gaussian = cv2.GaussianBlur(image, (7,7), 0)\n", 81 | "cv2.imshow('Gaussian Blurring', Gaussian)\n", 82 | "cv2.waitKey(0)\n", 83 | "\n", 84 | "# Takes median of all the pixels under kernel area and central \n", 85 | "# element is replaced with this median value\n", 86 | "median = cv2.medianBlur(image, 5)\n", 87 | "cv2.imshow('Median Blurring', median)\n", 88 | "cv2.waitKey(0)\n", 89 | "\n", 90 | "# Bilateral is very effective in noise removal while keeping edges sharp\n", 91 | "bilateral = cv2.bilateralFilter(image, 9, 75, 75)\n", 92 | "cv2.imshow('Bilateral Blurring', bilateral)\n", 93 | "cv2.waitKey(0)\n", 94 | "cv2.destroyAllWindows()" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "## Image De-noising - Non-Local Means Denoising" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [ 112 | "import numpy as np\n", 113 | "import cv2\n", 114 | "\n", 115 | "image = cv2.imread('images/elephant.jpg')\n", 116 | "\n", 117 | "# Parameters, after None are - the filter strength 'h' (5-10 is a good range)\n", 118 | "# Next is hForColorComponents, set as same value as h again\n", 119 | "# \n", 120 | "dst = cv2.fastNlMeansDenoisingColored(image, None, 6, 6, 7, 21)\n", 121 | "\n", 122 | "cv2.imshow('Fast Means Denoising', dst)\n", 123 | "cv2.waitKey(0)\n", 124 | "\n", 125 | "cv2.destroyAllWindows()" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "**There are 4 variations of Non-Local Means Denoising:**\n", 133 | "\n", 134 | "- cv2.fastNlMeansDenoising() - works with a single grayscale images\n", 135 | "- cv2.fastNlMeansDenoisingColored() - works with a color image.\n", 136 | "- cv2.fastNlMeansDenoisingMulti() - works with image sequence captured in short period of time (grayscale images)\n", 137 | "- cv2.fastNlMeansDenoisingColoredMulti() - same as above, but for color images." 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": { 144 | "collapsed": true 145 | }, 146 | "outputs": [], 147 | "source": [] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": { 153 | "collapsed": true 154 | }, 155 | "outputs": [], 156 | "source": [] 157 | } 158 | ], 159 | "metadata": { 160 | "kernelspec": { 161 | "display_name": "Python 2", 162 | "language": "python", 163 | "name": "python2" 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.11" 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": 12, 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 | "kernelspec": { 107 | "display_name": "Python 2", 108 | "language": "python", 109 | "name": "python2" 110 | }, 111 | "language_info": { 112 | "codemirror_mode": { 113 | "name": "ipython", 114 | "version": 2 115 | }, 116 | "file_extension": ".py", 117 | "mimetype": "text/x-python", 118 | "name": "python", 119 | "nbconvert_exporter": "python", 120 | "pygments_lexer": "ipython2", 121 | "version": "2.7.11" 122 | } 123 | }, 124 | "nbformat": 4, 125 | "nbformat_minor": 0 126 | } 127 | -------------------------------------------------------------------------------- /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": 9, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "('Number of contours found = ', 4)\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "import cv2\n", 29 | "import numpy as np\n", 30 | "\n", 31 | "# Load our image\n", 32 | "image = cv2.imread('images/bunchofshapes.jpg')\n", 33 | "cv2.imshow('0 - Original Image', image)\n", 34 | "cv2.waitKey(0)\n", 35 | "\n", 36 | "# Create a black image with same dimensions as our loaded image\n", 37 | "blank_image = np.zeros((image.shape[0], image.shape[1], 3))\n", 38 | "\n", 39 | "# Create a copy of our original image\n", 40 | "orginal_image = image\n", 41 | "\n", 42 | "# Grayscale our image\n", 43 | "gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n", 44 | "\n", 45 | "# Find Canny edges\n", 46 | "edged = cv2.Canny(gray, 50, 200)\n", 47 | "cv2.imshow('1 - Canny Edges', edged)\n", 48 | "cv2.waitKey(0)\n", 49 | "\n", 50 | "# Find contours and print how many were found\n", 51 | "contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", 52 | "print (\"Number of contours found = \", len(contours))\n", 53 | "\n", 54 | "#Draw all contours\n", 55 | "cv2.drawContours(blank_image, contours, -1, (0,255,0), 3)\n", 56 | "cv2.imshow('2 - All Contours over blank image', blank_image)\n", 57 | "cv2.waitKey(0)\n", 58 | "\n", 59 | "# Draw all contours over blank image\n", 60 | "cv2.drawContours(image, contours, -1, (0,255,0), 3)\n", 61 | "cv2.imshow('3 - All Contours', image)\n", 62 | "cv2.waitKey(0)\n", 63 | "\n", 64 | "cv2.destroyAllWindows()" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### Let's now sort by area" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 11, 77 | "metadata": { 78 | "collapsed": false 79 | }, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "Contor Areas before sorting [20587.5, 22901.5, 66579.5, 90222.0]\n", 86 | "Contor Areas after sorting [90222.0, 66579.5, 22901.5, 20587.5]\n" 87 | ] 88 | } 89 | ], 90 | "source": [ 91 | "import cv2\n", 92 | "import numpy as np\n", 93 | "\n", 94 | "# Function we'll use to display contour area\n", 95 | "\n", 96 | "def get_contour_areas(contours):\n", 97 | " # returns the areas of all contours as list\n", 98 | " all_areas = []\n", 99 | " for cnt in contours:\n", 100 | " area = cv2.contourArea(cnt)\n", 101 | " all_areas.append(area)\n", 102 | " return all_areas\n", 103 | "\n", 104 | "# Load our image\n", 105 | "image = cv2.imread('images/bunchofshapes.jpg')\n", 106 | "orginal_image = image\n", 107 | "\n", 108 | "# Let's print the areas of the contours before sorting\n", 109 | "print \"Contor Areas before sorting\", \n", 110 | "print get_contour_areas(contours)\n", 111 | "\n", 112 | "# Sort contours large to small\n", 113 | "sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)\n", 114 | "#sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)[:3]\n", 115 | "\n", 116 | "print \"Contor Areas after sorting\", \n", 117 | "print get_contour_areas(sorted_contours)\n", 118 | "\n", 119 | "# Iterate over our contours and draw one at a time\n", 120 | "for c in sorted_contours:\n", 121 | " cv2.drawContours(orginal_image, [c], -1, (255,0,0), 3)\n", 122 | " cv2.waitKey(0)\n", 123 | " cv2.imshow('Contours by area', orginal_image)\n", 124 | "\n", 125 | "cv2.waitKey(0)\n", 126 | "cv2.destroyAllWindows()" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 14, 132 | "metadata": { 133 | "collapsed": false 134 | }, 135 | "outputs": [ 136 | { 137 | "name": "stdout", 138 | "output_type": "stream", 139 | "text": [ 140 | "output_shape_number_1.jpg\n", 141 | "output_shape_number_2.jpg\n", 142 | "output_shape_number_3.jpg\n", 143 | "output_shape_number_4.jpg\n" 144 | ] 145 | } 146 | ], 147 | "source": [ 148 | "import cv2\n", 149 | "import numpy as np\n", 150 | "\n", 151 | "# Functions we'll use for sorting by position\n", 152 | "\n", 153 | "def x_cord_contour(contours):\n", 154 | " #Returns the X cordinate for the contour centroid\n", 155 | " if cv2.contourArea(contours) > 10:\n", 156 | " M = cv2.moments(contours)\n", 157 | " return (int(M['m10']/M['m00']))\n", 158 | " else:\n", 159 | " pass\n", 160 | "\n", 161 | " \n", 162 | "def label_contour_center(image, c):\n", 163 | " # Places a red circle on the centers of contours\n", 164 | " M = cv2.moments(c)\n", 165 | " cx = int(M['m10'] / M['m00'])\n", 166 | " cy = int(M['m01'] / M['m00'])\n", 167 | " \n", 168 | " # Draw the countour number on the image\n", 169 | " cv2.circle(image,(cx,cy), 10, (0,0,255), -1)\n", 170 | " return image\n", 171 | "\n", 172 | "\n", 173 | "# Load our image\n", 174 | "image = cv2.imread('images/bunchofshapes.jpg')\n", 175 | "orginal_image = image.copy()\n", 176 | "\n", 177 | "\n", 178 | "# Computer Center of Mass or centroids and draw them on our image\n", 179 | "for (i, c) in enumerate(contours):\n", 180 | " orig = label_contour_center(image, c)\n", 181 | " \n", 182 | "cv2.imshow(\"4 - Contour Centers \", image)\n", 183 | "cv2.waitKey(0)\n", 184 | "\n", 185 | "# Sort by left to right using our x_cord_contour function\n", 186 | "contours_left_to_right = sorted(contours, key = x_cord_contour, reverse = False)\n", 187 | "\n", 188 | "\n", 189 | "# Labeling Contours left to right\n", 190 | "for (i,c) in enumerate(contours_left_to_right):\n", 191 | " cv2.drawContours(orginal_image, [c], -1, (0,0,255), 3) \n", 192 | " M = cv2.moments(c)\n", 193 | " cx = int(M['m10'] / M['m00'])\n", 194 | " cy = int(M['m01'] / M['m00'])\n", 195 | " cv2.putText(orginal_image, str(i+1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)\n", 196 | " cv2.imshow('6 - Left to Right Contour', orginal_image)\n", 197 | " cv2.waitKey(0)\n", 198 | " (x, y, w, h) = cv2.boundingRect(c) \n", 199 | " \n", 200 | " # Let's now crop each contour and save these images\n", 201 | " cropped_contour = orginal_image[y:y + h, x:x + w]\n", 202 | " image_name = \"output_shape_number_\" + str(i+1) + \".jpg\"\n", 203 | " print image_name\n", 204 | " cv2.imwrite(image_name, cropped_contour)\n", 205 | " \n", 206 | "cv2.destroyAllWindows()\n", 207 | "\n", 208 | "\n" 209 | ] 210 | } 211 | ], 212 | "metadata": { 213 | "kernelspec": { 214 | "display_name": "Python 2", 215 | "language": "python", 216 | "name": "python2" 217 | }, 218 | "language_info": { 219 | "codemirror_mode": { 220 | "name": "ipython", 221 | "version": 2 222 | }, 223 | "file_extension": ".py", 224 | "mimetype": "text/x-python", 225 | "name": "python", 226 | "nbconvert_exporter": "python", 227 | "pygments_lexer": "ipython2", 228 | "version": "2.7.13" 229 | } 230 | }, 231 | "nbformat": 4, 232 | "nbformat_minor": 0 233 | } 234 | -------------------------------------------------------------------------------- /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 | "kernelspec": { 116 | "display_name": "Python 2", 117 | "language": "python", 118 | "name": "python2" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 2 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython2", 130 | "version": "2.7.11" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 0 135 | } 136 | -------------------------------------------------------------------------------- /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": 5, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "0.130815629271\n", 36 | "0.159020053398\n", 37 | "0.149879156825\n", 38 | "0.0709403447448\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, 3, 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 2", 111 | "language": "python", 112 | "name": "python2" 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.11" 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": 13, 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 | "\n", 30 | "# Run HoughLines using a rho accuracy of 1 pixel\n", 31 | "# theta accuracy of np.pi / 180 which is 1 degree\n", 32 | "# Our line threshold is set to 240 (number of points on line)\n", 33 | "lines = cv2.HoughLines(edges, 1, np.pi / 180, 240)\n", 34 | "\n", 35 | "# We iterate through each line and convert it to the format\n", 36 | "# required by cv.lines (i.e. requiring end points)\n", 37 | "for rho, theta in lines[0]:\n", 38 | " a = np.cos(theta)\n", 39 | " b = np.sin(theta)\n", 40 | " x0 = a * rho\n", 41 | " y0 = b * rho\n", 42 | " x1 = int(x0 + 1000 * (-b))\n", 43 | " y1 = int(y0 + 1000 * (a))\n", 44 | " x2 = int(x0 - 1000 * (-b))\n", 45 | " y2 = int(y0 - 1000 * (a))\n", 46 | " cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)\n", 47 | "\n", 48 | "cv2.imshow('Hough Lines', image)\n", 49 | "cv2.waitKey(0)\n", 50 | "cv2.destroyAllWindows()" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "### Probabilistic Hough Lines\n", 58 | "\n", 59 | "**cv2.HoughLinesP(binarized image, 𝜌 accuracy, 𝜃 accuracy, threshold, minimum line length, max line gap)\n", 60 | "\n", 61 | "\n" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 19, 67 | "metadata": { 68 | "collapsed": false 69 | }, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "(1L, 167L, 4L)\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "import cv2\n", 81 | "import numpy as np\n", 82 | "\n", 83 | "# Grayscale and Canny Edges extracted\n", 84 | "image = cv2.imread('images/soduku.jpg')\n", 85 | "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", 86 | "edges = cv2.Canny(gray, 100, 170, apertureSize = 3)\n", 87 | "\n", 88 | "# Again we use the same rho and theta accuracies\n", 89 | "# However, we specific a minimum vote (pts along line) of 100\n", 90 | "# and Min line length of 5 pixels and max gap between lines of 10 pixels\n", 91 | "lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 200, 5, 10)\n", 92 | "print lines.shape\n", 93 | "\n", 94 | "for x1, y1, x2, y2 in lines[0]:\n", 95 | " cv2.line(image, (x1, y1), (x2, y2),(0, 255, 0), 3)\n", 96 | "\n", 97 | "cv2.imshow('Probabilistic Hough Lines', image)\n", 98 | "cv2.waitKey(0)\n", 99 | "cv2.destroyAllWindows()" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "http://cmp.felk.cvut.cz/~matas/papers/matas-bmvc98.pdf" 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": "markdown", 120 | "metadata": { 121 | "collapsed": false 122 | }, 123 | "source": [ 124 | "\n", 125 | "\n" 126 | ] 127 | } 128 | ], 129 | "metadata": { 130 | "kernelspec": { 131 | "display_name": "Python 2", 132 | "language": "python", 133 | "name": "python2" 134 | }, 135 | "language_info": { 136 | "codemirror_mode": { 137 | "name": "ipython", 138 | "version": 2 139 | }, 140 | "file_extension": ".py", 141 | "mimetype": "text/x-python", 142 | "name": "python", 143 | "nbconvert_exporter": "python", 144 | "pygments_lexer": "ipython2", 145 | "version": "2.7.11" 146 | } 147 | }, 148 | "nbformat": 4, 149 | "nbformat_minor": 0 150 | } 151 | -------------------------------------------------------------------------------- /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": null, 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 | "\n", 37 | "blur = cv2.medianBlur(gray, 5)\n", 38 | "\n", 39 | "circles = cv2.HoughCircles(blur, cv.CV_HOUGH_GRADIENT, 1.5, 10)\n", 40 | "#circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 1, 10)\n", 41 | "\n", 42 | "circles = np.uint16(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": null, 59 | "metadata": { 60 | "collapsed": true 61 | }, 62 | "outputs": [], 63 | "source": [] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": { 78 | "collapsed": true 79 | }, 80 | "outputs": [], 81 | "source": [] 82 | } 83 | ], 84 | "metadata": { 85 | "kernelspec": { 86 | "display_name": "Python 2", 87 | "language": "python", 88 | "name": "python2" 89 | }, 90 | "language_info": { 91 | "codemirror_mode": { 92 | "name": "ipython", 93 | "version": 2 94 | }, 95 | "file_extension": ".py", 96 | "mimetype": "text/x-python", 97 | "name": "python", 98 | "nbconvert_exporter": "python", 99 | "pygments_lexer": "ipython2", 100 | "version": "2.7.11" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 0 105 | } 106 | -------------------------------------------------------------------------------- /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": 4, 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 | "kernelspec": { 91 | "display_name": "Python 2", 92 | "language": "python", 93 | "name": "python2" 94 | }, 95 | "language_info": { 96 | "codemirror_mode": { 97 | "name": "ipython", 98 | "version": 2 99 | }, 100 | "file_extension": ".py", 101 | "mimetype": "text/x-python", 102 | "name": "python", 103 | "nbconvert_exporter": "python", 104 | "pygments_lexer": "ipython2", 105 | "version": "2.7.13" 106 | } 107 | }, 108 | "nbformat": 4, 109 | "nbformat_minor": 0 110 | } 111 | -------------------------------------------------------------------------------- /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 2", 145 | "language": "python", 146 | "name": "python2" 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.11" 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": 12, 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/box_in_scene.png', 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 | "kernelspec": { 235 | "display_name": "Python 2", 236 | "language": "python", 237 | "name": "python2" 238 | }, 239 | "language_info": { 240 | "codemirror_mode": { 241 | "name": "ipython", 242 | "version": 2 243 | }, 244 | "file_extension": ".py", 245 | "mimetype": "text/x-python", 246 | "name": "python", 247 | "nbconvert_exporter": "python", 248 | "pygments_lexer": "ipython2", 249 | "version": "2.7.11" 250 | } 251 | }, 252 | "nbformat": 4, 253 | "nbformat_minor": 0 254 | } 255 | -------------------------------------------------------------------------------- /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": 12, 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": 7, 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": 11, 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 | "kernelspec": { 199 | "display_name": "Python 2", 200 | "language": "python", 201 | "name": "python2" 202 | }, 203 | "language_info": { 204 | "codemirror_mode": { 205 | "name": "ipython", 206 | "version": 2 207 | }, 208 | "file_extension": ".py", 209 | "mimetype": "text/x-python", 210 | "name": "python", 211 | "nbconvert_exporter": "python", 212 | "pygments_lexer": "ipython2", 213 | "version": "2.7.11" 214 | } 215 | }, 216 | "nbformat": 4, 217 | "nbformat_minor": 0 218 | } 219 | -------------------------------------------------------------------------------- /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 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "C:\\Users\\krish.naik\\AppData\\Local\\Continuum\\anaconda3\\python.exe\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "import sys\n", 36 | "print(sys.executable)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "### Pedistrian Detection" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "import cv2\n", 53 | "import numpy as np\n", 54 | "\n", 55 | "# Create our body classifier\n", 56 | "body_classifier = cv2.CascadeClassifier('Haarcascades\\haarcascade_fullbody.xml')\n", 57 | "\n", 58 | "# Initiate video capture for video file\n", 59 | "cap = cv2.VideoCapture('images/walking.avi')\n", 60 | "\n", 61 | "# Loop once video is successfully loaded\n", 62 | "while cap.isOpened():\n", 63 | " \n", 64 | " # Read first frame\n", 65 | " ret, frame = cap.read()\n", 66 | " frame = cv2.resize(frame, None,fx=0.5, fy=0.5, interpolation = cv2.INTER_LINEAR)\n", 67 | "\n", 68 | " gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", 69 | " # Pass frame to our body classifier\n", 70 | " bodies = body_classifier.detectMultiScale(gray, 1.2, 3)\n", 71 | " \n", 72 | " # Extract bounding boxes for any bodies identified\n", 73 | " for (x,y,w,h) in bodies:\n", 74 | " cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)\n", 75 | " cv2.imshow('Pedestrians', frame)\n", 76 | "\n", 77 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 78 | " break\n", 79 | "\n", 80 | "cap.release()\n", 81 | "cv2.destroyAllWindows()" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Car Detection\n" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 4, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "import cv2\n", 98 | "import time\n", 99 | "import numpy as np\n", 100 | "\n", 101 | "# Create our body classifier\n", 102 | "car_classifier = cv2.CascadeClassifier('Haarcascades\\haarcascade_car.xml')\n", 103 | "\n", 104 | "# Initiate video capture for video file\n", 105 | "cap = cv2.VideoCapture('images/cars.avi')\n", 106 | "\n", 107 | "\n", 108 | "# Loop once video is successfully loaded\n", 109 | "while cap.isOpened():\n", 110 | " \n", 111 | " time.sleep(.05)\n", 112 | " # Read first frame\n", 113 | " ret, frame = cap.read()\n", 114 | " gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", 115 | " \n", 116 | " # Pass frame to our car classifier\n", 117 | " cars = car_classifier.detectMultiScale(gray, 1.4, 2)\n", 118 | " \n", 119 | " # Extract bounding boxes for any bodies identified\n", 120 | " for (x,y,w,h) in cars:\n", 121 | " cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)\n", 122 | " cv2.imshow('Cars', frame)\n", 123 | "\n", 124 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 125 | " break\n", 126 | "\n", 127 | "cap.release()\n", 128 | "cv2.destroyAllWindows()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "- **Full Body / Pedestrian Classifier ** - https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_fullbody.xml\n", 136 | "- **Car Classifier ** - http://www.codeforge.com/read/241845/cars3.xml__html\n" 137 | ] 138 | } 139 | ], 140 | "metadata": { 141 | "kernelspec": { 142 | "display_name": "Python 3", 143 | "language": "python", 144 | "name": "python3" 145 | }, 146 | "language_info": { 147 | "codemirror_mode": { 148 | "name": "ipython", 149 | "version": 3 150 | }, 151 | "file_extension": ".py", 152 | "mimetype": "text/x-python", 153 | "name": "python", 154 | "nbconvert_exporter": "python", 155 | "pygments_lexer": "ipython3", 156 | "version": "3.6.6" 157 | } 158 | }, 159 | "nbformat": 4, 160 | "nbformat_minor": 1 161 | } 162 | -------------------------------------------------------------------------------- /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": null, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "-" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "See blog post here - https://matthewearl.github.io/2015/07/28/switching-eds-with-python/\n", 26 | "\n", 27 | "\n", 28 | "#### Install Instructions for dlib\n", 29 | "\n", 30 | "- Download and Install Dlib\n", 31 | "\n", 32 | "https://sourceforge.net/projects/dclib/\n", 33 | "\n", 34 | "- Extract files in C:/dlib \n", 35 | "- Use command prompt to Cd to folder and run “python setup.py install”\n", 36 | "\n", 37 | "#### Download the pre-trained model here \n", 38 | "\n", 39 | "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2\n", 40 | "\n", 41 | "- Place this file in your default ipython notebook folder\n" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 5, 47 | "metadata": { 48 | "collapsed": true 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "import cv2\n", 53 | "import dlib\n", 54 | "import numpy \n", 55 | "\n", 56 | "PREDICTOR_PATH = \"shape_predictor_68_face_landmarks.dat\"\n", 57 | "predictor = dlib.shape_predictor(PREDICTOR_PATH)\n", 58 | "detector = dlib.get_frontal_face_detector()\n", 59 | "\n", 60 | "\n", 61 | "class TooManyFaces(Exception):\n", 62 | " pass\n", 63 | "\n", 64 | "class NoFaces(Exception):\n", 65 | " pass\n", 66 | "\n", 67 | "def get_landmarks(im):\n", 68 | " rects = detector(im, 1)\n", 69 | "\n", 70 | " if len(rects) > 1:\n", 71 | " raise TooManyFaces\n", 72 | " if len(rects) == 0:\n", 73 | " raise NoFaces\n", 74 | "\n", 75 | " return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])\n", 76 | "\n", 77 | "def annotate_landmarks(im, landmarks):\n", 78 | " im = im.copy()\n", 79 | " for idx, point in enumerate(landmarks):\n", 80 | " pos = (point[0, 0], point[0, 1])\n", 81 | " cv2.putText(im, str(idx), pos,\n", 82 | " fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,\n", 83 | " fontScale=0.4,\n", 84 | " \n", 85 | " color=(0, 0, 255))\n", 86 | " cv2.circle(im, pos, 3, color=(0, 255, 255))\n", 87 | " return im\n", 88 | "\n", 89 | "image = cv2.imread('Obama.jpg')\n", 90 | "landmarks = get_landmarks(image)\n", 91 | "image_with_landmarks = annotate_landmarks(image, landmarks)\n", 92 | "\n", 93 | "cv2.imshow('Result', image_with_landmarks)\n", 94 | "cv2.imwrite('image_with_landmarks.jpg',image_with_landmarks)\n", 95 | "cv2.waitKey(0)\n", 96 | "cv2.destroyAllWindows()" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": { 103 | "collapsed": true 104 | }, 105 | "outputs": [], 106 | "source": [] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": { 112 | "collapsed": true 113 | }, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 2", 121 | "language": "python", 122 | "name": "python2" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 2 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython2", 134 | "version": "2.7.11" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 0 139 | } 140 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /Lecture 9.5 - Optical Flow Object Tracking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Lucas-Kanade Optical Flow in OpenCV\n", 8 | "Requires OpenCV 3.1" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 3, 14 | "metadata": { 15 | "collapsed": false 16 | }, 17 | "outputs": [], 18 | "source": [ 19 | "import numpy as np\n", 20 | "import cv2\n", 21 | "\n", 22 | "# Load video stream\n", 23 | "cap = cv2.VideoCapture('images/walking.avi')\n", 24 | "\n", 25 | "# Set parameters for ShiTomasi corner detection\n", 26 | "feature_params = dict( maxCorners = 100,\n", 27 | " qualityLevel = 0.3,\n", 28 | " minDistance = 7,\n", 29 | " blockSize = 7 )\n", 30 | "\n", 31 | "# Set parameters for lucas kanade optical flow\n", 32 | "lucas_kanade_params = dict( winSize = (15,15),\n", 33 | " maxLevel = 2,\n", 34 | " criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))\n", 35 | "\n", 36 | "# Create some random colors\n", 37 | "# Used to create our trails for object movement in the image \n", 38 | "color = np.random.randint(0,255,(100,3))\n", 39 | "\n", 40 | "# Take first frame and find corners in it\n", 41 | "ret, prev_frame = cap.read()\n", 42 | "prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)\n", 43 | "\n", 44 | "# Find inital corner locations\n", 45 | "prev_corners = cv2.goodFeaturesToTrack(prev_gray, mask = None, **feature_params)\n", 46 | "\n", 47 | "# Create a mask image for drawing purposes\n", 48 | "mask = np.zeros_like(prev_frame)\n", 49 | "\n", 50 | "while(1):\n", 51 | " ret, frame = cap.read()\n", 52 | " frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", 53 | "\n", 54 | " # calculate optical flow\n", 55 | " new_corners, status, errors = cv2.calcOpticalFlowPyrLK(prev_gray, \n", 56 | " frame_gray, \n", 57 | " prev_corners, \n", 58 | " None, \n", 59 | " **lucas_kanade_params)\n", 60 | "\n", 61 | " # Select and store good points\n", 62 | " good_new = new_corners[status==1]\n", 63 | " good_old = prev_corners[status==1]\n", 64 | "\n", 65 | " # Draw the tracks\n", 66 | " for i,(new,old) in enumerate(zip(good_new, good_old)):\n", 67 | " a, b = new.ravel()\n", 68 | " c, d = old.ravel()\n", 69 | " mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)\n", 70 | " frame = cv2.circle(frame, (a,b), 5, color[i].tolist(),-1)\n", 71 | " \n", 72 | " img = cv2.add(frame,mask)\n", 73 | "\n", 74 | " # Show Optical Flow\n", 75 | " cv2.imshow('Optical Flow - Lucas-Kanade',img)\n", 76 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 77 | " break\n", 78 | "\n", 79 | " # Now update the previous frame and previous points\n", 80 | " prev_gray = frame_gray.copy()\n", 81 | " prev_corners = good_new.reshape(-1,1,2)\n", 82 | "\n", 83 | "cv2.destroyAllWindows()\n", 84 | "cap.release()" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "### Dense Optical Flow\n", 92 | "Requires OpenCV 3.1" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 4, 98 | "metadata": { 99 | "collapsed": false 100 | }, 101 | "outputs": [], 102 | "source": [ 103 | "import cv2\n", 104 | "import numpy as np\n", 105 | "\n", 106 | "# Load video stream\n", 107 | "cap = cv2.VideoCapture(\"images/walking.avi\")\n", 108 | "\n", 109 | "# Get first frame\n", 110 | "ret, first_frame = cap.read()\n", 111 | "previous_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)\n", 112 | "hsv = np.zeros_like(first_frame)\n", 113 | "hsv[...,1] = 255\n", 114 | "\n", 115 | "while True:\n", 116 | " \n", 117 | " # Read of video file\n", 118 | " ret, frame2 = cap.read()\n", 119 | " next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)\n", 120 | "\n", 121 | " # Computes the dense optical flow using the Gunnar Farneback’s algorithm\n", 122 | " flow = cv2.calcOpticalFlowFarneback(previous_gray, next, \n", 123 | " None, 0.5, 3, 15, 3, 5, 1.2, 0)\n", 124 | "\n", 125 | " # use flow to calculate the magnitude (speed) and angle of motion\n", 126 | " # use these values to calculate the color to reflect speed and angle\n", 127 | " magnitude, angle = cv2.cartToPolar(flow[...,0], flow[...,1])\n", 128 | " hsv[...,0] = angle * (180 / (np.pi/2))\n", 129 | " hsv[...,2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)\n", 130 | " final = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)\n", 131 | "\n", 132 | " # Show our demo of Dense Optical Flow\n", 133 | " cv2.imshow('Dense Optical Flow', final)\n", 134 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 135 | " break\n", 136 | " \n", 137 | " # Store current image as previous image\n", 138 | " previous_gray = next\n", 139 | "\n", 140 | "cap.release()\n", 141 | "cv2.destroyAllWindows()" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": { 153 | "collapsed": false 154 | }, 155 | "outputs": [], 156 | "source": [] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": { 162 | "collapsed": false 163 | }, 164 | "outputs": [], 165 | "source": [] 166 | } 167 | ], 168 | "metadata": { 169 | "kernelspec": { 170 | "display_name": "Python 2", 171 | "language": "python", 172 | "name": "python2" 173 | }, 174 | "language_info": { 175 | "codemirror_mode": { 176 | "name": "ipython", 177 | "version": 2 178 | }, 179 | "file_extension": ".py", 180 | "mimetype": "text/x-python", 181 | "name": "python", 182 | "nbconvert_exporter": "python", 183 | "pygments_lexer": "ipython2", 184 | "version": "2.7.11" 185 | } 186 | }, 187 | "nbformat": 4, 188 | "nbformat_minor": 0 189 | } 190 | -------------------------------------------------------------------------------- /Lecture 9.6 - Mini Project # 11 - Ball Tracking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mini Project # 10 - Object Tracking" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 7, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "#Object Tracking\n", 19 | "import cv2\n", 20 | "import numpy as np\n", 21 | "\n", 22 | "# Initalize camera\n", 23 | "cap = cv2.VideoCapture(0)\n", 24 | "\n", 25 | "# define range of purple color in HSV\n", 26 | "lower_purple = np.array([130,50,90])\n", 27 | "upper_purple = np.array([170,255,255])\n", 28 | "\n", 29 | "# Create empty points array\n", 30 | "points = []\n", 31 | "\n", 32 | "# Get default camera window size\n", 33 | "ret, frame = cap.read()\n", 34 | "Height, Width = frame.shape[:2]\n", 35 | "frame_count = 0\n", 36 | "\n", 37 | "while True:\n", 38 | "\n", 39 | " # Capture webcame frame\n", 40 | " ret, frame = cap.read()\n", 41 | " hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)\n", 42 | "\n", 43 | " # Threshold the HSV image to get only blue colors\n", 44 | " mask = cv2.inRange(hsv_img, lower_purple, upper_purple)\n", 45 | " #mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)\n", 46 | " \n", 47 | " # Find contours, OpenCV 3.X users use this line instead\n", 48 | " # _, contours, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", 49 | " contours, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", 50 | " \n", 51 | " # Create empty centre array to store centroid center of mass\n", 52 | " center = int(Height/2), int(Width/2)\n", 53 | "\n", 54 | " if len(contours) > 0:\n", 55 | " \n", 56 | " # Get the largest contour and its center \n", 57 | " c = max(contours, key=cv2.contourArea)\n", 58 | " (x, y), radius = cv2.minEnclosingCircle(c)\n", 59 | " M = cv2.moments(c)\n", 60 | " try:\n", 61 | " center = (int(M[\"m10\"] / M[\"m00\"]), int(M[\"m01\"] / M[\"m00\"]))\n", 62 | "\n", 63 | " except:\n", 64 | " center = int(Height/2), int(Width/2)\n", 65 | "\n", 66 | " # Allow only countors that have a larger than 15 pixel radius\n", 67 | " if radius > 25:\n", 68 | " \n", 69 | " # Draw cirlce and leave the last center creating a trail\n", 70 | " cv2.circle(frame, (int(x), int(y)), int(radius),(0, 0, 255), 2)\n", 71 | " cv2.circle(frame, center, 5, (0, 255, 0), -1)\n", 72 | " \n", 73 | " # Log center points \n", 74 | " points.append(center)\n", 75 | " \n", 76 | " # loop over the set of tracked points\n", 77 | " if radius > 25:\n", 78 | " for i in range(1, len(points)):\n", 79 | " try:\n", 80 | " cv2.line(frame, points[i - 1], points[i], (0, 255, 0), 2)\n", 81 | " except:\n", 82 | " pass\n", 83 | " \n", 84 | " # Make frame count zero\n", 85 | " frame_count = 0\n", 86 | " else:\n", 87 | " # Count frames \n", 88 | " frame_count += 1\n", 89 | " \n", 90 | " # If we count 10 frames without object lets delete our trail\n", 91 | " if frame_count == 10:\n", 92 | " points = []\n", 93 | " # when frame_count reaches 20 let's clear our trail \n", 94 | " frame_count = 0\n", 95 | " \n", 96 | " # Display our object tracker\n", 97 | " frame = cv2.flip(frame, 1)\n", 98 | " cv2.imshow(\"Object Tracker\", frame)\n", 99 | "\n", 100 | " if cv2.waitKey(1) == 13: #13 is the Enter Key\n", 101 | " break\n", 102 | "\n", 103 | "# Release camera and close any open windows\n", 104 | "cap.release()\n", 105 | "cv2.destroyAllWindows()" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": { 112 | "collapsed": false 113 | }, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 2", 121 | "language": "python", 122 | "name": "python2" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 2 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython2", 134 | "version": "2.7.11" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 0 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer-Vision-Advanced -------------------------------------------------------------------------------- /images/4star.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/4star.jpg -------------------------------------------------------------------------------- /images/Hillary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/Hillary.jpg -------------------------------------------------------------------------------- /images/IMG_7539.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/IMG_7539.jpg -------------------------------------------------------------------------------- /images/IMG_8295.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/IMG_8295.JPG -------------------------------------------------------------------------------- /images/Origin_of_Species.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/Origin_of_Species.jpg -------------------------------------------------------------------------------- /images/Sunflowers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/Sunflowers.jpg -------------------------------------------------------------------------------- /images/Trump.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/Trump.jpg -------------------------------------------------------------------------------- /images/WaldoBeach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/WaldoBeach.jpg -------------------------------------------------------------------------------- /images/abraham.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/abraham.jpg -------------------------------------------------------------------------------- /images/abraham_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/abraham_mask.png -------------------------------------------------------------------------------- /images/beatle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/beatle.jpg -------------------------------------------------------------------------------- /images/blobs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/blobs.jpg -------------------------------------------------------------------------------- /images/bottlecaps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/bottlecaps.jpg -------------------------------------------------------------------------------- /images/box_in_scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/box_in_scene.png -------------------------------------------------------------------------------- /images/bunchofshapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/bunchofshapes.jpg -------------------------------------------------------------------------------- /images/candy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/candy.jpg -------------------------------------------------------------------------------- /images/cars.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/cars.avi -------------------------------------------------------------------------------- /images/chess.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/chess.JPG -------------------------------------------------------------------------------- /images/chihuahua.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/chihuahua.jpg -------------------------------------------------------------------------------- /images/coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/coffee.jpg -------------------------------------------------------------------------------- /images/contours.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/contours.jpg -------------------------------------------------------------------------------- /images/digits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/digits.png -------------------------------------------------------------------------------- /images/domino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/domino.png -------------------------------------------------------------------------------- /images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/download.png -------------------------------------------------------------------------------- /images/eigenface_reconstruction_opencv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/eigenface_reconstruction_opencv.png -------------------------------------------------------------------------------- /images/elephant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/elephant.jpg -------------------------------------------------------------------------------- /images/ex2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/ex2.jpg -------------------------------------------------------------------------------- /images/faceswap.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/faceswap.JPG -------------------------------------------------------------------------------- /images/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/gradient.jpg -------------------------------------------------------------------------------- /images/hand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/hand.jpg -------------------------------------------------------------------------------- /images/house.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/house.jpg -------------------------------------------------------------------------------- /images/input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/input.jpg -------------------------------------------------------------------------------- /images/input33.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/input33.JPG -------------------------------------------------------------------------------- /images/kim.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/kim.jpg -------------------------------------------------------------------------------- /images/lourve_noise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/lourve_noise.jpg -------------------------------------------------------------------------------- /images/marsface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/marsface.jpg -------------------------------------------------------------------------------- /images/mask.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/mask.jpg -------------------------------------------------------------------------------- /images/numbers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/numbers.jpg -------------------------------------------------------------------------------- /images/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/obama.jpg -------------------------------------------------------------------------------- /images/obamafacerecog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/obamafacerecog.jpg -------------------------------------------------------------------------------- /images/opencv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/opencv.png -------------------------------------------------------------------------------- /images/opencv_inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/opencv_inv.png -------------------------------------------------------------------------------- /images/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/output.jpg -------------------------------------------------------------------------------- /images/photorestore.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/photorestore.JPG -------------------------------------------------------------------------------- /images/rot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/rot.jpg -------------------------------------------------------------------------------- /images/scan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/scan.jpg -------------------------------------------------------------------------------- /images/shapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/shapes.jpg -------------------------------------------------------------------------------- /images/shapes_donut.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/shapes_donut.jpg -------------------------------------------------------------------------------- /images/shapestomatch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/shapestomatch.jpg -------------------------------------------------------------------------------- /images/soduku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/soduku.jpg -------------------------------------------------------------------------------- /images/someshapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/someshapes.jpg -------------------------------------------------------------------------------- /images/tobago.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/tobago.jpg -------------------------------------------------------------------------------- /images/truck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/truck.jpg -------------------------------------------------------------------------------- /images/waldo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/waldo.jpg -------------------------------------------------------------------------------- /images/walking.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnaik06/Computer-Vision-Advanced/94490ef808d01e378dc33b0e53f3d285f3de0cac/images/walking.avi --------------------------------------------------------------------------------