├── .gitignore ├── 2A-L1 ├── answers │ ├── blend_2_images.py │ └── color_planes.py ├── blend_2_images.ipynb ├── blend_2_images.py ├── color_planes.ipynb ├── color_planes.py ├── images │ ├── bicycle.png │ ├── dolphin.png │ └── fruit.png └── readme.md ├── 2A-L2 ├── answers │ └── remove_noise.py ├── images │ └── saturn.png ├── remove_noise.ipynb └── remove_noise.py ├── 2A-L3 ├── answers │ ├── apply_median_filter.py │ └── explore_edge_options.py ├── apply_median_filter.ipynb ├── apply_median_filter.py ├── explore_edge_options.ipynb ├── explore_edge_options.py └── images │ ├── fall-leaves.png │ └── moon.png ├── 2A-L4 ├── answers │ ├── find_template_1D.py │ └── find_template_2D.py ├── find_template_1D.ipynb ├── find_template_1D.py ├── find_template_2D.ipynb ├── find_template_2D.py └── images │ └── tablet.png ├── 2A-L5 ├── answers │ └── gradient_quiz.py ├── gradient_quiz.ipynb ├── gradient_quiz.py └── images │ └── octagon.png ├── 2A-L6 ├── answers │ ├── edge_demo.py │ └── for_your_eyes_only.py ├── edge_demo.ipynb ├── edge_demo.py ├── for_your_eyes_only.ipynb ├── for_your_eyes_only.py └── images │ ├── frizzy.png │ ├── froomer.png │ └── lena.png ├── 3A-L2 ├── answers │ └── project_a_point.py ├── project_a_point.ipynb └── project_a_point.py ├── 3B-L3 ├── answers │ ├── find_best_match.py │ └── match_two_strips.py ├── find_best_match.ipynb ├── find_best_match.py ├── images │ ├── flowers-left.png │ └── flowers-right.png ├── match_two_strips.ipynb └── match_two_strips.py ├── 6B-L3 ├── answers │ └── downsample_an_image.py ├── downsample_an_image.ipynb ├── downsample_an_image.py └── images │ └── frizzy.png ├── 8C-L2 ├── answers │ └── compute_integral_image.py ├── compute_integral_image.ipynb ├── compute_integral_image.py └── images │ └── dolphin.png ├── py2nb.py └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | .idea/ 4 | **/\.ipynb_checkpoints/** 5 | -------------------------------------------------------------------------------- /2A-L1/answers/blend_2_images.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Blend two images 6 | def blend(a, b, alpha): 7 | """ Blends to images using a weight factor. 8 | Args: 9 | a (numpy.array): Image A. 10 | b (numpy.array): Image B. 11 | alpha (float): Weight factor. 12 | 13 | Returns: 14 | numpy.array: Blended Image. 15 | """ 16 | return alpha * a + (1. - alpha) * b 17 | 18 | dolphin = cv2.imread("../images/dolphin.png") 19 | bicycle = cv2.imread("../images/bicycle.png") 20 | 21 | result = blend(dolphin, bicycle, 0.75) 22 | cv2.imshow('Result', result.astype(np.uint8)) 23 | cv2.waitKey(0) 24 | -------------------------------------------------------------------------------- /2A-L1/answers/color_planes.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | # Color planes 4 | 5 | img = cv2.imread('../images/fruit.png') 6 | cv2.imshow("Fruit image", img) 7 | 8 | print(img.shape) 9 | 10 | # TODO: Select a color plane, display it, inspect values from a row 11 | 12 | # Red, green, and blue color planes. Remember OpenCV uses BGR 13 | red = img[:, :, 2] 14 | green = img[:, :, 1] 15 | blue = img[:, :, 0] 16 | 17 | cv2.imshow("Red color plane", red) 18 | cv2.imshow("Green color plane", green) 19 | cv2.imshow("Blue color plane", blue) 20 | 21 | # Let's select the green plane, pick a row, and print the values 22 | print("Green color plane, 100-th row \n {}".format(green[99, :])) 23 | 24 | # Let's draw a horizontal line across that row we picked, just for fun 25 | # But in order to see the line in color we need to convert green to a 3-channel array 26 | green_bgr = cv2.cvtColor(green, cv2.COLOR_GRAY2BGR) 27 | 28 | # You will notice that cv2.line uses x-y coordinates instead of row-cols 29 | cv2.line(green_bgr, (0, 99), (green.shape[1], 99), (0, 0, 255)) 30 | cv2.imshow("50-th row drawn on the green color plane", green_bgr) 31 | 32 | cv2.waitKey(0) 33 | -------------------------------------------------------------------------------- /2A-L1/blend_2_images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "scrolled": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%matplotlib inline\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import cv2\n", 14 | "import numpy as np\n", 15 | "\n", 16 | "\n", 17 | "# Blend two images\n", 18 | "def blend(a, b, alpha):\n", 19 | " \"\"\" Blends to images using a weight factor.\n", 20 | " Args:\n", 21 | " a (numpy.array): Image A.\n", 22 | " b (numpy.array): Image B.\n", 23 | " alpha (float): Weight factor.\n", 24 | "\n", 25 | " Returns:\n", 26 | " numpy.array: Blended Image.\n", 27 | " \"\"\"\n", 28 | " # TODO: Your code here\n", 29 | " \n", 30 | "\n", 31 | "dolphin = cv2.imread(\"images/dolphin.png\")\n", 32 | "bicycle = cv2.imread(\"images/bicycle.png\")\n", 33 | "\n", 34 | "result = blend(dolphin, bicycle, 0.75)\n", 35 | "plt.imshow(result.astype(np.uint8))\n", 36 | "plt.show()" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [] 45 | } 46 | ], 47 | "metadata": { 48 | "kernelspec": { 49 | "display_name": "Python 3", 50 | "language": "python", 51 | "name": "python3" 52 | }, 53 | "language_info": { 54 | "codemirror_mode": { 55 | "name": "ipython", 56 | "version": 3 57 | }, 58 | "file_extension": ".py", 59 | "mimetype": "text/x-python", 60 | "name": "python", 61 | "nbconvert_exporter": "python", 62 | "pygments_lexer": "ipython3", 63 | "version": "3.5.5" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 2 68 | } 69 | -------------------------------------------------------------------------------- /2A-L1/blend_2_images.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Blend two images 6 | def blend(a, b, alpha): 7 | """ Blends to images using a weight factor. 8 | Args: 9 | a (numpy.array): Image A. 10 | b (numpy.array): Image B. 11 | alpha (float): Weight factor. 12 | 13 | Returns: 14 | numpy.array: Blended Image. 15 | """ 16 | # TODO: Your code here 17 | 18 | dolphin = cv2.imread("images/dolphin.png") 19 | bicycle = cv2.imread("images/bicycle.png") 20 | 21 | result = blend(dolphin, bicycle, 0.75) 22 | cv2.imshow('Result', result.astype(np.uint8)) 23 | cv2.waitKey(0) 24 | -------------------------------------------------------------------------------- /2A-L1/color_planes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "\n", 13 | "# Color planes\n", 14 | "\n", 15 | "img = cv2.imread('images/fruit.png')\n", 16 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 17 | "\n", 18 | "print(img.shape)\n", 19 | "\n", 20 | "# TODO: Select a color plane, display it, inspect values from a row\n", 21 | "\n", 22 | "img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n", 23 | "plt.show()" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [] 32 | } 33 | ], 34 | "metadata": { 35 | "kernelspec": { 36 | "display_name": "Python 3", 37 | "language": "python", 38 | "name": "python3" 39 | }, 40 | "language_info": { 41 | "codemirror_mode": { 42 | "name": "ipython", 43 | "version": 3 44 | }, 45 | "file_extension": ".py", 46 | "mimetype": "text/x-python", 47 | "name": "python", 48 | "nbconvert_exporter": "python", 49 | "pygments_lexer": "ipython3", 50 | "version": "3.5.5" 51 | } 52 | }, 53 | "nbformat": 4, 54 | "nbformat_minor": 2 55 | } 56 | -------------------------------------------------------------------------------- /2A-L1/color_planes.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | # Color planes 4 | 5 | img = cv2.imread('images/fruit.png') 6 | cv2.imshow("Fruit image", img) 7 | 8 | print(img.shape) 9 | 10 | # TODO: Select a color plane, display it, inspect values from a row 11 | 12 | cv2.waitKey(0) 13 | -------------------------------------------------------------------------------- /2A-L1/images/bicycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L1/images/bicycle.png -------------------------------------------------------------------------------- /2A-L1/images/dolphin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L1/images/dolphin.png -------------------------------------------------------------------------------- /2A-L1/images/fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L1/images/fruit.png -------------------------------------------------------------------------------- /2A-L1/readme.md: -------------------------------------------------------------------------------- 1 | # 2A-L1 2 | 3 | ## Color Planes 4 | Find out what each dimension in an image array represents. 5 | 6 | * Base code: [color_planes.py](color_planes.py) 7 | * Answer: [color_planes.py](answers/color_planes.py) 8 | * Video: [color_planes](https://youtu.be/Ro_uqjYW_gA) 9 | 10 | 11 | ## Blend 2 Images 12 | Work with intesity value ratios (weights) to blend two images. 13 | 14 | * Base code: [blend_2_images.py](blend_2_images.py) 15 | * Answer: [blend_2_images.py](answers/blend_2_images.py) 16 | * Video: [blend_2_images](https://youtu.be/UPReI_815cM) -------------------------------------------------------------------------------- /2A-L2/answers/remove_noise.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Helper function 6 | def imshow(title, image): 7 | # WARNING: Using np.clip to get results similar to the quiz. 8 | # This is NOT a good practice because you are discarding information that is 9 | # below 0 and above 255. Use normalization instead. 10 | 11 | image = np.clip(image, 0, 255).astype(np.uint8) 12 | cv2.imshow(title, image.astype(np.uint8)) 13 | 14 | # Apply a Gaussian filter to remove noise 15 | img = cv2.imread('../images/saturn.png', 0) 16 | cv2.imshow('Img', img) 17 | 18 | # Add some noise 19 | noise_sigma = 25 20 | r, c = img.shape 21 | noise = np.random.randn(r, c) * noise_sigma 22 | noisy_img = img + noise 23 | 24 | imshow('Noisy Image', noisy_img) # Customized imshow function to match the quiz 25 | 26 | # Create a Gaussian filter 27 | filter_size = 11 28 | filter_sigma = 2 29 | 30 | # OpenCV does not have a fspecial type of function. Instead we will cv2.getGaussianKernel 31 | # to generate a Gaussian kernel. 32 | filter_kernel = cv2.getGaussianKernel(filter_size, filter_sigma) 33 | 34 | # This however generates a 1D kernel and we want a 2D that is of shape (filter_size, filter_size) 35 | # To achieve this we multiply this array by its transpose 36 | filter_kernel = filter_kernel * filter_kernel.T 37 | 38 | # Apply it to remove noise 39 | smoothed = cv2.filter2D(noisy_img, -1, filter_kernel) 40 | 41 | imshow('Smoothed image', smoothed) # Customized imshow function to match the quiz 42 | cv2.waitKey(0) 43 | -------------------------------------------------------------------------------- /2A-L2/images/saturn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L2/images/saturn.png -------------------------------------------------------------------------------- /2A-L2/remove_noise.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "# Apply a Gaussian filter to remove noise\n", 15 | "img = cv2.imread('images/saturn.png')\n", 16 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 17 | "\n", 18 | "\n", 19 | "\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "# TODO: Add noise to the image\n", 29 | "\n", 30 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# TODO: Now apply a Gaussian filter to smooth out the noise\n", 40 | "\n", 41 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [] 50 | } 51 | ], 52 | "metadata": { 53 | "kernelspec": { 54 | "display_name": "Python 3", 55 | "language": "python", 56 | "name": "python3" 57 | }, 58 | "language_info": { 59 | "codemirror_mode": { 60 | "name": "ipython", 61 | "version": 3 62 | }, 63 | "file_extension": ".py", 64 | "mimetype": "text/x-python", 65 | "name": "python", 66 | "nbconvert_exporter": "python", 67 | "pygments_lexer": "ipython3", 68 | "version": "3.5.5" 69 | } 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 2 73 | } 74 | -------------------------------------------------------------------------------- /2A-L2/remove_noise.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | # Apply a Gaussian filter to remove noise 5 | img = cv2.imread('images/saturn.png') 6 | cv2.imshow('Img', img) 7 | 8 | # TODO: Add noise to the image 9 | 10 | # TODO: Now apply a Gaussian filter to smooth out the noise 11 | -------------------------------------------------------------------------------- /2A-L3/answers/apply_median_filter.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Helper function 6 | def imnoise(img_in, method, dens): 7 | 8 | if method == 'salt & pepper': 9 | img_out = np.copy(img_in) 10 | r, c = img_in.shape 11 | x = np.random.rand(r, c) 12 | ids = x < dens / 2. 13 | img_out[ids] = 0 14 | ids = dens / 2. <= x 15 | ids &= x < dens 16 | img_out[ids] = 255 17 | 18 | return img_out 19 | 20 | else: 21 | print("Method {} not yet implemented.".format(method)) 22 | exit() 23 | 24 | 25 | # Apply a median filter 26 | 27 | # Read an image 28 | img = cv2.imread('../images/moon.png', 0) 29 | cv2.imshow('Image', img) 30 | 31 | # Add salt & pepper 32 | noisy_img = imnoise(img, 'salt & pepper', 0.02) 33 | cv2.imshow('Noisy', noisy_img.astype(np.uint8)) 34 | 35 | # Apply a median filter 36 | median_filtered = cv2.medianBlur(noisy_img, 3) 37 | cv2.imshow('Filtered', median_filtered) 38 | 39 | cv2.waitKey(0) 40 | -------------------------------------------------------------------------------- /2A-L3/answers/explore_edge_options.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | # Explore edge options 4 | 5 | # Load an image 6 | img = cv2.imread('../images/fall-leaves.png') 7 | cv2.imshow('Image', img) 8 | 9 | # Create a Gaussian Filter 10 | filter_size = 11 11 | filter_sigma = 2 12 | filter_kernel = cv2.getGaussianKernel(filter_size, filter_sigma) 13 | filter_kernel = filter_kernel * filter_kernel.T 14 | 15 | # Apply the kernel using different edge parameters. The ones below mimic what 16 | # Matlab does. OpenCV has even more options, you should read the cv2.filter2D 17 | # documentation for more 18 | edge_params = {"replicate": cv2.BORDER_CONSTANT, "symmetric": cv2.BORDER_REFLECT, 19 | "circular": cv2.BORDER_WRAP} 20 | 21 | method = "symmetric" 22 | if method == "circular": 23 | # cv2.copyMakeBorder does not support cv2.BORDER_WRAP. Instead we create a new image 24 | # with borders that mirror the edges adding a number of pixels around it equal to 25 | # filter_size. Then we proceed to filter the image with the Gaussian Kernel. 26 | # Finally, we crop the blurred image back to the original size removing the added 27 | # border. 28 | 29 | temp_img = cv2.copyMakeBorder(img, filter_size, filter_size, filter_size, filter_size, 30 | edge_params[method]) 31 | smoothed = cv2.filter2D(temp_img, -1, filter_kernel) 32 | smoothed = smoothed[filter_size:-filter_size, 33 | filter_size:-filter_size] 34 | 35 | else: 36 | smoothed = cv2.filter2D(img, -1, filter_kernel, borderType=edge_params[method]) 37 | 38 | cv2.imshow('Smoothed', smoothed) 39 | cv2.waitKey(0) 40 | -------------------------------------------------------------------------------- /2A-L3/apply_median_filter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "\n", 15 | "# Helper function\n", 16 | "def imnoise(img_in, method, dens):\n", 17 | "\n", 18 | " if method == 'salt & pepper':\n", 19 | " img_out = np.copy(img_in)\n", 20 | " r, c = img_in.shape\n", 21 | " x = np.random.rand(r, c)\n", 22 | " ids = x < dens / 2.\n", 23 | " img_out[ids] = 0\n", 24 | " ids = dens / 2. <= x\n", 25 | " ids &= x < dens\n", 26 | " img_out[ids] = 255\n", 27 | "\n", 28 | " return img_out\n", 29 | "\n", 30 | " else:\n", 31 | " print(\"Method {} not yet implemented.\").format(method)\n", 32 | " exit()\n", 33 | "\n", 34 | "# Apply a median filter\n", 35 | "\n", 36 | "# Read an image\n", 37 | "img = cv2.imread('images/moon.png', 0)\n", 38 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 39 | "plt.show()\n" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "# TODO: Add salt & pepper noise\n", 49 | "\n", 50 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 51 | "plt.show()" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "# TODO: Apply a median filter. Use cv2.medianBlur\n", 61 | "\n", 62 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 63 | "plt.show()" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": "Python 3", 77 | "language": "python", 78 | "name": "python3" 79 | }, 80 | "language_info": { 81 | "codemirror_mode": { 82 | "name": "ipython", 83 | "version": 3 84 | }, 85 | "file_extension": ".py", 86 | "mimetype": "text/x-python", 87 | "name": "python", 88 | "nbconvert_exporter": "python", 89 | "pygments_lexer": "ipython3", 90 | "version": "3.5.5" 91 | } 92 | }, 93 | "nbformat": 4, 94 | "nbformat_minor": 2 95 | } 96 | -------------------------------------------------------------------------------- /2A-L3/apply_median_filter.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Helper function 6 | def imnoise(img_in, method, dens): 7 | 8 | if method == 'salt & pepper': 9 | img_out = np.copy(img_in) 10 | r, c = img_in.shape 11 | x = np.random.rand(r, c) 12 | ids = x < dens / 2. 13 | img_out[ids] = 0 14 | ids = dens / 2. <= x 15 | ids &= x < dens 16 | img_out[ids] = 255 17 | 18 | return img_out 19 | 20 | else: 21 | print("Method {} not yet implemented.".format(method)) 22 | exit() 23 | 24 | # Apply a median filter 25 | 26 | # Read an image 27 | img = cv2.imread('images/moon.png', 0) 28 | cv2.imshow('Image', img) 29 | 30 | # TODO: Add salt & pepper noise 31 | 32 | # TODO: Apply a median filter. Use cv2.medianBlur 33 | -------------------------------------------------------------------------------- /2A-L3/explore_edge_options.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "\n", 13 | "# Explore edge options\n", 14 | "\n", 15 | "# Load an image\n", 16 | "img = cv2.imread('images/fall-leaves.png')\n", 17 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# TODO: Create a Gaussian filter. Use cv2.getGaussianKernel.\n", 27 | "\n", 28 | "\n", 29 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# TODO: Apply it, specifying an edge parameter (try different parameters). Use cv2.filter2D.\n", 39 | "\n", 40 | "\n", 41 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" 42 | ] 43 | } 44 | ], 45 | "metadata": { 46 | "kernelspec": { 47 | "display_name": "Python 3", 48 | "language": "python", 49 | "name": "python3" 50 | }, 51 | "language_info": { 52 | "codemirror_mode": { 53 | "name": "ipython", 54 | "version": 3 55 | }, 56 | "file_extension": ".py", 57 | "mimetype": "text/x-python", 58 | "name": "python", 59 | "nbconvert_exporter": "python", 60 | "pygments_lexer": "ipython3", 61 | "version": "3.5.5" 62 | } 63 | }, 64 | "nbformat": 4, 65 | "nbformat_minor": 2 66 | } 67 | -------------------------------------------------------------------------------- /2A-L3/explore_edge_options.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | # Explore edge options 4 | 5 | # Load an image 6 | img = cv2.imread('images/fall-leaves.png') 7 | cv2.imshow('Image', img) 8 | 9 | # TODO: Create a Gaussian filter. Use cv2.getGaussianKernel. 10 | 11 | # TODO: Apply it, specifying an edge parameter (try different parameters). Use cv2.filter2D. 12 | -------------------------------------------------------------------------------- /2A-L3/images/fall-leaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L3/images/fall-leaves.png -------------------------------------------------------------------------------- /2A-L3/images/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L3/images/moon.png -------------------------------------------------------------------------------- /2A-L4/answers/find_template_1D.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.signal as sp 3 | 4 | 5 | def find_template_1D(t, s): 6 | c = sp.correlate2d(s, t, mode='valid') 7 | raw_index = np.argmax(c) 8 | return raw_index 9 | 10 | 11 | s = np.array([[-1, 0, 0, 5, 1, 1, 0, 0, -1, -7, 2, 1, 0, 0, -1]]) 12 | t = np.array([[-1, -7, 2]]) 13 | 14 | print("Signal: \n {} \n {}".format(np.array(range(s.shape[1])), s[0])) 15 | print("Tiemplate: \n {} \n {}".format(np.array(range(t.shape[1])), t[0])) 16 | 17 | index = find_template_1D(t, s) 18 | print("Index: {}".format(index)) -------------------------------------------------------------------------------- /2A-L4/answers/find_template_2D.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import scipy.signal as sp 4 | 5 | 6 | # Find template 2D 7 | def find_template_2D(template, img): 8 | c = sp.correlate2d(img, template, mode='same') 9 | 10 | # These y, x coordinates represent the peak. This point needs to be 11 | # translated to be the top-left corner as the quiz suggests 12 | y, x = np.unravel_index(np.argmax(c), c.shape) 13 | return y - template.shape[0] // 2, x - template.shape[1] // 2 14 | 15 | tablet = cv2.imread('../images/tablet.png', 0) 16 | cv2.imshow('Tablet', tablet) 17 | 18 | glyph = tablet[74:165, 149:184] 19 | cv2.imshow('Glyph', glyph) 20 | 21 | tablet_2 = 1. * tablet - np.mean(tablet) 22 | glyph_2 = 1. * glyph - np.mean(glyph) 23 | 24 | y, x = find_template_2D(glyph_2, tablet_2) 25 | print("Y: {}, X: {}".format(y, x)) 26 | 27 | # The code below is not part of the quiz but helps to verify the results are 28 | # what we are looking for. 29 | tablet = cv2.cvtColor(tablet, code=cv2.COLOR_GRAY2BGR) 30 | cv2.rectangle(tablet, (x, y), (x + glyph.shape[1], y + glyph.shape[0]), 31 | (0, 0, 255), thickness=2) 32 | cv2.imshow('Rectangle', tablet) 33 | cv2.waitKey(0) 34 | -------------------------------------------------------------------------------- /2A-L4/find_template_1D.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import numpy as np\n", 12 | "import scipy.signal as sp\n", 13 | "\n", 14 | "\n", 15 | "def find_template_1D(t, s):\n", 16 | " # TODO: Locate template t in signal s and return index. Use scipy.signal.correlate2d\n", 17 | " pass\n", 18 | "\n", 19 | "s = np.array([[-1, 0, 0, 5, 1, 1, 0, 0, -1, -7, 2, 1, 0, 0, -1]])\n", 20 | "t = np.array([[-1, -7, 2]])\n", 21 | "\n", 22 | "print (\"Signal: \\n {} \\n {}\").format(np.array(range(s.shape[1])), s[0])\n", 23 | "print (\"Tiemplate: \\n {} \\n {}\").format(np.array(range(t.shape[1])), t[0])\n", 24 | "\n", 25 | "index = find_template_1D(t, s)\n", 26 | "print (\"Index: {}\").format(index)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [] 35 | } 36 | ], 37 | "metadata": { 38 | "kernelspec": { 39 | "display_name": "Python 3", 40 | "language": "python", 41 | "name": "python3" 42 | }, 43 | "language_info": { 44 | "codemirror_mode": { 45 | "name": "ipython", 46 | "version": 3 47 | }, 48 | "file_extension": ".py", 49 | "mimetype": "text/x-python", 50 | "name": "python", 51 | "nbconvert_exporter": "python", 52 | "pygments_lexer": "ipython3", 53 | "version": "3.5.5" 54 | } 55 | }, 56 | "nbformat": 4, 57 | "nbformat_minor": 2 58 | } 59 | -------------------------------------------------------------------------------- /2A-L4/find_template_1D.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.signal as sp 3 | 4 | 5 | def find_template_1D(t, s): 6 | # TODO: Locate template t in signal s and return index. Use scipy.signal.correlate2d 7 | pass 8 | 9 | s = np.array([[-1, 0, 0, 5, 1, 1, 0, 0, -1, -7, 2, 1, 0, 0, -1]]) 10 | t = np.array([[-1, -7, 2]]) 11 | 12 | print("Signal: \n {} \n {}".format(np.array(range(s.shape[1])), s[0])) 13 | print("Tiemplate: \n {} \n {}".format(np.array(range(t.shape[1])), t[0])) 14 | 15 | index = find_template_1D(t, s) 16 | print("Index: {}".format(index)) 17 | -------------------------------------------------------------------------------- /2A-L4/find_template_2D.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "import scipy.signal as sp\n", 14 | "\n", 15 | "\n", 16 | "# Find template 2D\n", 17 | "def find_template_2D(template, img):\n", 18 | " # TODO: Find template in img and return [y x] location. Make sure this location is the top-left corner of the match.\n", 19 | " # Use scipy.signal.correlate2d\n", 20 | " pass\n", 21 | "\n", 22 | "tablet = cv2.imread('images/tablet.png', 0)\n", 23 | "plt.imshow(cv2.cvtColor(tablet, cv2.COLOR_BGR2RGB))\n", 24 | "\n", 25 | "glyph = tablet[74:165, 149:184]\n", 26 | "plt.imshow(cv2.cvtColor(glyph, cv2.COLOR_BGR2RGB))\n", 27 | "\n", 28 | "tablet_2 = 1. * tablet - np.mean(tablet)\n", 29 | "glyph_2 = 1. * glyph - np.mean(glyph)\n", 30 | "\n", 31 | "y, x = find_template_2D(glyph_2, tablet_2)\n", 32 | "print(\"Y: {}, X: {}\").format(y, x)\n", 33 | "\n", 34 | "# The code below is not part of the quiz but helps to verify the results are\n", 35 | "# what we are looking for.\n", 36 | "tablet = cv2.cvtColor(tablet, code=cv2.COLOR_GRAY2BGR)\n", 37 | "cv2.rectangle(tablet, (x, y), (x + glyph.shape[1], y + glyph.shape[0]),\n", 38 | " (0, 0, 255), thickness=2)\n", 39 | "cv2.imshow('Rectangle', tablet)\n", 40 | "plt.imshow(cv2.cvtColor(tablet, cv2.COLOR_BGR2RGB))" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [] 49 | } 50 | ], 51 | "metadata": { 52 | "kernelspec": { 53 | "display_name": "Python 3", 54 | "language": "python", 55 | "name": "python3" 56 | }, 57 | "language_info": { 58 | "codemirror_mode": { 59 | "name": "ipython", 60 | "version": 3 61 | }, 62 | "file_extension": ".py", 63 | "mimetype": "text/x-python", 64 | "name": "python", 65 | "nbconvert_exporter": "python", 66 | "pygments_lexer": "ipython3", 67 | "version": "3.5.5" 68 | } 69 | }, 70 | "nbformat": 4, 71 | "nbformat_minor": 2 72 | } 73 | -------------------------------------------------------------------------------- /2A-L4/find_template_2D.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import scipy.signal as sp 4 | 5 | 6 | # Find template 2D 7 | def find_template_2D(template, img): 8 | # TODO: Find template in img and return [y x] location. Make sure this location is the top-left corner of the match. 9 | # Use scipy.signal.correlate2d 10 | pass 11 | 12 | tablet = cv2.imread('images/tablet.png', 0) 13 | cv2.imshow('Tablet', tablet) 14 | 15 | glyph = tablet[74:165, 149:184] 16 | cv2.imshow('Glyph', glyph) 17 | 18 | tablet_2 = 1. * tablet - np.mean(tablet) 19 | glyph_2 = 1. * glyph - np.mean(glyph) 20 | 21 | y, x = find_template_2D(glyph_2, tablet_2) 22 | print("Y: {}, X: {}".format(y, x)) 23 | 24 | # The code below is not part of the quiz but helps to verify the results are 25 | # what we are looking for. 26 | tablet = cv2.cvtColor(tablet, code=cv2.COLOR_GRAY2BGR) 27 | cv2.rectangle(tablet, (x, y), (x + glyph.shape[1], y + glyph.shape[0]), 28 | (0, 0, 255), thickness=2) 29 | cv2.imshow('Rectangle', tablet) 30 | cv2.waitKey(0) 31 | -------------------------------------------------------------------------------- /2A-L4/images/tablet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L4/images/tablet.png -------------------------------------------------------------------------------- /2A-L5/answers/gradient_quiz.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import scipy.signal as sp 4 | 5 | 6 | def normalize(img_in): 7 | img_out = np.zeros(img_in.shape) 8 | cv2.normalize(img_in, img_out, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 9 | return img_out 10 | 11 | 12 | # Gradient Direction 13 | def select_gdir(gmag, gdir, mag_min, angle_low, angle_high): 14 | # TODO: Find and return pixels that fall within the desired mag, angle range 15 | result = gmag >= mag_min 16 | result &= gdir >= angle_low 17 | result &= gdir <= angle_high 18 | return result.astype(np.float) # Converts bool array to float [0., 1.] 19 | 20 | # Load and convert image to double type, range [0, 1] for convenience 21 | img = cv2.imread('../images/octagon.png', 0) / 255. 22 | cv2.imshow('Image', img) # assumes [0, 1] range for double images 23 | 24 | # Compute x, y gradients 25 | gx = cv2.Sobel(img, -1, dx=1, dy=0) 26 | gy = cv2.Sobel(img, -1, dx=0, dy=1) 27 | cv2.imshow('Gx', gx) 28 | cv2.imshow('Gy', gy) 29 | 30 | gmag = np.sqrt(gx**2 + gy**2) 31 | 32 | # The minus sign here is used based on how imgradient is implemented in octave 33 | # See https://sourceforge.net/p/octave/image/ci/default/tree/inst/imgradient.m#l61 34 | gdir = np.arctan2(-gy, gx) * 180 / np.pi 35 | cv2.imshow('Gmag', gmag / (4 * np.sqrt(2))) 36 | cv2.imshow('Gdir', normalize(gdir).astype(np.uint8)) 37 | 38 | # Find pixels with desired gradient direction 39 | my_grad = select_gdir(gmag, gdir, 1, 30, 60) 40 | cv2.imshow('My Grad', my_grad) 41 | cv2.waitKey(0) 42 | -------------------------------------------------------------------------------- /2A-L5/gradient_quiz.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "\n", 15 | "def normalize(img_in):\n", 16 | " img_out = np.zeros(img_in.shape)\n", 17 | " cv2.normalize(img_in, img_out, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)\n", 18 | " return img_out\n", 19 | "\n", 20 | "\n", 21 | "# Gradient Direction\n", 22 | "def select_gdir(gmag, gdir, mag_min, angle_low, angle_high):\n", 23 | " # TODO: Find and return pixels that fall within the desired mag, angle range\n", 24 | " return gmag\n", 25 | " pass\n", 26 | "\n", 27 | "# Load and convert image to double type, range [0, 1] for convenience\n", 28 | "img = cv2.imread('images/octagon.png', 0) / 255.\n", 29 | "plt.imshow(img, cmap='gray')\n", 30 | "plt.show()\n", 31 | "\n", 32 | "# Compute x, y gradients\n", 33 | "gx = cv2.Sobel(img, -1, dx=1, dy=0)\n", 34 | "gy = cv2.Sobel(img, -1, dx=0, dy=1)\n", 35 | "plt.imshow(gx, cmap='gray')\n", 36 | "plt.show()\n", 37 | "plt.imshow(gy, cmap='gray')\n", 38 | "plt.show()" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "gmag = np.sqrt(gx**2 + gy**2)\n", 48 | "\n", 49 | "# The minus sign here is used based on how imgradient is implemented in octave\n", 50 | "# See https://sourceforge.net/p/octave/image/ci/default/tree/inst/imgradient.m#l61\n", 51 | "gdir = np.arctan2(-gy, gx) * 180 / np.pi\n", 52 | "plt.imshow(gmag / (4 * np.sqrt(2)), cmap='gray')\n", 53 | "plt.show()\n", 54 | "plt.imshow(normalize(gmag).astype(np.uint8), cmap='gray')\n", 55 | "plt.show()\n", 56 | "plt.imshow(normalize(gdir).astype(np.uint8), cmap='gray')" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "# Find pixels with desired gradient direction\n", 66 | "my_grad = select_gdir(gmag, gdir, 1, 30, 60)\n", 67 | "plt.imshow(my_grad, cmap='gray')" 68 | ] 69 | } 70 | ], 71 | "metadata": { 72 | "kernelspec": { 73 | "display_name": "Python 3", 74 | "language": "python", 75 | "name": "python3" 76 | }, 77 | "language_info": { 78 | "codemirror_mode": { 79 | "name": "ipython", 80 | "version": 3 81 | }, 82 | "file_extension": ".py", 83 | "mimetype": "text/x-python", 84 | "name": "python", 85 | "nbconvert_exporter": "python", 86 | "pygments_lexer": "ipython3", 87 | "version": "3.5.5" 88 | } 89 | }, 90 | "nbformat": 4, 91 | "nbformat_minor": 2 92 | } 93 | -------------------------------------------------------------------------------- /2A-L5/gradient_quiz.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | def normalize(img_in): 6 | img_out = np.zeros(img_in.shape) 7 | cv2.normalize(img_in, img_out, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 8 | return img_out 9 | 10 | 11 | # Gradient Direction 12 | def select_gdir(gmag, gdir, mag_min, angle_low, angle_high): 13 | # TODO: Find and return pixels that fall within the desired mag, angle range 14 | 15 | pass 16 | 17 | # Load and convert image to double type, range [0, 1] for convenience 18 | img = cv2.imread('images/octagon.png', 0) / 255. 19 | cv2.imshow('Image', img) # assumes [0, 1] range for double images 20 | 21 | # Compute x, y gradients 22 | gx = cv2.Sobel(img, -1, dx=1, dy=0) 23 | gy = cv2.Sobel(img, -1, dx=0, dy=1) 24 | cv2.imshow('Gx', gx) 25 | cv2.imshow('Gy', gy) 26 | 27 | gmag = np.sqrt(gx**2 + gy**2) 28 | 29 | # The minus sign here is used based on how imgradient is implemented in octave 30 | # See https://sourceforge.net/p/octave/image/ci/default/tree/inst/imgradient.m#l61 31 | gdir = np.arctan2(-gy, gx) * 180 / np.pi 32 | cv2.imshow('Gmag', gmag / (4 * np.sqrt(2))) 33 | cv2.imshow('Gdir', normalize(gdir).astype(np.uint8)) 34 | 35 | # Find pixels with desired gradient direction 36 | my_grad = select_gdir(gmag, gdir, 1, 30, 60) 37 | cv2.imshow('My Grad', my_grad) 38 | cv2.waitKey(0) -------------------------------------------------------------------------------- /2A-L5/images/octagon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L5/images/octagon.png -------------------------------------------------------------------------------- /2A-L6/answers/edge_demo.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | from mpl_toolkits.mplot3d import Axes3D 7 | 8 | 9 | def surf(data): 10 | y = np.arange(0, data.shape[0]) 11 | x = np.arange(0, data.shape[1]) 12 | X, Y = np.meshgrid(x, y) 13 | 14 | fig = plt.figure() 15 | ax = fig.gca(projection='3d') 16 | 17 | ax.plot_surface(X, Y, data, rstride=1, cstride=1, linewidth=0, 18 | cmap='jet', antialiased=False) 19 | 20 | plt.show(block=False) 21 | 22 | 23 | def LoG(size, sigma): 24 | x = y = np.linspace(-size, size, 2*size+1) 25 | x, y = np.meshgrid(x, y) 26 | 27 | f = (x**2 + y**2)/(2*sigma**2) 28 | k = -1./(np.pi * sigma**4) * (1 - f) * np.exp(-f) 29 | 30 | return k 31 | 32 | 33 | # Edge demo 34 | 35 | # Read Lena image 36 | lenaL = cv2.imread('../images/lena.png') 37 | cv2.imshow('Original image, color', lenaL) 38 | 39 | # Convert to monochrome (grayscale) using BGR2GRAY 40 | lenaMono = cv2.cvtColor(lenaL, cv2.COLOR_BGR2GRAY) 41 | cv2.imshow('Original image, monochrome', lenaMono) 42 | 43 | # Make a blurred/smoothed version 44 | h = cv2.getGaussianKernel(11, 4) 45 | h = h * h.T 46 | 47 | print(h) 48 | 49 | # Mimic Matlab's surf(h) 50 | surf(h) 51 | 52 | # The border type used below was set to show results similar to the demo 53 | lenaSmooth = cv2.filter2D(lenaMono, -1, h, borderType=cv2.BORDER_CONSTANT) 54 | cv2.imshow('Smoothed image', lenaSmooth) 55 | 56 | # Method 1: Shift left and right, and show diff image 57 | lenaL = np.copy(lenaSmooth) 58 | lenaL[:, :-1] = lenaL[:, 1:] 59 | 60 | lenaR = np.copy(lenaSmooth) 61 | lenaR[:, 1:] = lenaR[:, :-1] 62 | 63 | lenaDiff = 1. * lenaR - 1. * lenaL # Multiplying by 1. as a shortcut to converting array to float 64 | 65 | # Here we shift the value range to fit [0, 255] and make sure the data type is uint8 in order to display the results. 66 | lenaDiff = cv2.normalize(lenaDiff, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 67 | cv2.imshow('Difference between right and left shifted images', lenaDiff.astype(np.uint8)) 68 | 69 | # Method 2: Canny edge detector 70 | # OpenCV needs you to specify low and high threshold values. While these are not the 71 | # exactly the same as the ones used in the demo you should refer to the lines below 72 | # as a reference on how cv2.Canny works 73 | thresh1 = 110 74 | thresh2 = 60 75 | 76 | cannyEdges = cv2.Canny(lenaMono, thresh1, thresh2) 77 | cv2.imshow('Original edges', cannyEdges) 78 | 79 | cannyEdges = cv2.Canny(lenaSmooth, thresh1, thresh2) 80 | cv2.imshow('Edges of smoothed image', cannyEdges) 81 | 82 | # Method 3: Laplacian of Gaussian 83 | h = LoG(4, 1.) 84 | surf(h) 85 | 86 | logEdges = cv2.filter2D(1. * lenaMono, -1, h, borderType=cv2.BORDER_CONSTANT) 87 | logEdgesShow = cv2.normalize(logEdges, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 88 | 89 | cv2.imshow('Laplacian image before zero crossing', logEdgesShow.astype(np.uint8)) 90 | 91 | # OpenCV doesn't have a function edge like Matlab that implements a 'log' method. This would 92 | # have to be implemented from scratch. 93 | 94 | cv2.waitKey(0) 95 | -------------------------------------------------------------------------------- /2A-L6/answers/for_your_eyes_only.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # For Your Eyes Only 6 | frizzy = cv2.imread('../images/frizzy.png', 0) 7 | froomer = cv2.imread('../images/froomer.png', 0) 8 | cv2.imshow('Frizzy', frizzy) 9 | cv2.imshow('Froomer', froomer) 10 | 11 | # Find edges in frizzy and froomer images 12 | frizzy_edge = cv2.Canny(frizzy, 20, 100) 13 | froomer_edge = cv2.Canny(froomer, 20, 100) 14 | cv2.imshow('Frizzy Edge', frizzy_edge) 15 | cv2.imshow('Froomer Edge', froomer_edge) 16 | 17 | # Display common edge pixels 18 | common = frizzy_edge * froomer_edge 19 | cv2.imshow('Common', common.astype(np.float)) 20 | cv2.waitKey(0) 21 | -------------------------------------------------------------------------------- /2A-L6/edge_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import cv2\n", 11 | "\n", 12 | "import numpy as np\n", 13 | "import matplotlib.pyplot as plt\n", 14 | "\n", 15 | "from mpl_toolkits.mplot3d import Axes3D\n", 16 | "\n", 17 | "\n", 18 | "def surf(data):\n", 19 | " y = np.arange(0, data.shape[0])\n", 20 | " x = np.arange(0, data.shape[1])\n", 21 | " X, Y = np.meshgrid(x, y)\n", 22 | "\n", 23 | " fig = plt.figure()\n", 24 | " ax = fig.gca(projection='3d')\n", 25 | "\n", 26 | " ax.plot_surface(X, Y, data, rstride=1, cstride=1, linewidth=0,\n", 27 | " cmap='jet', antialiased=False)\n", 28 | "\n", 29 | " plt.show(block=False)\n", 30 | "\n", 31 | "\n", 32 | "def LoG(size, sigma):\n", 33 | " x = y = np.linspace(-size, size, 2*size+1)\n", 34 | " x, y = np.meshgrid(x, y)\n", 35 | "\n", 36 | " f = (x**2 + y**2)/(2*sigma**2)\n", 37 | " k = -1./(np.pi * sigma**4) * (1 - f) * np.exp(-f)\n", 38 | "\n", 39 | " return k\n", 40 | "\n", 41 | "\n", 42 | "# Edge demo\n", 43 | "\n", 44 | "# Read Lena image\n", 45 | "lenaL = cv2.imread('images/lena.png')\n", 46 | "plt.imshow(cv2.cvtColor(lenaL, cv2.COLOR_BGR2RGB))\n", 47 | "plt.show()" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": { 54 | "scrolled": false 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "# Convert to monochrome (grayscale) using BGR2GRAY.\n", 59 | "lenaMono = None # TODO: change this line with the call to cv2.cvtColor\n", 60 | "plt.imshow(lenaMono, cmap='gray')" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "# Make a blurred/smoothed version. Use cv2.getGaussianKernel to get the h kernel\n", 70 | "h = None # TODO: change this line with the call to cv2.getGaussianKernel\n", 71 | "\n", 72 | "print (h)\n", 73 | "\n", 74 | "# Mimic Matlab's surf(h)\n", 75 | "surf(h)\n", 76 | "\n", 77 | "# Use cv2.filter2D with BORDER_CONSTANT to get results similar to the Matlab demo\n", 78 | "lenaSmooth = None # TODO: use cv2.filter2D\n", 79 | "plt.imshow(lenaSmooth, cmap='gray')\n", 80 | "plt.show()" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "# Method 1: Shift left and right, and show diff image\n", 90 | "lenaL = np.copy(lenaSmooth) # Let's use np.copy to avoid modifying the original array\n", 91 | "# TODO: use numpy indexing to copy and paste the array to the right position\n", 92 | "\n", 93 | "lenaR = np.copy(lenaSmooth) # Let's use np.copy to avoid modifying the original array\n", 94 | "# TODO: use numpy indexing to copy and paste the array to the right position\n", 95 | "\n", 96 | "# TODO: Subtract lenaL from lenaR. Don't forget about using the correct data type\n", 97 | "lenaDiff = None # Change this line with the answer\n", 98 | "\n", 99 | "# Here we shift the value range to fit [0, 255] and make sure the data type is uint8 in order to display the results.\n", 100 | "lenaDiff = cv2.normalize(lenaDiff, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)\n", 101 | "plt.imshow(lenaDiff, cmap='gray')" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "# Method 2: Canny edge detector\n", 111 | "# OpenCV doesn't have a function similar to edge but it does have a Canny Edge detector\n", 112 | "# OpenCV needs you to specify low and high threshold values. While these are not the\n", 113 | "# exactly the same as the ones used in the demo you should refer to the lines below\n", 114 | "# as a reference on how cv2.Canny works\n", 115 | "thresh1 = 110\n", 116 | "thresh2 = 60\n", 117 | "\n", 118 | "cannyEdges = None # TODO: use cv2.Canny with lenaMono and the thresholds defined above\n", 119 | "plt.imshow(cannyEdges, cmap='gray')\n", 120 | "plt.show()\n", 121 | "\n", 122 | "cannyEdges = None # TODO: use cv2.Canny with lenaSmooth and the thresholds defined above\n", 123 | "plt.imshow(cannyEdges, cmap='gray')\n", 124 | "plt.show()" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [ 133 | "# Method 3: Laplacian of Gaussian\n", 134 | "h = LoG(4, 1.)\n", 135 | "surf(h)\n", 136 | "\n", 137 | "# Let's use cv2.filter2D with the new h\n", 138 | "logEdges = None # TODO: use cv2.filter2D\n", 139 | "logEdgesShow = cv2.normalize(logEdges, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)\n", 140 | "\n", 141 | "plt.imshow(logEdgesShow, cmap='gray')\n", 142 | "plt.title('Laplacian image before zero crossing')\n", 143 | "plt.show()\n", 144 | "\n", 145 | "# OpenCV doesn't have a function edge like Matlab that implements a 'log' method. This would\n", 146 | "# have to be implemented from scratch. This may take a little more time to implement this :)." 147 | ] 148 | } 149 | ], 150 | "metadata": { 151 | "kernelspec": { 152 | "display_name": "Python 3", 153 | "language": "python", 154 | "name": "python3" 155 | }, 156 | "language_info": { 157 | "codemirror_mode": { 158 | "name": "ipython", 159 | "version": 3 160 | }, 161 | "file_extension": ".py", 162 | "mimetype": "text/x-python", 163 | "name": "python", 164 | "nbconvert_exporter": "python", 165 | "pygments_lexer": "ipython3", 166 | "version": "3.5.5" 167 | } 168 | }, 169 | "nbformat": 4, 170 | "nbformat_minor": 2 171 | } 172 | -------------------------------------------------------------------------------- /2A-L6/edge_demo.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | from mpl_toolkits.mplot3d import Axes3D 7 | 8 | 9 | def surf(data): 10 | y = np.arange(0, data.shape[0]) 11 | x = np.arange(0, data.shape[1]) 12 | X, Y = np.meshgrid(x, y) 13 | 14 | fig = plt.figure() 15 | ax = fig.gca(projection='3d') 16 | 17 | ax.plot_surface(X, Y, data, rstride=1, cstride=1, linewidth=0, 18 | cmap='jet', antialiased=False) 19 | 20 | plt.show(block=False) 21 | 22 | 23 | def LoG(size, sigma): 24 | x = y = np.linspace(-size, size, 2*size+1) 25 | x, y = np.meshgrid(x, y) 26 | 27 | f = (x**2 + y**2)/(2*sigma**2) 28 | k = -1./(np.pi * sigma**4) * (1 - f) * np.exp(-f) 29 | 30 | return k 31 | 32 | 33 | # Edge demo 34 | 35 | # Read Lena image 36 | lenaL = cv2.imread('images/lena.png') 37 | cv2.imshow('Original image, color', lenaL) 38 | 39 | # Convert to monochrome (grayscale) using BGR2GRAY. 40 | lenaMono = None # TODO: change this line with the call to cv2.cvtColor 41 | cv2.imshow('Original image, monochrome', lenaMono) 42 | 43 | # Make a blurred/smoothed version. Use cv2.getGaussianKernel to get the h kernel 44 | h = None # TODO: change this line with the call to cv2.getGaussianKernel 45 | 46 | print( h) 47 | 48 | # Mimic Matlab's surf(h) 49 | surf(h) 50 | 51 | # Use cv2.filter2D with BORDER_CONSTANT to get results similar to the Matlab demo 52 | lenaSmooth = None # TODO: use cv2.filter2D 53 | cv2.imshow('Smoothed image', lenaSmooth) 54 | 55 | # Method 1: Shift left and right, and show diff image 56 | lenaL = np.copy(lenaSmooth) # Let's use np.copy to avoid modifying the original array 57 | # TODO: use numpy indexing to copy and paste the array to the right position 58 | 59 | lenaR = np.copy(lenaSmooth) # Let's use np.copy to avoid modifying the original array 60 | # TODO: use numpy indexing to copy and paste the array to the right position 61 | 62 | # TODO: Subtract lenaL from lenaR. Don't forget about using the correct data type 63 | lenaDiff = None # Change this line with the answer 64 | 65 | # Here we shift the value range to fit [0, 255] and make sure the data type is uint8 in order to display the results. 66 | lenaDiff = cv2.normalize(lenaDiff, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 67 | cv2.imshow('Difference between right and left shifted images', lenaDiff.astype(np.uint8)) 68 | 69 | # Method 2: Canny edge detector 70 | # OpenCV doesn't have a function similar to edge but it does have a Canny Edge detector 71 | # OpenCV needs you to specify low and high threshold values. While these are not the 72 | # exactly the same as the ones used in the demo you should refer to the lines below 73 | # as a reference on how cv2.Canny works 74 | thresh1 = 110 75 | thresh2 = 60 76 | 77 | cannyEdges = None # TODO: use cv2.Canny with lenaMono and the thresholds defined above 78 | cv2.imshow('Original edges', cannyEdges) 79 | 80 | cannyEdges = None # TODO: use cv2.Canny with lenaSmooth and the thresholds defined above 81 | cv2.imshow('Edges of smoothed image', cannyEdges) 82 | 83 | # Method 3: Laplacian of Gaussian 84 | h = LoG(4, 1.) 85 | surf(h) 86 | 87 | # Let's use cv2.filter2D with the new h 88 | logEdges = None # TODO: use cv2.filter2D 89 | logEdgesShow = cv2.normalize(logEdges, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) 90 | 91 | cv2.imshow('Laplacian image before zero crossing', logEdgesShow.astype(np.uint8)) 92 | 93 | # OpenCV doesn't have a function edge like Matlab that implements a 'log' method. This would 94 | # have to be implemented from scratch. This may take a little more time to implement this :). 95 | 96 | cv2.waitKey(0) 97 | -------------------------------------------------------------------------------- /2A-L6/for_your_eyes_only.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "\n", 15 | "# For Your Eyes Only\n", 16 | "frizzy = cv2.imread('images/frizzy.png')\n", 17 | "froomer = cv2.imread('images/froomer.png')\n", 18 | "plt.imshow(cv2.cvtColor(frizzy, cv2.COLOR_BGR2RGB))\n", 19 | "plt.show()\n", 20 | "plt.imshow(cv2.cvtColor(froomer, cv2.COLOR_BGR2RGB))" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "# TODO: Find edges in frizzy and froomer images\n", 30 | "\n", 31 | "\n", 32 | "\n", 33 | "plt.imshow(cv2.cvtColor(frizzy, cv2.COLOR_BGR2RGB))\n", 34 | "plt.show()\n", 35 | "plt.imshow(cv2.cvtColor(froomer, cv2.COLOR_BGR2RGB))" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "# TODO: Display common edge pixels\n", 45 | "\n", 46 | "\n", 47 | "\n", 48 | "plt.imshow(cv2.cvtColor(frizzy, cv2.COLOR_BGR2RGB))\n", 49 | "plt.show()\n", 50 | "plt.imshow(cv2.cvtColor(froomer, cv2.COLOR_BGR2RGB))" 51 | ] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Python 3", 57 | "language": "python", 58 | "name": "python3" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": { 62 | "name": "ipython", 63 | "version": 3 64 | }, 65 | "file_extension": ".py", 66 | "mimetype": "text/x-python", 67 | "name": "python", 68 | "nbconvert_exporter": "python", 69 | "pygments_lexer": "ipython3", 70 | "version": "3.5.5" 71 | } 72 | }, 73 | "nbformat": 4, 74 | "nbformat_minor": 2 75 | } 76 | -------------------------------------------------------------------------------- /2A-L6/for_your_eyes_only.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # For Your Eyes Only 6 | frizzy = cv2.imread('images/frizzy.png') 7 | froomer = cv2.imread('images/froomer.png') 8 | cv2.imshow('Frizzy', frizzy) 9 | cv2.imshow('Froomer', froomer) 10 | 11 | 12 | # TODO: Find edges in frizzy and froomer images 13 | 14 | # TODO: Display common edge pixels 15 | -------------------------------------------------------------------------------- /2A-L6/images/frizzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L6/images/frizzy.png -------------------------------------------------------------------------------- /2A-L6/images/froomer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L6/images/froomer.png -------------------------------------------------------------------------------- /2A-L6/images/lena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/2A-L6/images/lena.png -------------------------------------------------------------------------------- /3A-L2/answers/project_a_point.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | # Project a point from 3D to 2D using a matrix operation 5 | 6 | # Given: Point p in 3-space [x y z], and focal length f 7 | # Return: Location of projected point on 2D image plane [u v] 8 | 9 | 10 | def project_point(p, f): 11 | # TODO: Define and apply projection matrix 12 | H = np.array([[1, 0, 0, 0], 13 | [0, 1, 0, 0], 14 | [0, 0, 1./f, 0]]) 15 | 16 | p2 = np.hstack((p, np.array([[1]]))) 17 | res = np.dot(H, p2.T) 18 | return res[0, 0] / res[2, 0], res[1, 0] / res[2, 0] 19 | 20 | # Test: Given point and focal length (units: mm) 21 | p = np.array([[200, 100, 120]]) 22 | f = 50 23 | 24 | print( project_point(p, f)) 25 | -------------------------------------------------------------------------------- /3A-L2/project_a_point.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "# Project a point from 3D to 2D using a matrix operation\n", 15 | "\n", 16 | "# Given: Point p in 3-space [x y z], and focal length f\n", 17 | "# Return: Location of projected point on 2D image plane [u v]\n", 18 | "\n", 19 | "\n", 20 | "def project_point(p, f):\n", 21 | " # TODO: Define and apply projection matrix\n", 22 | " pass\n", 23 | "\n", 24 | "# Test: Given point and focal length (units: mm)\n", 25 | "p = np.array([[200, 100, 120]])\n", 26 | "f = 50\n", 27 | "\n", 28 | "print (project_point(p, f))" 29 | ] 30 | } 31 | ], 32 | "metadata": { 33 | "kernelspec": { 34 | "display_name": "Python 3", 35 | "language": "python", 36 | "name": "python3" 37 | }, 38 | "language_info": { 39 | "codemirror_mode": { 40 | "name": "ipython", 41 | "version": 3 42 | }, 43 | "file_extension": ".py", 44 | "mimetype": "text/x-python", 45 | "name": "python", 46 | "nbconvert_exporter": "python", 47 | "pygments_lexer": "ipython3", 48 | "version": "3.5.5" 49 | } 50 | }, 51 | "nbformat": 4, 52 | "nbformat_minor": 2 53 | } 54 | -------------------------------------------------------------------------------- /3A-L2/project_a_point.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | # Project a point from 3D to 2D using a matrix operation 5 | 6 | # Given: Point p in 3-space [x y z], and focal length f 7 | # Return: Location of projected point on 2D image plane [u v] 8 | 9 | 10 | def project_point(p, f): 11 | # TODO: Define and apply projection matrix 12 | pass 13 | 14 | # Test: Given point and focal length (units: mm) 15 | p = np.array([[200, 100, 120]]) 16 | f = 50 17 | 18 | print (project_point(p, f)) -------------------------------------------------------------------------------- /3B-L3/answers/find_best_match.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Find best match 6 | def find_best_match(patch, strip): 7 | # TODO: Find patch in strip and return column index (x value) of topleft corner 8 | 9 | # We will use SSD to find out the best match 10 | 11 | best_id = 0 12 | min_diff = np.infty 13 | 14 | for i in range(int(strip.shape[1] - patch.shape[1])): 15 | temp = strip[:, i: i + patch.shape[1]] 16 | ssd = np.sum((temp - patch) ** 2) 17 | if ssd < min_diff: 18 | min_diff = ssd 19 | best_id = i 20 | 21 | return best_id 22 | 23 | # Test code: 24 | 25 | # Load images 26 | left = cv2.imread('../images/flowers-left.png') 27 | right = cv2.imread('../images/flowers-right.png') 28 | cv2.imshow('Left', left) 29 | cv2.imshow('Right', right) 30 | 31 | # Convert to grayscale, double, [0, 1] range for easier computation 32 | left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255. 33 | right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255. 34 | 35 | # Define image patch location (topleft [row col]) and size 36 | patch_loc = [94, 119] # Adapted index values to approximate the difference with the original images shapes 37 | patch_size = [100, 100] 38 | 39 | # Extract patch (from left image) 40 | patch_left = left_gray[patch_loc[0]:patch_loc[0] + patch_size[0], 41 | patch_loc[1]:patch_loc[1] + patch_size[1]] 42 | cv2.imshow('Patch', patch_left) 43 | 44 | # Extract strip (from right image) 45 | strip_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0], :] 46 | cv2.imshow('Strip', strip_right) 47 | 48 | # Now look for the patch in the strip and report the best position (column index of topleft corner) 49 | best_x = find_best_match(patch_left, strip_right) 50 | print( best_x) 51 | 52 | patch_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0], 53 | best_x: best_x + patch_size[1]] 54 | 55 | # Because we had to adjust the index numbers for this quiz, we will 56 | # plot a rectangle where the best match is in the right image. This 57 | # will help us verify if what we did was correct. 58 | cv2.rectangle(right, (best_x, patch_loc[0]), 59 | (best_x + patch_size[0], patch_loc[0] + patch_size[0]), 60 | (0, 0, 255), 61 | 2) 62 | cv2.imshow("Match", right) 63 | cv2.waitKey(0) 64 | -------------------------------------------------------------------------------- /3B-L3/answers/match_two_strips.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | # Find best match from the previous quiz 7 | def find_best_match(patch, strip): 8 | 9 | # We will use SSD to find out the best match 10 | best_id = 0 11 | min_diff = np.infty 12 | 13 | for i in range(int(strip.shape[1] - patch.shape[1])): 14 | temp = strip[:, i: i + patch.shape[1]] 15 | ssd = np.sum((temp - patch) ** 2) 16 | if ssd < min_diff: 17 | min_diff = ssd 18 | best_id = i 19 | 20 | return best_id 21 | 22 | 23 | def match_strips(strip_left, strip_right, b): 24 | # For each non-overlapping patch/block of width b in the left strip, 25 | # find the best matching position (along X-axis) in the right strip. 26 | # Return a vector of disparities (left X-position - right X-position). 27 | # Note: Only consider whole blocks that fit within image bounds. 28 | 29 | num_blocks = int(np.floor(strip_left.shape[1] / b)) 30 | disparity = np.zeros((1, num_blocks)) 31 | 32 | for block in range(num_blocks): 33 | x_left = block * b 34 | patch_left = strip_left[:, x_left: x_left + b] 35 | x_right = find_best_match(patch_left, strip_right) 36 | disparity[0, block] = x_left - x_right 37 | 38 | return disparity 39 | 40 | # Test code: 41 | 42 | # Load images 43 | left = cv2.imread('../images/flowers-left.png') 44 | right = cv2.imread('../images/flowers-right.png') 45 | cv2.imshow('Left', left) 46 | cv2.imshow('Right', right) 47 | 48 | # Convert to grayscale, double, [0, 1] range for easier computation 49 | left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255. 50 | right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255. 51 | 52 | # Define strip row (y) and square block size (b) 53 | y = 120 54 | b = 100 55 | 56 | # Extract strip from left image 57 | strip_left = left_gray[y: y + b, :] 58 | cv2.imshow('Strip Left', strip_left) 59 | 60 | # Extract strip from right image 61 | strip_right = right_gray[y: y + b, :] 62 | cv2.imshow('Strip Right', strip_right) 63 | 64 | # Now match these two strips to compute disparity values 65 | disparity = match_strips(strip_left, strip_right, b) 66 | print( disparity[0]) 67 | 68 | # Finally we plot the disparity values. Note that there may be some differences 69 | # in the results shown in the quiz because we had to adapt the index values. 70 | plt.plot(range(disparity.shape[1]), disparity[0]) 71 | plt.show() 72 | plt.close('all') 73 | -------------------------------------------------------------------------------- /3B-L3/find_best_match.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "\n", 15 | "# Test code:\n", 16 | "\n", 17 | "# Load images\n", 18 | "left = cv2.imread('images/flowers-left.png')\n", 19 | "right = cv2.imread('images/flowers-right.png')\n", 20 | "plt.imshow(cv2.cvtColor(left, cv2.COLOR_BGR2RGB))\n", 21 | "plt.show()\n", 22 | "plt.imshow(cv2.cvtColor(right, cv2.COLOR_BGR2RGB))" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# Convert to grayscale, double, [0, 1] range for easier computation\n", 32 | "left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255.\n", 33 | "right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255.\n", 34 | "\n", 35 | "# Define image patch location (topleft [row col]) and size\n", 36 | "patch_loc = [94, 119] # Adapted index values to approximate the difference with the original images shapes\n", 37 | "patch_size = [100, 100]\n", 38 | "\n", 39 | "# Extract patch (from left image)\n", 40 | "patch_left = left_gray[patch_loc[0]:patch_loc[0] + patch_size[0],\n", 41 | " patch_loc[1]:patch_loc[1] + patch_size[1]]\n", 42 | "plt.imshow(patch_left, cmap='gray')\n", 43 | "plt.show()\n", 44 | "\n", 45 | "# Extract strip (from right image)\n", 46 | "strip_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0], :]\n", 47 | "plt.imshow(strip_right, cmap='gray')" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "# Now look for the patch in the strip and report the best position (column index of topleft corner)\n", 57 | "\n", 58 | "# Find best match\n", 59 | "def find_best_match(patch, strip):\n", 60 | " # TODO: Find patch in strip and return column index (x value) of topleft corner\n", 61 | " pass\n", 62 | "\n", 63 | "\n", 64 | "best_x = find_best_match(patch_left, strip_right)\n", 65 | "print (best_x)\n", 66 | "\n", 67 | "patch_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0],\n", 68 | " best_x: best_x + patch_size[1]]\n", 69 | "\n" 70 | ] 71 | } 72 | ], 73 | "metadata": { 74 | "kernelspec": { 75 | "display_name": "Python 3", 76 | "language": "python", 77 | "name": "python3" 78 | }, 79 | "language_info": { 80 | "codemirror_mode": { 81 | "name": "ipython", 82 | "version": 3 83 | }, 84 | "file_extension": ".py", 85 | "mimetype": "text/x-python", 86 | "name": "python", 87 | "nbconvert_exporter": "python", 88 | "pygments_lexer": "ipython3", 89 | "version": "3.5.5" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 2 94 | } 95 | -------------------------------------------------------------------------------- /3B-L3/find_best_match.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | # Find best match 6 | def find_best_match(patch, strip): 7 | # TODO: Find patch in strip and return column index (x value) of topleft corner 8 | pass 9 | 10 | # Test code: 11 | 12 | # Load images 13 | left = cv2.imread('images/flowers-left.png') 14 | right = cv2.imread('images/flowers-right.png') 15 | cv2.imshow('Left', left) 16 | cv2.imshow('Right', right) 17 | 18 | # Convert to grayscale, double, [0, 1] range for easier computation 19 | left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255. 20 | right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255. 21 | 22 | # Define image patch location (topleft [row col]) and size 23 | patch_loc = [94, 119] # Adapted index values to approximate the difference with the original images shapes 24 | patch_size = [100, 100] 25 | 26 | # Extract patch (from left image) 27 | patch_left = left_gray[patch_loc[0]:patch_loc[0] + patch_size[0], 28 | patch_loc[1]:patch_loc[1] + patch_size[1]] 29 | cv2.imshow('Patch', patch_left) 30 | 31 | # Extract strip (from right image) 32 | strip_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0], :] 33 | cv2.imshow('Strip', strip_right) 34 | 35 | # Now look for the patch in the strip and report the best position (column index of topleft corner) 36 | best_x = find_best_match(patch_left, strip_right) 37 | print( best_x) 38 | 39 | patch_right = right_gray[patch_loc[0]: patch_loc[0] + patch_size[0], 40 | best_x: best_x + patch_size[1]] 41 | 42 | cv2.waitKey(0) 43 | -------------------------------------------------------------------------------- /3B-L3/images/flowers-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/3B-L3/images/flowers-left.png -------------------------------------------------------------------------------- /3B-L3/images/flowers-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/3B-L3/images/flowers-right.png -------------------------------------------------------------------------------- /3B-L3/match_two_strips.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import cv2\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "\n", 14 | "\n", 15 | "# We will use the function implemented in the last quiz\n", 16 | "# Find best match\n", 17 | "def find_best_match(patch, strip):\n", 18 | " # TODO: Find patch in strip and return column index (x value) of topleft corner\n", 19 | " # Paste your answer from the previous quiz here\n", 20 | " pass\n", 21 | "\n", 22 | "\n", 23 | "# Test code:\n", 24 | "\n", 25 | "# Load images\n", 26 | "left = cv2.imread('images/flowers-left.png')\n", 27 | "right = cv2.imread('images/flowers-right.png')\n", 28 | "plt.imshow(cv2.cvtColor(left, cv2.COLOR_BGR2RGB))\n", 29 | "plt.show()\n", 30 | "plt.imshow(cv2.cvtColor(right, cv2.COLOR_BGR2RGB))\n", 31 | "plt.show()" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "# Convert to grayscale, double, [0, 1] range for easier computation\n", 41 | "left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255.\n", 42 | "right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255.\n", 43 | "\n", 44 | "# Define strip row (y) and square block size (b)\n", 45 | "y = 120\n", 46 | "b = 100\n", 47 | "\n", 48 | "# Extract strip from left image\n", 49 | "strip_left = left_gray[y: y + b, :]\n", 50 | "plt.imshow(strip_left, cmap='gray')\n", 51 | "plt.title('strip left')\n", 52 | "plt.show()\n", 53 | "\n", 54 | "# Extract strip from right image\n", 55 | "strip_right = right_gray[y: y + b, :]\n", 56 | "plt.imshow(strip_right, cmap='gray')\n", 57 | "plt.title('strip right')\n", 58 | "plt.show()" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "def match_strips(strip_left, strip_right, b):\n", 68 | " # For each non-overlapping patch/block of width b in the left strip,\n", 69 | " # find the best matching position (along X-axis) in the right strip.\n", 70 | " # Return a vector of disparities (left X-position - right X-position).\n", 71 | " # Note: Only consider whole blocks that fit within image bounds.\n", 72 | " pass\n", 73 | "\n", 74 | "# Now match these two strips to compute disparity values\n", 75 | "disparity = match_strips(strip_left, strip_right, b)\n", 76 | "print (disparity)\n", 77 | "\n", 78 | "# Finally we plot the disparity values. Note that there may be some differences\n", 79 | "# in the results shown in the quiz because we had to adapt the index values.\n", 80 | "plt.plot(range(disparity.shape[1]), disparity[0])\n", 81 | "plt.show()" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [] 90 | } 91 | ], 92 | "metadata": { 93 | "kernelspec": { 94 | "display_name": "Python 3", 95 | "language": "python", 96 | "name": "python3" 97 | }, 98 | "language_info": { 99 | "codemirror_mode": { 100 | "name": "ipython", 101 | "version": 3 102 | }, 103 | "file_extension": ".py", 104 | "mimetype": "text/x-python", 105 | "name": "python", 106 | "nbconvert_exporter": "python", 107 | "pygments_lexer": "ipython3", 108 | "version": "3.5.5" 109 | } 110 | }, 111 | "nbformat": 4, 112 | "nbformat_minor": 2 113 | } 114 | -------------------------------------------------------------------------------- /3B-L3/match_two_strips.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | # We will use the function implemented in the last quiz 7 | # Find best match 8 | def find_best_match(patch, strip): 9 | # TODO: Find patch in strip and return column index (x value) of topleft corner 10 | # Paste your answer from the previous quiz here 11 | pass 12 | 13 | 14 | def match_strips(strip_left, strip_right, b): 15 | # For each non-overlapping patch/block of width b in the left strip, 16 | # find the best matching position (along X-axis) in the right strip. 17 | # Return a vector of disparities (left X-position - right X-position). 18 | # Note: Only consider whole blocks that fit within image bounds. 19 | pass 20 | 21 | # Test code: 22 | 23 | # Load images 24 | left = cv2.imread('images/flowers-left.png') 25 | right = cv2.imread('images/flowers-right.png') 26 | cv2.imshow('Left', left) 27 | cv2.imshow('Right', right) 28 | 29 | # Convert to grayscale, double, [0, 1] range for easier computation 30 | left_gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY) / 255. 31 | right_gray = cv2.cvtColor(right, cv2.COLOR_BGR2GRAY) / 255. 32 | 33 | # Define strip row (y) and square block size (b) 34 | y = 120 35 | b = 100 36 | 37 | # Extract strip from left image 38 | strip_left = left_gray[y: y + b, :] 39 | cv2.imshow('Strip Left', strip_left) 40 | 41 | # Extract strip from right image 42 | strip_right = right_gray[y: y + b, :] 43 | cv2.imshow('Strip Right', strip_right) 44 | 45 | # Now match these two strips to compute disparity values 46 | disparity = match_strips(strip_left, strip_right, b) 47 | print( disparity) 48 | 49 | # Finally we plot the disparity values. Note that there may be some differences 50 | # in the results shown in the quiz because we had to adapt the index values. 51 | plt.plot(range(disparity.shape[1]), disparity[0]) 52 | plt.show() 53 | plt.close('all') 54 | -------------------------------------------------------------------------------- /6B-L3/answers/downsample_an_image.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | 4 | def downsample(img): 5 | # TODO: img_d = ? (pick alternate rows, cols: 1, 3, 5, ...) 6 | img_d = img[::2, ::2, :] 7 | return img_d 8 | 9 | 10 | def blur_downsample(img): 11 | # TODO img_bd = ? (blur by 5x5 gaussian, then downsample) 12 | img_bd = cv2.GaussianBlur(img, (5, 5), 0, 0)[::2, ::2, :] 13 | return img_bd 14 | 15 | 16 | img = cv2.imread('../images/frizzy.png') 17 | cv2.imshow("original_image", img) 18 | print(img.shape) 19 | 20 | # downsample image 21 | img_d = downsample(img) 22 | img_d = downsample(img_d) 23 | img_d = downsample(img_d) 24 | print(img_d.shape) 25 | 26 | # blur and downsample 27 | img_bd = blur_downsample(img) 28 | img_bd = blur_downsample(img_bd) 29 | img_bd = blur_downsample(img_bd) 30 | print(img_bd.shape) 31 | 32 | cv2.imshow("downsampled_image", cv2.resize(img_d, (img.shape[1], img.shape[0]))) 33 | cv2.imshow("blur_downsampled_image", cv2.resize(img_bd, (img.shape[1], img.shape[0]))) 34 | cv2.waitKey(0) 35 | -------------------------------------------------------------------------------- /6B-L3/downsample_an_image.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "\n", 13 | "\n", 14 | "img = cv2.imread('images/frizzy.png')\n", 15 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 16 | "plt.title('original image')\n", 17 | "plt.show()\n", 18 | "print(img.shape)" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "def downsample(img):\n", 28 | " # TODO: img_d = ? (pick alternate rows, cols: 1, 3, 5, ...)\n", 29 | " pass\n", 30 | "\n", 31 | "# downsample image\n", 32 | "img_d = downsample(img)\n", 33 | "img_d = downsample(img_d)\n", 34 | "img_d = downsample(img_d)\n", 35 | "print(img_d.shape)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "def blur_downsample(img):\n", 45 | " # TODO img_bd = ? (blur by 5x5 gaussian, then downsample)\n", 46 | " pass\n", 47 | "\n", 48 | "# blur and downsample\n", 49 | "img_bd = blur_downsample(img)\n", 50 | "img_bd = blur_downsample(img_bd)\n", 51 | "img_bd = blur_downsample(img_bd)\n", 52 | "print(img_bd.shape)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "img_d = cv2.resize(img_d, (img.shape[1], img.shape[0]))\n", 62 | "plt.imshow(cv2.cvtColor(img_d, cv2.COLOR_BGR2RGB))\n", 63 | "plt.title(\"downsampled_image\")\n", 64 | "plt.show()\n", 65 | "\n", 66 | "img_bd = cv2.resize(img_bd, (img.shape[1], img.shape[0]))\n", 67 | "plt.imshow(cv2.cvtColor(img_bd, cv2.COLOR_BGR2RGB))\n", 68 | "plt.title(\"blur_downsampled_image\")\n", 69 | "plt.show()" 70 | ] 71 | } 72 | ], 73 | "metadata": { 74 | "kernelspec": { 75 | "display_name": "Python 3", 76 | "language": "python", 77 | "name": "python3" 78 | }, 79 | "language_info": { 80 | "codemirror_mode": { 81 | "name": "ipython", 82 | "version": 3 83 | }, 84 | "file_extension": ".py", 85 | "mimetype": "text/x-python", 86 | "name": "python", 87 | "nbconvert_exporter": "python", 88 | "pygments_lexer": "ipython3", 89 | "version": "3.5.5" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 2 94 | } 95 | -------------------------------------------------------------------------------- /6B-L3/downsample_an_image.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | 4 | def downsample(img): 5 | # TODO: img_d = ? (pick alternate rows, cols: 1, 3, 5, ...) 6 | pass 7 | 8 | 9 | def blur_downsample(img): 10 | # TODO img_bd = ? (blur by 5x5 gaussian, then downsample) 11 | pass 12 | 13 | 14 | img = cv2.imread('images/frizzy.png') 15 | cv2.imshow("original_image", img) 16 | print(img.shape) 17 | 18 | # downsample image 19 | img_d = downsample(img) 20 | img_d = downsample(img_d) 21 | img_d = downsample(img_d) 22 | print(img_d.shape) 23 | 24 | # blur and downsample 25 | img_bd = blur_downsample(img) 26 | img_bd = blur_downsample(img_bd) 27 | img_bd = blur_downsample(img_bd) 28 | print(img_bd.shape) 29 | 30 | cv2.imshow("downsampled_image", cv2.resize(img_d, (img.shape[1], img.shape[0]))) 31 | cv2.imshow("blur_downsampled_image", cv2.resize(img_bd, (img.shape[1], img.shape[0]))) 32 | cv2.waitKey(0) 33 | -------------------------------------------------------------------------------- /6B-L3/images/frizzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/6B-L3/images/frizzy.png -------------------------------------------------------------------------------- /8C-L2/answers/compute_integral_image.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | def compute_integral(img): 6 | # TODO: Compute I such that I(y,x) = sum of img(1,1) to img(y,x) 7 | I = np.cumsum(np.cumsum(img, 0), 1) 8 | return I 9 | 10 | 11 | img = cv2.imread('../images/dolphin.png', 0) 12 | cv2.imshow("original_image", img) 13 | print(img.shape) 14 | 15 | # compute integral 16 | img = np.float64(img) 17 | I = compute_integral(img) 18 | cv2.imshow("integral_image", (I / I.max())) 19 | 20 | x1 = 150 21 | y1 = 100 22 | x2 = 350 23 | y2 = 200 24 | 25 | print("Sum: ", np.sum(img[y1:y2 + 1, x1:x2 + 1])) 26 | print(I[y2, x2] - I[y1 - 1, x2] - I[y2, x1 - 1] + I[y1 - 1, x1 - 1]) 27 | 28 | cv2.waitKey(0) 29 | -------------------------------------------------------------------------------- /8C-L2/compute_integral_image.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "import cv2\n", 12 | "import numpy as np\n", 13 | "\n", 14 | "\n", 15 | "img = cv2.imread('images/dolphin.png', 0)\n", 16 | "plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n", 17 | "plt.title('original image')\n", 18 | "plt.show()\n", 19 | "print(img.shape)" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "def compute_integral(img):\n", 29 | " # TODO: Compute I such that I(y,x) = sum of img(1,1) to img(y,x)\n", 30 | " pass\n", 31 | "\n", 32 | "# compute integral\n", 33 | "img = np.float64(img)\n", 34 | "I = compute_integral(img)\n", 35 | "integral = (I / I.max())\n", 36 | "plt.imshow(integral, cmap='gray')\n", 37 | "plt.title('integral image')\n", 38 | "plt.show()\n", 39 | "\n", 40 | "x1 = 150\n", 41 | "y1 = 100\n", 42 | "x2 = 350\n", 43 | "y2 = 200\n", 44 | "\n", 45 | "print(\"Sum: \", np.sum(img[y1:y2 + 1, x1:x2 + 1]))\n", 46 | "print(I[y2, x2] - I[y1 - 1, x2] - I[y2, x1 - 1] + I[y1 - 1, x1 - 1])\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 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.5.5" 74 | } 75 | }, 76 | "nbformat": 4, 77 | "nbformat_minor": 2 78 | } 79 | -------------------------------------------------------------------------------- /8C-L2/compute_integral_image.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | def compute_integral(img): 6 | # TODO: Compute I such that I(y,x) = sum of img(1,1) to img(y,x) 7 | pass 8 | 9 | 10 | img = cv2.imread('images/dolphin.png', 0) 11 | cv2.imshow("original_image", img) 12 | print(img.shape) 13 | 14 | # compute integral 15 | img = np.float64(img) 16 | I = compute_integral(img) 17 | cv2.imshow("integral_image", (I / I.max())) 18 | 19 | x1 = 150 20 | y1 = 100 21 | x2 = 350 22 | y2 = 200 23 | 24 | print("Sum: ", np.sum(img[y1:y2 + 1, x1:x2 + 1])) 25 | print(I[y2, x2] - I[y1 - 1, x2] - I[y2, x1 - 1] + I[y1 - 1, x1 - 1]) 26 | 27 | cv2.waitKey(0) 28 | -------------------------------------------------------------------------------- /8C-L2/images/dolphin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdvelez/CV-lecture-quizzes-python/ca47ac17e7010e3caf72dbd0bfd9706d6a4accba/8C-L2/images/dolphin.png -------------------------------------------------------------------------------- /py2nb.py: -------------------------------------------------------------------------------- 1 | '''Convert py script to ipynb notebook 2 | 3 | This script finds all .py in the lesson subdirectories and converts 4 | them to Jupyter notebooks. It excludes the answers dir and itself. 5 | 6 | Tested on Linux; no cross-OS guarantees. 7 | 8 | Source modified from https://stackoverflow.com/questions/23292242/converting-to-not-from-ipython-notebook-format/35720002#35720002 9 | ''' 10 | 11 | from nbformat import v3, v4 12 | from pathlib import Path 13 | import re 14 | 15 | p = Path('./') 16 | pysrc = list(p.glob('[0-9]*L*/**/*.py')) 17 | 18 | print(pysrc) 19 | 20 | for src in pysrc: 21 | if 'answers' in str(src.parent): 22 | print('Skipping: {}'.format(src)) 23 | pass 24 | else: 25 | # print('Writing file: {} to dir {}'.format(src.name, src.parent)) 26 | with open(str(src)) as infile: 27 | text = infile.read() 28 | 29 | # Add matplotlib import 30 | if 'matplotlib' not in text: 31 | text = '%matplotlib inline\nimport matplotlib.pyplot as plt\n' + text 32 | else: 33 | text = '%matplotlib inline\n' + text 34 | 35 | # Convert and write the notebooks 36 | notebook = v3.read_py(text) 37 | notebook = v4.upgrade(notebook) 38 | jsonform = v4.writes(notebook) + "\n" 39 | outfile = re.sub('\.py', '.ipynb', str(src)) 40 | with open(outfile, 'w') as fpout: 41 | fpout.write(jsonform) 42 | print('Converted {} to {}'.format(str(src), outfile)) 43 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Introduction to Computer Vision 2 | 3 | This repository contains an **unofficial** python version of the Matlab quizzes available at GT's / Udacity's Introduction to Computer Vision. 4 | 5 | The code available was implemented to closely mimic the results shown in each quiz. 6 | 7 | The Jupyter Notebook files were converted automatically based on the following Stack Overflow response: 8 | https://stackoverflow.com/questions/23292242/converting-to-not-from-ipython-notebook-format 9 | 10 | For the Notebooks, all calls to cv2.imshow were converted to inline calls to matplotlib imshow. Sources: 11 | https://stackoverflow.com/questions/34643747/ipython-notebook-jupyter-opencv-cv2-and-plotting 12 | 13 | 14 | ## Available quizzes: 15 | 16 | * 2A-L1 17 | * 2A-L2 18 | * 2A-L3 19 | * 2A-L4 20 | * 2A-L6 21 | * 3A-L2 22 | * 3B-L3 23 | * 6B-L3 24 | * 8C-L2 25 | --------------------------------------------------------------------------------