├── .gitignore ├── README.md ├── core_operations ├── README.md ├── arithmetics_operations_on_images │ ├── README.md │ ├── Thumbs.db │ ├── add_images.py │ ├── bitwise_operate_images.py │ ├── blend_images.py │ ├── demo_image_arithmetics.py │ ├── image_thresholding.py │ ├── images │ │ ├── iron_man.png │ │ ├── iron_man_400px_by_500px.png │ │ ├── messi_717px_by_483px.jpg │ │ ├── opencv_logo_200px_by_246px.png │ │ ├── tony_stark.png │ │ └── tony_stark_400px_by_500px.png │ ├── iron_man_400px_by_500px.png │ ├── messi_717px_by_483px.png │ ├── messi_grayscale.jpg │ ├── opencv_logo_black_background.png │ ├── opencv_logo_white_background.png │ ├── screenshots │ │ ├── add_images.png │ │ ├── blend_images.png │ │ ├── dst.png │ │ ├── img1_bg.png │ │ ├── img2_fg.png │ │ ├── img2_opencv_logo_black_background.png │ │ ├── img2gray.png │ │ ├── img_thresholding_THRESH_BINARY.png │ │ ├── img_thresholding_THRESH_BINARY_INV.png │ │ ├── img_thresholding_THRESH_TO_ZERO.png │ │ ├── img_thresholding_THRESH_TO_ZERO_INV.png │ │ ├── img_thresholding_THRESH_TRUNC.png │ │ ├── img_thresholding_grayscale.png │ │ ├── ironman.png │ │ ├── mask.png │ │ ├── mask_inv.png │ │ ├── messi.png │ │ ├── res.png │ │ ├── roi.png │ │ └── tony_stark.png │ └── tony_stark_400px_by_500px.png ├── basic_operations_on_images │ ├── README.md │ ├── demo_add_border_to_image.py │ ├── demo_modify_image.py │ ├── messi.jpg │ └── screenshots │ │ ├── border_constant_blue.png │ │ ├── border_original.png │ │ ├── border_reflect.png │ │ ├── border_reflect_101.png │ │ ├── border_replicate.png │ │ ├── border_wrap.png │ │ ├── img_1.png │ │ ├── img_2.png │ │ ├── img_3.png │ │ ├── img_4.png │ │ ├── img_5.png │ │ ├── img_6.png │ │ └── img_7.png └── performance_measurement_and_improvement_techniques │ ├── README.md │ ├── demo_time_code.py │ ├── messi.jpg │ └── messi_grayscale.jpg ├── gui_features_in_opencv ├── README.md ├── drawing_functions_in_opencv │ ├── README.md │ ├── output.jpg │ ├── run_tutorial.py │ └── screenshots │ │ ├── screenshot_run_in_spyder_1.png │ │ └── screenshot_run_in_spyder_2.png ├── getting_started_with_images │ ├── README.md │ ├── load_image.py │ ├── messi.jpg │ ├── messi_grayscale.jpg │ ├── screenshots │ │ ├── screenshot_cv2_vs_pyplot.png │ │ ├── screenshot_run_in_spyder_1.png │ │ └── screenshot_run_in_spyder_2.png │ └── show_cv2_vs_pyplot.py ├── getting_started_with_videos │ ├── README.md │ ├── input.mp4 │ ├── load_video.py │ ├── output.avi │ └── screenshots │ │ └── before_vs_after.png ├── mouse_as_a_paint_brush │ ├── README.md │ ├── draw_circle_demo.py │ ├── print_available_events.py │ ├── run_advanced_demo.py │ └── screenshots │ │ ├── advanced_demo_1.PNG │ │ ├── advanced_demo_2.PNG │ │ ├── advanced_demo_3.PNG │ │ ├── circle_demo_1.PNG │ │ ├── circle_demo_2.PNG │ │ └── circle_demo_3.PNG └── trackbar_as_the_color_palette │ ├── README.md │ ├── run_trackbar_tutorial.py │ └── screenshots │ ├── trackbar_1.png │ ├── trackbar_2.png │ ├── trackbar_3.png │ ├── trackbar_4.png │ ├── trackbar_5.png │ └── trackbar_6.png └── image_processing_in_opencv ├── README.md ├── canny_edge_detection ├── README.md ├── messi.jpg ├── screenshots │ ├── simple_canny.png │ ├── trackbar_canny_1.png │ ├── trackbar_canny_2.png │ ├── trackbar_canny_3.png │ ├── trackbar_canny_4.png │ ├── trackbar_canny_5.png │ ├── trackbar_canny_6.png │ ├── trackbar_canny_7.png │ └── youtube_thumb.png ├── simple_canny.py └── trackbar_canny.py ├── changing-colorspaces ├── README.md ├── big_blue_ball_machine_8HZPb7ulu08.mp4 ├── demo_gbr_to_hsv.py ├── images │ └── blue_ball_1.PNG ├── screenshots │ ├── Thumbs.db │ ├── shoot_1_frame.png │ ├── shoot_1_mask.png │ └── shoot_1_res.png ├── show_color_conversion_methods.py └── track_blue_ball.py ├── contours_in_opencv ├── README.md ├── contour_features │ ├── README.md │ ├── blue0.png │ ├── blue1.png │ ├── blue2.png │ ├── blue3.png │ ├── blue4.png │ ├── blue5.png │ ├── blue6.png │ ├── blue7.png │ ├── blue_thunder.png │ ├── demo_area.py │ ├── demo_bounding_rectangle.py │ ├── demo_contour_approx.py │ ├── demo_contour_convexity.py │ ├── demo_fit_eclipse.py │ ├── demo_fit_line.py │ ├── demo_min_enclosing_circle.py │ ├── demo_moments.py │ ├── demo_perimeter.py │ ├── screenshots │ │ ├── approx_plate_contour_epsi_0p001.png │ │ ├── approx_plate_contour_epsi_0p01.png │ │ ├── approx_plate_contour_epsi_0p05.png │ │ ├── approx_plate_contour_epsi_0p1.png │ │ ├── approx_plate_contour_epsi_0p5.png │ │ ├── blue0.png │ │ ├── blue1.png │ │ ├── bounding_rectangle.png │ │ ├── fit_eclipse.png │ │ ├── fit_line.png │ │ ├── hull1.png │ │ ├── min_circle.png │ │ ├── tb_approx_1.png │ │ ├── tb_approx_2.png │ │ ├── tb_approx_3.png │ │ ├── tb_approx_4.png │ │ ├── tb_approx_5.png │ │ └── tb_approx_6.png │ └── trackbar_contour_approx.py ├── contour_properties │ ├── Contour.py │ ├── Contour.pyc │ ├── README.md │ ├── blue0.png │ ├── blue1.png │ ├── blue2.png │ ├── blue3.png │ ├── blue4.png │ ├── blue5.png │ ├── blue6.png │ ├── blue7.png │ ├── blue_thunder.png │ ├── demo_contour_properties.py │ ├── plot_extreme_points.py │ └── screenshots │ │ ├── extreme_blue0.png │ │ ├── extreme_blue1.png │ │ ├── extreme_blue2.png │ │ ├── extreme_blue3.png │ │ ├── extreme_blue4.png │ │ ├── extreme_blue5.png │ │ ├── extreme_blue6.png │ │ └── extreme_blue7.png ├── contours_getting_started │ ├── README.md │ ├── box.png │ ├── box_2.png │ ├── box_3.png │ ├── box_4.png │ ├── demo_find_countours.py │ ├── screenshots │ │ ├── demo_output.png │ │ ├── track_1.png │ │ ├── track_10.png │ │ ├── track_11.png │ │ ├── track_2.png │ │ ├── track_3.png │ │ ├── track_4.png │ │ ├── track_5.png │ │ ├── track_6.png │ │ ├── track_7.png │ │ ├── track_8.png │ │ ├── track_9.png │ │ └── youtube_thumb.png │ ├── tom_cruise.jpg │ └── trackbar_countours.py └── contours_more_functions │ ├── README.md │ ├── blue0.png │ ├── blue1.png │ ├── blue2.png │ ├── blue3.png │ ├── blue4.png │ ├── blue5.png │ ├── blue6.png │ ├── blue6_rotated.png │ ├── blue7.png │ ├── demo_convexity_defect.py │ ├── demo_match_shapes.py │ ├── screenshots │ └── blue3_defects.png │ └── visualize_convexity_defect.py ├── geometric_transformations_of_images ├── README.md ├── affine_transform_image.py ├── messi.jpg ├── perspective_transform_image.py ├── resize_image.py ├── rotate_image.py ├── screenshots │ ├── affine_transform.png │ ├── perspective_transform.png │ ├── resize_after.png │ ├── resize_before.png │ ├── rotate_after.png │ ├── rotate_before.png │ ├── translate_after.png │ └── translate_before.png └── translate_image.py ├── image_gradients ├── README.md ├── box.png ├── box_2.png ├── box_3.png ├── box_4.png ├── compare_depths_8u_vs_64f_laplacian.py ├── compare_depths_8u_vs_64f_sobel_x.py ├── compare_methods_at_depth_64f.py ├── compare_methods_at_depth_8u.py ├── davemark_sudoku.jpg └── screenshots │ ├── compare_depths_8u_vs_64f_laplacian_box.png │ ├── compare_depths_8u_vs_64f_sobel_x_box.png │ ├── compare_methods_at_depth_64f_sudoku.png │ └── compare_methods_at_depth_8u_sudoku.png ├── image_pyramids ├── README.md ├── apple.jpg ├── messi.jpg ├── orange.jpg ├── pyramid.py ├── pyramid_edged_image.py ├── pyramid_image_blending.py └── screenshots │ ├── image_pyramid.png │ ├── image_pyramid_down3_up3.png │ ├── image_pyramid_down3_up3_edged_image.png │ ├── pyramid_blending.png │ ├── pyramid_steps_1.jpg │ ├── pyramid_steps_2.jpg │ └── pyramid_steps_3.jpg ├── image_thresholding ├── README.md ├── create_gradient_png.py ├── davemark_sudoku.jpg ├── demo_find_otsu_threshold_value.py ├── demo_image_adaptive_thresholding.py ├── demo_image_thresholding.py ├── demo_otsu_binarization.py ├── gradient.png ├── noisy_twitter_colored.jpg └── screenshots │ ├── gradient.png │ ├── gradient_image_thresholding.png │ ├── sudoku_image_adaptive_thresholding.png │ └── twitter_image_otsu_binarization.png ├── morphological_transformations ├── README.md ├── compare_morph.py ├── screenshots │ ├── compare_morphology_options.png │ └── smily_original_noisy.png ├── smily_in_snow.png ├── smily_in_snow_2.png ├── smily_in_snow_3.png ├── smily_original.png └── smily_original_noisy.png └── smoothing_images ├── README.md ├── carpet.png ├── opencv_logo_black_background.png ├── opencv_logo_black_background_noisy.png ├── screenshots ├── bilateral_filter.png ├── blur.png ├── filter2d.png ├── gaussian_blur.png └── median_blur.png ├── smooth_image_with_bilateral_filter.py ├── smooth_image_with_blur.py ├── smooth_image_with_filter2d.py ├── smooth_image_with_gaussian_blur.py └── smooth_image_with_median_blur.py /.gitignore: -------------------------------------------------------------------------------- 1 | ############ 2 | ## Windows 3 | ############ 4 | 5 | # Windows image file caches 6 | Thumbs.db 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # opencv-python-tutorials 2 | 3 | A place to play around with the [OpenCV-Python Tutorials](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_tutorials.html). 4 | 5 | # Python 2.x or 3.x? 6 | 7 | I use Python 2.x - seems to work fine so far. (As well as Anaconda IDE for Python 2.x). 8 | 9 | # OpenCV 2.x or 3.x? 10 | 11 | Even though the OpenCV 2.x version is very mature and well documented, the [OpenCV-Python Tutorials](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_tutorials.html) are written base on OpenCV 3.x version. 12 | 13 | When I first started the tutorial I used OpenCV 2.x - but when I progressed I realized the need to try out OpenCV 3.x (So what the tutorial produces mataches to what I produce locally on my machine). 14 | 15 | To prevent having a mix of OpenCV 2.x and 3.x codes, I shall stick to OpenCV 3.x for the duration of the [OpenCV-Python Tutorials](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_tutorials.html) as suggested by the Authors. 16 | 17 | # Get OpenCV working in Anaconda 18 | 19 | This [Stackoverflow Forum](http://stackoverflow.com/questions/23119413/how-to-install-python-opencv-through-conda/30281466#30281466) will provide some top tips and hints on getting OpenCV (2.x and/or 3/x) working with Python 2.x Anaconda. 20 | -------------------------------------------------------------------------------- /core_operations/README.md: -------------------------------------------------------------------------------- 1 | # Core Operations 2 | 3 | See [OpenCV-Python Tutorials - Core Operations](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_table_of_contents_core/py_table_of_contents_core.html) for the original tutorials. 4 | -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/README.md: -------------------------------------------------------------------------------- 1 | # Artithemetics Operations on Images 2 | 3 | See [OpenCV-Python Tutorials - Artithemetics Operations on Images](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_image_arithmetics/py_image_arithmetics.html#image-arithmetics) for the original Tutorials. 4 | 5 | ## Image Addition 6 | 7 | The code `demo_image_arithmetics.py` illustrates `numpy` vs `cv2` additions. 8 | 9 | There is a difference between OpenCV addition and Numpy addition. OpenCV addition is a [saturated operation](http://en.wikipedia.org/wiki/Saturation_arithmetic) while Numpy addition is a [modulo operation](http://en.wikipedia.org/wiki/Modulo_operation). 10 | 11 | Here is [a great post by Abid Rahman K](http://opencvpython.blogspot.co.uk/2012/06/difference-between-matrix-arithmetic-in.html) explaining the difference between these two additions. 12 | 13 | For image processing problems, always stick to using the cv2 addition! 14 | 15 | For example, the code `add_images.py` uses the `cv2.add()` method to add two images together (saturated operation). 16 | 17 | Image 1 - Iron Man: 18 | 19 | ![ironman.png](./screenshots/ironman.png) 20 | 21 | Image 2 - Tony Stark: 22 | 23 | ![tony_stark.png](./screenshots/tony_stark.png) 24 | 25 | Add image 1 and image 2 (using `cv2.add(), a saturated operation): 26 | 27 | ![add_images.png](./screenshots/add_images.png) 28 | 29 | Notice that adding images essentially increase the color scale GBR value towards `(255, 255, 255)`. i.e. white. The more we add, the more likely we will get a "brighter / whiter" image. 30 | 31 | ## Image Blending 32 | 33 | The code `blend_images.py` illustrates blending image 1 and image 2 together (overlaying) incorporating assigning weights. 34 | 35 | Here I will be using two images of the same size (400 width by 500 height pixels). I essentially downloaded the two images from a Google search, and resized them with the Windows Paint application. 36 | 37 | Image 1 - Iron Man: 38 | 39 | ![ironman.png](./screenshots/ironman.png) 40 | 41 | Image 2 - Tony Stark: 42 | 43 | ![tony_stark.png](./screenshots/tony_stark.png) 44 | 45 | Blend image 1 (`.7` weight) and image 2 (`.3` weight): 46 | 47 | ![blend_images.png](./screenshots/blend_images.png) 48 | 49 | # Image Thresholding 50 | 51 | Objective of this section is to learn more about thresholding - in particular the 5 thresholding options in OpenCV. 52 | 53 | The code `image_thresholding.py` code illustrates this. 54 | 55 | See these articles for more info: 56 | 57 | - [OpenCV-Python - Image Thresholding Blog by Abid Rahman K](http://opencvpython.blogspot.co.uk/2013/05/thresholding.html) 58 | - [The 5 Image Thresholding Options](http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html) 59 | 60 | Some screenshots: 61 | 62 | Original Grayscale image: 63 | 64 | ![img_thresholding_grayscale.png](./screenshots/img_thresholding_grayscale.png) 65 | 66 | THRESH_BINARY: 67 | 68 | ![img_thresholding_THRESH_BINARY.png](./screenshots/img_thresholding_THRESH_BINARY.png) 69 | 70 | THRESH_BINARY_INV: 71 | 72 | ![img_thresholding_THRESH_BINARY_INV.png](./screenshots/img_thresholding_THRESH_BINARY_INV.png) 73 | 74 | THRESH_TRUNC: 75 | 76 | ![img_thresholding_THRESH_TRUNC.png](./screenshots/img_thresholding_THRESH_TRUNC.png) 77 | 78 | THRESH_TO_ZERO: 79 | 80 | ![img_thresholding_THRESH_TO_ZERO.png](./screenshots/img_thresholding_THRESH_TO_ZERO.png) 81 | 82 | THRESH_TO_ZERO_INV: 83 | 84 | ![img_thresholding_THRESH_TO_ZERO_INV.png](./screenshots/img_thresholding_THRESH_TO_ZERO_INV.png) 85 | 86 | # Bitwise Operation 87 | 88 | The code `bitwise_operate_images.py` illustrates Bitwise Operations on images - a powerful technique to enable us to achieve things like... 89 | 90 | We have two images. 91 | 92 | Image 1 is photo of Messi. 93 | 94 | ![messi.png](./screenshots/messi.png) 95 | 96 | Image 2 is the OpenCV logo (black background). 97 | 98 | ![img2_opencv_logo_black_background.png](./screenshots/img2_opencv_logo_black_background.png) 99 | 100 | We wish to overlay the OpenCV logo (Opague) on top of the phot of Messi like this: 101 | 102 | ![res.png](./screenshots/res.png) 103 | 104 | Some key facts to know: 105 | 106 | - In a 256 (8 bits) true color world, intensity ranges from 0 (000000) to 255 (11111111). 107 | - So, see the decimal intensity 255 (white) as binary 1 (True), and decimal intensity 0 as binary 0 (False). 108 | - i.e. if we manage to make an image black and white only (i.e. contains only intensity of 0 and 1), we can use that as a mask for bitwise and/or/not operations. 109 | 110 | Explain the process: 111 | 112 | ```python 113 | img1 = cv2.imread('messi_717px_by_483px.png') 114 | ``` 115 | 116 | ![messi.png](./screenshots/messi.png) 117 | 118 | ```python 119 | img2 = cv2.imread('opencv_logo_black_background.png') 120 | ``` 121 | 122 | ![img2_opencv_logo_black_background.png](./screenshots/img2_opencv_logo_black_background.png) 123 | 124 | ```python 125 | rows,cols,channels = img2.shape 126 | roi = img1[0:rows, 0:cols ] 127 | ``` 128 | 129 | ![roi.png](./screenshots/roi.png) 130 | 131 | ```python 132 | img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) 133 | ``` 134 | 135 | ![img2gray.png](./screenshots/img2gray.png) 136 | 137 | ```python 138 | ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY) 139 | ``` 140 | 141 | ![mask.png](./screenshots/mask.png) 142 | 143 | ```python 144 | mask_inv = cv2.bitwise_not(mask) 145 | ``` 146 | 147 | ![mask_inv.png](./screenshots/mask_inv.png) 148 | 149 | ```python 150 | img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv) 151 | ``` 152 | 153 | ![img1_bg.png](./screenshots/img1_bg.png) 154 | 155 | ```python 156 | img2_fg = cv2.bitwise_and(img2,img2,mask = mask) 157 | ``` 158 | 159 | ![img2_fg.png](./screenshots/img2_fg.png) 160 | 161 | ```python 162 | dst = cv2.add(img1_bg,img2_fg) 163 | ``` 164 | 165 | ![dst.png](./screenshots/dst.png) 166 | 167 | ```python 168 | img1[0:rows, 0:cols ] = dst 169 | ``` 170 | 171 | ![res.png](./screenshots/res.png) 172 | 173 | # Conclusion 174 | 175 | Here we have run through some exercises on image addition and blending. We also performed Bitwise operation to essentially enable opague overlaying of an image over another. -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/Thumbs.db -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/add_images.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 17:03:32 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | 10 | 11 | # Image Blending (with weights in image 1 and image 2) 12 | img1 = cv2.imread("iron_man_400px_by_500px.png") 13 | print img1 is not None 14 | 15 | img2 = cv2.imread("tony_stark_400px_by_500px.png") 16 | print img2 is not None 17 | 18 | dst = cv2.add(img1, img2) 19 | 20 | cv2.imshow("img1", img1) 21 | cv2.imshow("img2", img2) 22 | cv2.imshow("cv2.add img1 and img2", dst) 23 | cv2.waitKey(0) 24 | cv2.destroyAllWindows() 25 | -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/bitwise_operate_images.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 23:10:26 2015 4 | 5 | @author: Johnny 6 | Inspired by: 7 | https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_image_arithmetics/py_image_arithmetics.html#image-arithmetics 8 | """ 9 | 10 | #%% 11 | import numpy as np 12 | import cv2 13 | #%% 14 | # Load image - messi 15 | img1 = cv2.imread('messi_717px_by_483px.png') 16 | print img1 is not None 17 | cv2.imshow("img1", img1) 18 | cv2.waitKey(0) 19 | cv2.destroyAllWindows() 20 | #%% 21 | # load image - opencv logo 22 | #img2 = cv2.imread('opencv_logo_white_background.png') 23 | img2 = cv2.imread('opencv_logo_black_background.png') 24 | print img2 is not None 25 | cv2.imshow("img2", img2) 26 | cv2.waitKey(0) 27 | cv2.destroyAllWindows() 28 | #%% 29 | # I want to put logo on top-left corner, So I create a ROI 30 | rows,cols,channels = img2.shape 31 | print (rows,cols,channels) 32 | #%% 33 | roi = img1[0:rows, 0:cols ] 34 | cv2.imshow("roi", roi) 35 | cv2.waitKey(0) 36 | cv2.destroyAllWindows() 37 | #%% 38 | # Now create a mask of logo and create its inverse mask also 39 | img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) 40 | cv2.imshow("img2gray", img2gray) 41 | cv2.waitKey(0) 42 | cv2.destroyAllWindows() 43 | #%% 44 | # If white (255), leave it as it is. Else, make it black (0). 45 | ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY) 46 | cv2.imshow("mask", mask) 47 | cv2.waitKey(0) 48 | cv2.destroyAllWindows() 49 | #%% 50 | # Invert: white become black, and black become white 51 | mask_inv = cv2.bitwise_not(mask) 52 | cv2.imshow("mask_inv", mask_inv) 53 | cv2.waitKey(0) 54 | cv2.destroyAllWindows() 55 | #%% 56 | # Now black-out the area of logo in ROI 57 | img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv) 58 | cv2.imshow("img1_bg", img1_bg) 59 | cv2.waitKey(0) 60 | cv2.destroyAllWindows() 61 | #%% 62 | # Take only region of logo from logo image. 63 | img2_fg = cv2.bitwise_and(img2,img2,mask = mask) 64 | cv2.imshow("img2_fg", img2_fg) 65 | cv2.waitKey(0) 66 | cv2.destroyAllWindows() 67 | #%% 68 | # Put logo in ROI and modify the main image 69 | dst = cv2.add(img1_bg,img2_fg) 70 | cv2.imshow("dst", dst) 71 | cv2.waitKey(0) 72 | cv2.destroyAllWindows() 73 | #%% 74 | img1[0:rows, 0:cols] = dst 75 | cv2.imshow('res',img1) 76 | cv2.waitKey(0) 77 | cv2.destroyAllWindows() 78 | -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/blend_images.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 17:03:32 2015 4 | 5 | @author: Johnny 6 | """ 7 | #%% 8 | import numpy as np 9 | import cv2 10 | 11 | #%% 12 | # Image Blending (with weights in image 1 and image 2) 13 | img1 = cv2.imread("iron_man_400px_by_500px.png") 14 | print img1 is not None 15 | cv2.imshow("img1", img1) 16 | cv2.waitKey(0) 17 | cv2.destroyAllWindows() 18 | #%% 19 | img2 = cv2.imread("tony_stark_400px_by_500px.png") 20 | print img2 is not None 21 | cv2.imshow("img2", img2) 22 | cv2.waitKey(0) 23 | cv2.destroyAllWindows() 24 | #%% 25 | dst = cv2.addWeighted(img1,0.7,img2,0.3,0) 26 | 27 | cv2.imshow("Blend img1 and img2", dst) 28 | cv2.waitKey(0) 29 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/demo_image_arithmetics.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 15:57:02 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | #%% 9 | import cv2 10 | import numpy as np 11 | 12 | #%% 13 | # mage Addition 14 | # There is a difference between OpenCV addition and Numpy addition. 15 | # - OpenCV addition is a saturated operation (clamped between min and max) 16 | # - Numpy addition is a modulo operation. (number gets recycle after hitting min / max) 17 | 18 | # Note: uint8 type contains 2**8 = 256 integers. Ranging between 0 and 255. 19 | #%% 20 | x = np.uint8([250]) 21 | x 22 | #%% 23 | y = np.uint8([10]) 24 | y 25 | #%% 26 | #%% 27 | # cv2 addition is clamped between min and max (think color scale) 28 | print cv2.add(x,y) # 250+10 = 260 => 255 (max) 29 | #%% 30 | # NumPy addition is modulo - like a clock. 31 | print x+y # 250+10 = 260 % 256 = 4 (255 + 4 = 260) -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/image_thresholding.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat May 23 12:28:29 2015 4 | 5 | @author: Johnny 6 | 7 | Illustrate image thresholding. 8 | 9 | Inspired by: 10 | http://opencvpython.blogspot.co.uk/2013/05/thresholding.html 11 | """ 12 | #%% 13 | import cv2 14 | import numpy as np 15 | from matplotlib import pyplot as plt 16 | #%% 17 | # Read grayscale image. OK if not return None. 18 | img = cv2.imread('messi_grayscale.jpg',0) 19 | print img is not None 20 | #%% 21 | # refer to http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html 22 | # ret,threshold_image = cv2.threshold(gray_scale_image,threshold,resolved_value,option) 23 | ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) # if greater than threshold, make it 255 (white). Otherwise, 0 (black) 24 | ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) # inverse above. 25 | ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) # If greater than threshold, make it threshold. Otherwise, leave as it is. 26 | ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) # if greater than threshold, leave as it is. Otherwise, 0 (black) 27 | ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) # # if greater than threshold, 0 (black). Otherwise, lave as it is. 28 | #%% 29 | thresh = ['img','thresh1','thresh2','thresh3','thresh4','thresh5'] 30 | thresh_dict = { 31 | 'img':'grayscale image', 32 | 'thresh1': 'THRESH_BINARY', 33 | 'thresh2': 'THRESH_BINARY_INV', 34 | 'thresh3': 'THRESH_TRUNC', 35 | 'thresh4': 'THRESH_TOZERO', 36 | 'thresh5': 'THRESH_TOZERO_INV' 37 | } 38 | #%% 39 | for i in thresh: 40 | plt.imshow(eval(i),'gray') 41 | #plt.subplot(2,3,i+1),plt.imshow(eval(thresh[i]),'gray') 42 | plt.title(i + ": " + thresh_dict[i]) 43 | plt.tight_layout() 44 | plt.show() 45 | 46 | 47 | -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/iron_man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/iron_man.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/iron_man_400px_by_500px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/iron_man_400px_by_500px.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/messi_717px_by_483px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/messi_717px_by_483px.jpg -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/opencv_logo_200px_by_246px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/opencv_logo_200px_by_246px.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/tony_stark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/tony_stark.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/images/tony_stark_400px_by_500px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/images/tony_stark_400px_by_500px.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/iron_man_400px_by_500px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/iron_man_400px_by_500px.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/messi_717px_by_483px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/messi_717px_by_483px.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/messi_grayscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/messi_grayscale.jpg -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/opencv_logo_black_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/opencv_logo_black_background.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/opencv_logo_white_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/opencv_logo_white_background.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/add_images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/add_images.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/blend_images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/blend_images.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/dst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/dst.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img1_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img1_bg.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img2_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img2_fg.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img2_opencv_logo_black_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img2_opencv_logo_black_background.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img2gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img2gray.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_BINARY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_BINARY.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_BINARY_INV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_BINARY_INV.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TO_ZERO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TO_ZERO.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TO_ZERO_INV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TO_ZERO_INV.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TRUNC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_THRESH_TRUNC.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_grayscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/img_thresholding_grayscale.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/ironman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/ironman.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/mask.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/mask_inv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/mask_inv.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/messi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/messi.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/res.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/roi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/roi.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/screenshots/tony_stark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/screenshots/tony_stark.png -------------------------------------------------------------------------------- /core_operations/arithmetics_operations_on_images/tony_stark_400px_by_500px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/arithmetics_operations_on_images/tony_stark_400px_by_500px.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/README.md: -------------------------------------------------------------------------------- 1 | # Basic Operations on Images 2 | 3 | See [OpenCV-Python Tutorials - Basic Operations on Images](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#basic-ops) for the original tutorial. 4 | 5 | # Demo Modify Image 6 | 7 | Run the demo code `demo_modify_image.py`. 8 | 9 | This covers: 10 | 11 | - Accessing and Modifying pixel values 12 | - Accessing Image Properties 13 | - Image ROI (Region of Interest) 14 | - Splitting and Merging Image Channels 15 | 16 | Some screenshots: 17 | 18 | Origina image: 19 | 20 | ![img_1.png](./screenshots/img_1.png) 21 | 22 | Add a white pixel at row 100, column 150: 23 | 24 | ![img_2.png](./screenshots/img_2.png) 25 | 26 | Add a red pixel at row 100, column 150: 27 | 28 | ![img_3.png](./screenshots/img_3.png) 29 | 30 | Show the ball only: 31 | 32 | ![img_4.png](./screenshots/img_4.png) 33 | 34 | Copy and paste the ball to somewhere else: 35 | 36 | ![img_5.png](./screenshots/img_5.png) 37 | 38 | Image after split and merge: 39 | 40 | ![img_6.png](./screenshots/img_6.png) 41 | 42 | Reduce the BGR red scale to 0: 43 | 44 | ![img_7.png](./screenshots/img_7.png) 45 | 46 | # Demo Making Borders for Images (Padding) 47 | 48 | Run the demo code `demo_add_border_to_image.py`. 49 | 50 | Some snapshots: 51 | 52 | Original image - no border: 53 | 54 | ![border_original.png](./screenshots/border_original.png) 55 | 56 | Border Option - `cv2.BORDER_REPLICATE`: 57 | 58 | ![border_replicate.png](./screenshots/border_replicate.png) 59 | 60 | Border Option - `cv2.BORDER_REFLECT`: 61 | 62 | ![border_reflect.png](./screenshots/border_reflect.png) 63 | 64 | Border Option - `cv2.BORDER_REFLECT_101`: 65 | 66 | ![border_reflect_101.png](./screenshots/border_reflect_101.png) 67 | 68 | Border Option - `cv2.BORDER_WRAP`: 69 | 70 | ![border_wrap.png](./screenshots/border_wrap.png) 71 | 72 | Border Option - `cv2.BORDER_CONSTANT` (Blue): 73 | 74 | ![border_constant_blue.png](./screenshots/border_constant_blue.png) 75 | 76 | # Conclusion 77 | 78 | Some cool examples demonstrating basic operations around accessing and manipulating an image (matrix). 79 | -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/demo_add_border_to_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 14:27:39 2015 4 | 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | BLUE = [255,0,0] 13 | 14 | img1 = cv2.imread('messi.jpg') 15 | if img is None: 16 | print "imread Failure" 17 | else: 18 | print "imread OK" 19 | 20 | #%% 21 | # cv2.copyMakeBorder(image,top,bottom,left,right,border_type) 22 | replicate = cv2.copyMakeBorder(img1,50,50,50,50,cv2.BORDER_REPLICATE) 23 | reflect = cv2.copyMakeBorder(img1,50,50,50,50,cv2.BORDER_REFLECT) 24 | reflect101 = cv2.copyMakeBorder(img1,50,50,50,50,cv2.BORDER_REFLECT_101) 25 | wrap = cv2.copyMakeBorder(img1,50,50,50,50,cv2.BORDER_WRAP) 26 | constant= cv2.copyMakeBorder(img1,50,50,50,50,cv2.BORDER_CONSTANT,value=BLUE) 27 | 28 | #%% 29 | # show modified image 30 | cv2.imshow('ORIGINAL',img1) 31 | k = cv2.waitKey(0) & 0xFF 32 | cv2.destroyAllWindows() 33 | 34 | #%% 35 | cv2.imshow('cv2.BORDER_REPLICATE',replicate) 36 | k = cv2.waitKey(0) & 0xFF 37 | cv2.destroyAllWindows() 38 | 39 | #%% 40 | cv2.imshow('cv2.BORDER_REFLECT',reflect) 41 | k = cv2.waitKey(0) & 0xFF 42 | cv2.destroyAllWindows() 43 | 44 | #%% 45 | cv2.imshow('BORDER_REFLECT_101',reflect101) 46 | k = cv2.waitKey(0) & 0xFF 47 | cv2.destroyAllWindows() 48 | 49 | #%% 50 | cv2.imshow('cv2.BORDER_WRAP',wrap) 51 | k = cv2.waitKey(0) & 0xFF 52 | cv2.destroyAllWindows() 53 | 54 | #%% 55 | cv2.imshow('cv2.BORDER_CONSTANT (Blue)',constant) 56 | k = cv2.waitKey(0) & 0xFF 57 | cv2.destroyAllWindows() 58 | 59 | #%% 60 | #plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL') 61 | #plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE') 62 | #plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT') 63 | #plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101') 64 | #plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP') 65 | #plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT') 66 | 67 | #plt.show() -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/demo_modify_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 12:08:40 2015 4 | 5 | @author: Johnny 6 | """ 7 | #%% 8 | #Accessing and Modifying pixel values 9 | #%% 10 | import cv2 11 | import numpy as np 12 | 13 | #%% 14 | img = cv2.imread('messi.jpg') 15 | 16 | #%% 17 | print img 18 | #%% 19 | cv2.imshow('original image',img) 20 | k = cv2.waitKey(0) & 0xFF 21 | cv2.destroyAllWindows() 22 | #%% 23 | # Access pixe lBGR values at row 100 (y), column 150 (x) 24 | px = img[100,150] 25 | print px 26 | #%% 27 | # accessing only blue pixel at row 100 (y), column 150 (x) 28 | blue = img[100,150,0] 29 | print blue 30 | #%% 31 | # Modify pixel BGR value at row 100 (y), column 150 (x) - to white. 32 | img[100,150] = [255,255,255] 33 | print img[100,150] 34 | # show modified image 35 | cv2.imshow('add a white pixel at row 100, column 150',img) 36 | k = cv2.waitKey(0) & 0xFF 37 | cv2.destroyAllWindows() 38 | #%% 39 | #Better pixel accessing and editing method 40 | print img.item(10,20,2) 41 | # modifying BGR red value using the better accessin method 42 | img.itemset((10,20,2),255) 43 | print img.item(10,10,2) 44 | #%% 45 | # show modified image 46 | cv2.imshow('add a red pixel at row 100, column 150',img) 47 | k = cv2.waitKey(0) & 0xFF 48 | cv2.destroyAllWindows() 49 | #%% 50 | #Accessing Image Properties 51 | #%% 52 | # Access image property - shape 53 | print img.shape 54 | #%% 55 | # Total number of pixels 56 | print img.size 57 | #%% 58 | # Image datatype 59 | print img.dtype 60 | #%% 61 | # Image ROI (region of interest) 62 | #%% 63 | # Select the ball from the image (use the Windows Paint App to find ball location) 64 | ball = img[398:468,438:521] 65 | # Show the ball 66 | cv2.imshow('show the ball only',ball) 67 | k = cv2.waitKey(0) & 0xFF 68 | cv2.destroyAllWindows() 69 | #%% 70 | #Copy the ball to a different region of the picture 71 | img[198:268,238:321] = ball 72 | cv2.imshow('copy and paste the ball to somewhere else',img) 73 | k = cv2.waitKey(0) & 0xFF 74 | cv2.destroyAllWindows() 75 | #%% 76 | # Splitting and Merging Image Channels 77 | b,g,r = cv2.split(img) 78 | img_split_merge = cv2.merge((b,g,r)) 79 | print img_split_merge 80 | cv2.imshow('image after split and merge',img) 81 | k = cv2.waitKey(0) & 0xFF 82 | cv2.destroyAllWindows() 83 | #%% 84 | # Access all the blue pixels 85 | b = img[:,:,0] 86 | print b 87 | #%% 88 | # Change all the red pixel to white 89 | img[:,:,2] = 0 90 | cv2.imshow('reduce the BGR red scale to 0',img) 91 | k = cv2.waitKey(0) & 0xFF 92 | cv2.destroyAllWindows() 93 | #%% -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/messi.jpg -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_constant_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_constant_blue.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_original.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_reflect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_reflect.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_reflect_101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_reflect_101.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_replicate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_replicate.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/border_wrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/border_wrap.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_1.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_2.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_3.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_4.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_5.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_6.png -------------------------------------------------------------------------------- /core_operations/basic_operations_on_images/screenshots/img_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/basic_operations_on_images/screenshots/img_7.png -------------------------------------------------------------------------------- /core_operations/performance_measurement_and_improvement_techniques/README.md: -------------------------------------------------------------------------------- 1 | # Performance Measurement and Improvement Techniques 2 | 3 | Use this space to play around with [OpenCV-Python Tutorials - Performance Measurement and Improvement Techniques](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_optimization/py_optimization.html) 4 | -------------------------------------------------------------------------------- /core_operations/performance_measurement_and_improvement_techniques/demo_time_code.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat May 23 15:18:17 2015 4 | 5 | @author: Johnny 6 | """ 7 | import cv2 8 | 9 | img1 = cv2.imread('messi.jpg') 10 | 11 | e1 = cv2.getTickCount() 12 | for i in xrange(5,49,2): 13 | img1 = cv2.medianBlur(img1,i) 14 | e2 = cv2.getTickCount() 15 | t = (e2 - e1)/cv2.getTickFrequency() 16 | print t -------------------------------------------------------------------------------- /core_operations/performance_measurement_and_improvement_techniques/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/performance_measurement_and_improvement_techniques/messi.jpg -------------------------------------------------------------------------------- /core_operations/performance_measurement_and_improvement_techniques/messi_grayscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/core_operations/performance_measurement_and_improvement_techniques/messi_grayscale.jpg -------------------------------------------------------------------------------- /gui_features_in_opencv/README.md: -------------------------------------------------------------------------------- 1 | # GUI Features in OpenCV 2 | 3 | See [this OpenCV-Python Tutorial Page](http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_table_of_contents_gui/py_table_of_contents_gui.html#py-table-of-content-gui) for instructions. -------------------------------------------------------------------------------- /gui_features_in_opencv/drawing_functions_in_opencv/README.md: -------------------------------------------------------------------------------- 1 | # Drawing Functions in OpenCV 2 | 3 | Use this space top play around with drawing functions in OpenCV. 4 | 5 | Resources: 6 | 7 | - [Main Tutorial Page - Drawing Functions in OpenCV](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_drawing_functions/py_drawing_functions.html#drawing-functions) 8 | - [OpenCV Doc - Drawing Functions](http://docs.opencv.org/modules/core/doc/drawing_functions.html) 9 | 10 | # Test Instructions 11 | 12 | The main code is `run_tutorial.py`. You can run in a number of ways: 13 | 14 | ## Batch mode 15 | 16 | Just do this in a command window: 17 | 18 | ``` 19 | ipython run_tutorial.py 20 | ``` 21 | 22 | ## Anaconda Spyder IDE 23 | 24 | Make sure to set the current working directory to where the code is stored. 25 | 26 | Either run in in chunks or as a whole program: 27 | 28 | ![screenshot_run_in_spyder_1.png](./screenshots/screenshot_run_in_spyder_1.png) 29 | 30 | A new window with the drawing is now displayed: 31 | 32 | ![screenshot_run_in_spyder_2.png](./screenshots/screenshot_run_in_spyder_2.png) 33 | 34 | Use the keyboad key `s` if you want to save the picture (it will save it as `output.jpg`). 35 | 36 | Or hit any key to close the window. 37 | 38 | # Cautious Notes: 39 | 40 | In OpenCV 3.x Version, draw functions mutate `img` and also returns `img`. 41 | 42 | ``` 43 | img = cv2.line(img,...) 44 | img = cv2.rectangle(img,...) 45 | img = cv2.circle(img,...) 46 | img = cv2.ellipse(img,...) 47 | img = cv2.polylines(img,...) 48 | ``` 49 | 50 | In OpenCV 2.x version, draw functions mutate `img` and also `none`. 51 | 52 | ``` 53 | cv2.line(img,...) 54 | cv2.rectangle(img,...) 55 | cv2.circle(img,...) 56 | cv2.ellipse(img,...) 57 | cv2.polylines(img,...) 58 | ``` 59 | 60 | # Conclusion 61 | 62 | A nice simple tutorial to illustrate how to use draw functions (to draw things) and reuse of the `cv2.imshow()` to display image. 63 | 64 | A drawing essentially is made of a matrix of `height, width, BGR_tuple`. -------------------------------------------------------------------------------- /gui_features_in_opencv/drawing_functions_in_opencv/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/drawing_functions_in_opencv/output.jpg -------------------------------------------------------------------------------- /gui_features_in_opencv/drawing_functions_in_opencv/run_tutorial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 17 14:06:43 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | #%% 9 | import numpy as np 10 | import cv2 11 | #%% 12 | # Create a black image 13 | # initialize the image as a box of 512 units (height) by 512 units (width) by 3 units (BGR tuple). 14 | # Each value is of type numpy.unit8 (unsigned integer ranging between 0 to 255) 15 | img = np.zeros((512,512,3), np.uint8) 16 | #%% 17 | print img.shape 18 | #>>> (512L, 512L, 3L) 19 | #%% 20 | # Draw shapes. 21 | # Notes: a 2-D coordinate tuple is in (x, y) 22 | #%% 23 | # Draw a diagonal blue line with thickness of 5 px 24 | # Essentially update img like this: 25 | # img = cv2.line(image_to_draw_on, start_coordinate, end_coordinate, BGR_tuple, thickness_in_pixels) 26 | img = cv2.line(img,(0,0),(511,511),(255,0,0),5) 27 | #%% 28 | # Draw a rectangle with thickness of 3 px 29 | # Essentially update img like this: 30 | # img = cv2.rectangle(image_to_draw_on, top_left_coordinate, bottom_right_coordinate, BGR_tuple, thickness_in_pixels) 31 | img = cv2.rectangle(img,(384,0),(510,128),(0,255,0),3) 32 | #%% 33 | # Draw a circle with thickness of 1 px (inwards - indicated by the negative sign thickness) 34 | # Essentially update img like this: 35 | # img = cv2.circle(image_to_draw_on, center_coordinate, radius, BGR_tuple, thickness_in_pixels) 36 | img = cv2.circle(img,(447,63), 63, (0,0,255), -1) 37 | #%% 38 | # Draw an ellipse with thickness of 1 px (inwards - indicated by the negative sign thickness) 39 | # Essentially update img like this: 40 | # cv2.ellipse(image_to_draw_on, center_coordinate, (axis_a_length, axis_b_length), angle, startAngle, endAngle, color, thickness) 41 | img = cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1) 42 | #%% 43 | # Draw a polyline 44 | pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32) 45 | print pts 46 | pts = pts.reshape((-1,1,2)) 47 | print "---" 48 | print pts 49 | cv2.polylines(img,[pts],True,(0,255,255)) 50 | #%% 51 | # Draw text 52 | font = cv2.FONT_HERSHEY_SIMPLEX 53 | # Python 3.x version uses cv2.LINE_AA 54 | cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA) 55 | # Python 2.x version uses cv2.CV_AA 56 | #cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.CV_AA) 57 | #%% 58 | # Display image in a window. 59 | 60 | # Optional: 61 | #cv2.startWindowThread() 62 | # Optional: enable resizing. Handy for very large image. 63 | #cv2.namedWindow('img', cv2.WINDOW_NORMAL) 64 | # Display an image 65 | cv2.imshow('img',img) 66 | 67 | # 's' to save. 68 | k = cv2.waitKey(0) & 0xFF 69 | if k == ord('s'): 70 | cv2.imwrite("output.jpg",img) 71 | 72 | cv2.destroyAllWindows() 73 | 74 | -------------------------------------------------------------------------------- /gui_features_in_opencv/drawing_functions_in_opencv/screenshots/screenshot_run_in_spyder_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/drawing_functions_in_opencv/screenshots/screenshot_run_in_spyder_1.png -------------------------------------------------------------------------------- /gui_features_in_opencv/drawing_functions_in_opencv/screenshots/screenshot_run_in_spyder_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/drawing_functions_in_opencv/screenshots/screenshot_run_in_spyder_2.png -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Images 2 | 3 | ## How to test program 4 | 5 | Open the code in Spyder IDE: 6 | 7 | - Start the Spyder IDE. 8 | - Open the file `load_image.py`. 9 | - Update the current working directory (to the location where the `load_image.py` is stored. 10 | 11 | ![screenshot_run_in_spyder_1.png](./screenshots/screenshot_run_in_spyder_1.png) 12 | 13 | Run the code in Spyder IDE: 14 | 15 | ![screenshot_run_in_spyder_2.png](./screenshots/screenshot_run_in_spyder_2.png) 16 | 17 | Close the image preview window: 18 | 19 | - Hover the mouse over the image preview window. 20 | - Click on any buttons to close the image preview window. (Or click "s" to save as "messi_grayscale.jpg"). 21 | 22 | Try out other images if we like! 23 | 24 | ## References 25 | 26 | See this [OpenCV-Python Tutorial Page - Getting Started with Images](http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_image_display/py_image_display.html#display-image) for the official OpenCV-Python Tutorial Instructions. 27 | 28 | The image [messi.jpg](messi_hd.jpg) (High Definition version) is obtained from [http://www.biznews.com/wp-content/uploads/2014/04/Barcelona.jpg](http://www.biznews.com/wp-content/uploads/2014/04/Barcelona.jpg). 29 | 30 | # cv2.imshow (BGR) versus matplotlib.pyplot (RGB) 31 | 32 | Inspired by a Python code by user "Abid Rahman Kat" at [this Stackoverflow forum](http://stackoverflow.com/questions/15072736/extracting-a-region-from-an-image-using-slicing-in-python-opencv/15074748#15074748), the code `show_cv2_vs_pyplot.py` demonstrates the difference between plotting with cv2 versus matplotlib. 33 | 34 | Simply running the code will reveal the difference between cv2.imshow (default uses BGR) versus matplotlib.pyplot (default uses RGB): 35 | 36 | | Module | BGR | RGB | 37 | |-------------|-----------------|-----------------| 38 | | cv2 | true color | distorted color | 39 | | matplotlib | distorted color | true color | 40 | 41 | ![screenshot_cv2_vs_pyplot.png](./screenshots/screenshot_cv2_vs_pyplot.png) 42 | -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/load_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed May 13 22:04:13 2015 4 | 5 | @author: Johnny 6 | 7 | """ 8 | 9 | #%% 10 | import os 11 | import numpy as np 12 | import cv2 13 | 14 | #%% 15 | # Load an color image. 2nd arg: 1 = color, 0 = grayscale, -1 = unchanged) 16 | img = cv2.imread("messi.jpg", 0) 17 | #print img 18 | 19 | #%% 20 | # Display an image 21 | cv2.imshow('image',img) 22 | k = cv2.waitKey(0) & 0xFF 23 | if k == ord('s'): # wait for 's' key to save and exit 24 | cv2.imwrite("messi_grayscale.jpg",img) 25 | 26 | cv2.destroyAllWindows() 27 | -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_images/messi.jpg -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/messi_grayscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_images/messi_grayscale.jpg -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_cv2_vs_pyplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_cv2_vs_pyplot.png -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_run_in_spyder_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_run_in_spyder_1.png -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_run_in_spyder_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_images/screenshots/screenshot_run_in_spyder_2.png -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_images/show_cv2_vs_pyplot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 14 10:09:22 2015 4 | 5 | @author: Johnny 6 | 7 | Inspired by a Python code by user "Abid Rahman Kat" at this Stackoverflow forum 8 | http://stackoverflow.com/questions/15072736/extracting-a-region-from-an-image-using-slicing-in-python-opencv/15074748#15074748 9 | 10 | It demonstrates the difference between plotting with cv2 versus matplotlib. 11 | 12 | cv2: bgr (true color); rgb (distorted color) 13 | 14 | matplotlib: bgr (distorted color); rgb (true color) 15 | """ 16 | import cv2 17 | import numpy as np 18 | import matplotlib.pyplot as plt 19 | 20 | img = cv2.imread('messi.jpg') 21 | 22 | # A quick way to flip bgr to rgb 23 | img2 = img[:,:,::-1] 24 | 25 | # view matplotlib subplot under IPython Console 26 | plt.subplot(121);plt.title('PyPlot: bgr');plt.imshow(img) # bgr: expects distorted color 27 | plt.subplot(122);plt.title('PyPlot: rgb');plt.imshow(img2) # rgb: expect true color 28 | plt.show() 29 | 30 | # view cv2 plots in separate windows 31 | cv2.imshow('cv2: bgr image',img) # expects true color 32 | cv2.imshow('cv2: rgb image',img2) # expects distorted color 33 | cv2.waitKey(0) 34 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_videos/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Videos 2 | 3 | ## Prerequisites: 4 | 5 | - If run via an IDE (like Anaconda). Make sure to change the current working directory to where this directory (i.e. where the Python file and the input video file is stored). The code uses relative pathnames. So this is mandatory for the Video Capture and writer steps. 6 | - Make sure the `ffmpeg` codec is installed and works within OpenCV. This [Stackoverflow forum](http://stackoverflow.com/questions/23119413/how-to-install-python-opencv-through-conda) has provided a good tip on getting this done. Check out the solution by user [eculeus](http://stackoverflow.com/users/2012659/eculeus). This is mandatory for the Video Writer step. 7 | 8 | ## Test Instructions: 9 | 10 | So here are the files that we have to begin with: 11 | 12 | - `load_video.py`: the python code that we are going to run. 13 | - `input.mp4` the video that we are going to use to test run our code. 14 | 15 | Run the code `load_video.py` and we get a flipped version (`output.avi`)! 16 | 17 | ![before_vs_after.png](./screenshots/before_vs_after.png) 18 | 19 | # References 20 | 21 | The test sample video (`input.mp4`) is originated from [this YouTube Video](https://www.youtube.com/watch?v=3WUUovQwwrM) uploaded by [Brand Spank](https://www.youtube.com/channel/UC-yJ5ogPw3wmWJhyAKEfx2Q). Since at the time of code testing I did not have any video files on my desktop, I used the free and open-source tool [youtube-dl](https://rg3.github.io/youtube-dl/) to download the video from [YouTube](https://www.youtube.com), save it as a MPEG4 (`.mp4`) file. The code uses this `.mp4` file and output a `.avi` format video. The use of this video is purely for illustration purpose. 22 | -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_videos/input.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_videos/input.mp4 -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_videos/load_video.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 14 12:10:14 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | #%% 9 | import numpy as np 10 | import cv2 11 | 12 | #%% 13 | cap = cv2.VideoCapture("input.mp4") 14 | #%% 15 | cap 16 | #%% 17 | print cap.isOpened() 18 | #%% 19 | # Define the codec and create VideoWriter object 20 | fourcc = cv2.VideoWriter_fourcc(*'XVID') 21 | #fourcc = cv2.cv.CV_FOURCC(*'XVID') 22 | 23 | #%% 24 | out = cv2.VideoWriter("output.avi",fourcc, 20.0, (640,360)) 25 | 26 | #%% 27 | print out.isOpened() 28 | #%% 29 | while(cap.isOpened()): 30 | ret, frame = cap.read() 31 | if ret==True: 32 | frame = cv2.flip(frame,0) 33 | 34 | # write the flipped frame 35 | out.write(frame) 36 | 37 | cv2.imshow('frame',frame) 38 | if cv2.waitKey(1) & 0xFF == ord('q'): 39 | break 40 | else: 41 | break 42 | #%% 43 | # Release everything if job is finished 44 | cap.release() 45 | out.release() 46 | cv2.destroyAllWindows() 47 | -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_videos/output.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_videos/output.avi -------------------------------------------------------------------------------- /gui_features_in_opencv/getting_started_with_videos/screenshots/before_vs_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/getting_started_with_videos/screenshots/before_vs_after.png -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/README.md: -------------------------------------------------------------------------------- 1 | # Mouse as a Paint Brush 2 | 3 | This the original official tutorial [at this OpenCV-Python Tutorial Page - Mouse as a Paint Brush](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_mouse_handling/py_mouse_handling.html#simple-demo). 4 | 5 | # Check what mouse events are available 6 | 7 | Run the code `print_available_events.py` will print out the list of available list of events to choose from. In this case, the output is: 8 | 9 | ``` 10 | ['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON', 'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP'] 11 | ``` 12 | 13 | # Draw Circle Demo 14 | 15 | This demo is pretty cool. Run the code `draw_circle_demo.py`. 16 | 17 | It opens up a square black canvas (window). Hover over any point on the canvas. If you do a double click on the mouse, it draws out a blue circle. 18 | 19 | Double click the mouse at different points will draw circles at those points. 20 | 21 | Hit the `Esc` button to exit. 22 | 23 | ![circle_demo_1.PNG](./screenshots/circle_demo_1.PNG) 24 | 25 | ![circle_demo_2.PNG](./screenshots/circle_demo_2.PNG) 26 | 27 | ![circle_demo_3.PNG](./screenshots/circle_demo_3.PNG) 28 | 29 | # Advanced Demo 30 | 31 | An even cooler demo. Run the code `run_advanced_demo.py`. 32 | 33 | It opens up a square black canvas (window). Hover over any point on the canvas. 34 | 35 | Hold down mouse and draw to create square shapes. 36 | 37 | Type "m" (on keyboard) to switch to draw circle mode. Hold down mouse and move round canvas to draw. 38 | 39 | Type "m" (on keyboard) to switch back to draw square mode. 40 | 41 | Hit the `Esc` button to exit. 42 | 43 | ![advanced_demo_1.PNG](./screenshots/advanced_demo_1.PNG) 44 | 45 | ![advanced_demo_2.PNG](./screenshots/advanced_demo_2.PNG) 46 | 47 | ![advanced_demo_3.PNG](./screenshots/advanced_demo_3.PNG) 48 | 49 | # Conclusions 50 | 51 | Here we have run a few demos relating to using the mouse and keyboard to draw circles and squares. This concept will aid our understanding in later concepts such as object tracking and image segmentation. 52 | -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/draw_circle_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue May 19 20:47:23 2015 4 | 5 | @author: Johnny 6 | 7 | This is the draw circle demo. 8 | """ 9 | 10 | import cv2 11 | import numpy as np 12 | 13 | # mouse callback function 14 | def draw_circle(event,x,y,flags,param): 15 | if event == cv2.EVENT_LBUTTONDBLCLK: 16 | cv2.circle(img,(x,y),100,(255,0,0),-1) 17 | 18 | # Create a black image, a window and bind the function to window 19 | img = np.zeros((512,512,3), np.uint8) 20 | cv2.namedWindow('image') 21 | cv2.setMouseCallback('image',draw_circle) 22 | 23 | while(1): 24 | cv2.imshow('image',img) 25 | if cv2.waitKey(20) & 0xFF == 27: # Esc key to stop 26 | break 27 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/print_available_events.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue May 19 20:38:04 2015 4 | 5 | @author: Johnny 6 | 7 | Print all available events to choose from. 8 | """ 9 | 10 | import cv2 11 | 12 | events = [i for i in dir(cv2) if 'EVENT' in i] 13 | print events -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/run_advanced_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue May 19 21:23:56 2015 4 | 5 | @author: Johnny 6 | 7 | A more advance demo on using mouse as a paint brush. 8 | Hold on to mouse and drag to draw rectangle. 9 | Click m to switch to draw mode. 10 | """ 11 | 12 | import cv2 13 | import numpy as np 14 | 15 | drawing = False # true if mouse is pressed 16 | mode = True # if True, draw rectangle. Press 'm' to toggle to curve 17 | ix,iy = -1,-1 18 | 19 | # mouse callback function 20 | def draw_circle(event,x,y,flags,param): 21 | global ix,iy,drawing,mode 22 | 23 | if event == cv2.EVENT_LBUTTONDOWN: 24 | drawing = True 25 | ix,iy = x,y 26 | 27 | elif event == cv2.EVENT_MOUSEMOVE: 28 | if drawing == True: 29 | if mode == True: 30 | cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) 31 | else: 32 | cv2.circle(img,(x,y),5,(0,0,255),-1) 33 | 34 | elif event == cv2.EVENT_LBUTTONUP: 35 | drawing = False 36 | if mode == True: 37 | cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) 38 | else: 39 | cv2.circle(img,(x,y),5,(0,0,255),-1) 40 | 41 | # Main program to bind the mouse callback function 42 | img = np.zeros((512,512,3), np.uint8) 43 | cv2.namedWindow('image') 44 | cv2.setMouseCallback('image',draw_circle) 45 | 46 | while(1): 47 | cv2.imshow('image',img) 48 | k = cv2.waitKey(1) & 0xFF 49 | if k == ord('m'): 50 | mode = not mode 51 | elif k == 27: 52 | break 53 | 54 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_1.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_2.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/advanced_demo_3.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_1.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_2.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/mouse_as_a_paint_brush/screenshots/circle_demo_3.PNG -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/README.md: -------------------------------------------------------------------------------- 1 | # Trackbar as the Color Palette 2 | 3 | See [OpenCV-Python Tutorial - Trakbar as the Color palette](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_trackbar/py_trackbar.html#trackbar) for the original tutorial. 4 | 5 | ## Demo Instructions 6 | 7 | Run the program `run_trackbar_tutorial.py`. The output looks like this: 8 | 9 | ![trackbar_1.png](./screenshots/trackbar_1.png) 10 | 11 | ![trackbar_2.png](./screenshots/trackbar_2.png) 12 | 13 | ![trackbar_3.png](./screenshots/trackbar_3.png) 14 | 15 | ![trackbar_4.png](./screenshots/trackbar_4.png) 16 | 17 | ![trackbar_5.png](./screenshots/trackbar_5.png) 18 | 19 | ![trackbar_6.png](./screenshots/trackbar_6.png) 20 | 21 | Hit the "Esc" key to close the window. 22 | -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/run_trackbar_tutorial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 21 10:36:32 2015 4 | 5 | @author: Johnny 6 | 7 | Taken from: 8 | [OpenCV-Python Tutorial - Trakbar as the Color palette] 9 | (https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_gui/py_trackbar/py_trackbar.html#trackbar) 10 | """ 11 | 12 | import cv2 13 | import numpy as np 14 | 15 | def nothing(x): 16 | pass 17 | 18 | # Create a black image, a window 19 | img = np.zeros((300,512,3), np.uint8) 20 | cv2.namedWindow('image') 21 | 22 | # create trackbars for color change 23 | cv2.createTrackbar('R','image',0,255,nothing) 24 | cv2.createTrackbar('G','image',0,255,nothing) 25 | cv2.createTrackbar('B','image',0,255,nothing) 26 | 27 | # create switch for ON/OFF functionality 28 | switch = '0 : OFF \n1 : ON' 29 | cv2.createTrackbar(switch, 'image',0,1,nothing) 30 | 31 | while(1): 32 | cv2.imshow('image',img) 33 | k = cv2.waitKey(1) & 0xFF 34 | if k == 27: 35 | break 36 | 37 | # get current positions of four trackbars 38 | r = cv2.getTrackbarPos('R','image') 39 | g = cv2.getTrackbarPos('G','image') 40 | b = cv2.getTrackbarPos('B','image') 41 | s = cv2.getTrackbarPos(switch,'image') 42 | 43 | if s == 0: 44 | img[:] = 0 45 | else: 46 | img[:] = [b,g,r] 47 | 48 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_1.png -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_2.png -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_3.png -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_4.png -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_5.png -------------------------------------------------------------------------------- /gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/gui_features_in_opencv/trackbar_as_the_color_palette/screenshots/trackbar_6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/README.md: -------------------------------------------------------------------------------- 1 | # Image Processing in OpenCV 2 | 3 | See [OpenCV-Python Tutorials - Image Processing in OpenCV](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_table_of_contents_imgproc/py_table_of_contents_imgproc.html) for the original tutorials. 4 | -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/README.md: -------------------------------------------------------------------------------- 1 | # Canny Edge Detection 2 | 3 | See [OpenCV-Python Tutorials - Canny Edge Detection](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_canny/py_canny.html#canny) for the original tutorials. 4 | 5 | # Basic Canny Edge Detection Program 6 | 7 | Code: `simple_canny.py` 8 | 9 | This is the basic code that illustrate the `cv2.Canny()` Canny Edge Detection method. This illustration code uses a fix lower grayscale threshold of 100 and upper threshold of 200. (Grayscale threshold has a range of between 0 and 255) 10 | 11 | Demo output: 12 | 13 | ![simple_canny.png](./screenshots/simple_canny.png) 14 | 15 | # Exercise 1: Enhanced Canny Edge Detection Program with Threshold Trackbars 16 | 17 | The challenge: write a small application to find the Canny edge detection whose threshold values can be varied using two trackbars. This way, you can understand the effect of threshold values. 18 | 19 | ## Exercise 1 Solution 20 | 21 | This is a possible solution: `trackbar_canny.py`. 22 | 23 | Run the code and it will display the "original" and "canny" images side-by-side. 24 | 25 | Youtube Demo: 26 | 27 | [![youtube_video_link](./screenshots/youtube_thumb.png)](https://youtu.be/A0OFX6W1AcA) 28 | 29 | Snapshot Demo: 30 | 31 | ![trackbar_canny_1.png](./screenshots/trackbar_canny_1.png) 32 | 33 | ![trackbar_canny_2.png](./screenshots/trackbar_canny_2.png) 34 | 35 | ![trackbar_canny_3.png](./screenshots/trackbar_canny_3.png) 36 | 37 | ![trackbar_canny_4.png](./screenshots/trackbar_canny_4.png) 38 | 39 | ![trackbar_canny_5.png](./screenshots/trackbar_canny_5.png) 40 | 41 | ![trackbar_canny_6.png](./screenshots/trackbar_canny_6.png) 42 | 43 | ![trackbar_canny_7.png](./screenshots/trackbar_canny_7.png) 44 | 45 | When done playing, hit the "Esc" key to quit. 46 | -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/messi.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/simple_canny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/simple_canny.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/trackbar_canny_7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/screenshots/youtube_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/canny_edge_detection/screenshots/youtube_thumb.png -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/simple_canny.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 02 21:31:17 2015 4 | This is the basic Canny Edge Detection code supplied by the 5 | original OpenCV-Python Tutorials. 6 | @author: Johnny 7 | """ 8 | 9 | import cv2 10 | from matplotlib import pyplot as plt 11 | 12 | img = cv2.imread('messi.jpg', 0) 13 | edges = cv2.Canny(img, 100, 200) 14 | 15 | plt.subplot(121), plt.imshow(img, cmap='gray') 16 | plt.title('Original Image'), plt.xticks([]), plt.yticks([]) 17 | plt.subplot(122), plt.imshow(edges, cmap='gray') 18 | plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) 19 | 20 | plt.show() 21 | -------------------------------------------------------------------------------- /image_processing_in_opencv/canny_edge_detection/trackbar_canny.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 02 21:31:17 2015 4 | Canny Edge Detection tool with trackbars for varying thresholds. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | 10 | 11 | # this function is needed for the createTrackbar step downstream 12 | def nothing(x): 13 | pass 14 | 15 | # read the experimental image 16 | img = cv2.imread('messi.jpg', 0) 17 | 18 | # create trackbar for canny edge detection threshold changes 19 | cv2.namedWindow('canny') 20 | 21 | # add ON/OFF switch to "canny" 22 | switch = '0 : OFF \n1 : ON' 23 | cv2.createTrackbar(switch, 'canny', 0, 1, nothing) 24 | 25 | # add lower and upper threshold slidebars to "canny" 26 | cv2.createTrackbar('lower', 'canny', 0, 255, nothing) 27 | cv2.createTrackbar('upper', 'canny', 0, 255, nothing) 28 | 29 | # Infinite loop until we hit the escape key on keyboard 30 | while(1): 31 | 32 | # get current positions of four trackbars 33 | lower = cv2.getTrackbarPos('lower', 'canny') 34 | upper = cv2.getTrackbarPos('upper', 'canny') 35 | s = cv2.getTrackbarPos(switch, 'canny') 36 | 37 | if s == 0: 38 | edges = img 39 | else: 40 | edges = cv2.Canny(img, lower, upper) 41 | 42 | # display images 43 | cv2.imshow('original', img) 44 | cv2.imshow('canny', edges) 45 | k = cv2.waitKey(1) & 0xFF 46 | if k == 27: # hit escape to quit 47 | break 48 | 49 | cv2.destroyAllWindows() 50 | -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/README.md: -------------------------------------------------------------------------------- 1 | # Image Processing in OpenCV 2 | 3 | See [OpenCV-Python - Image Processing in OpenCV](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_table_of_contents_imgproc/py_table_of_contents_imgproc.html) for the original tutorials. 4 | 5 | # Track Blue Ball 6 | 7 | The code `track_blue_ball.py` illustrate this. 8 | 9 | The key is to find the lower and upper HSV range of the color to track. (`lower_blue` and `upper_blue`). I estimated these values using GIMP (in which the Hue value ranges between 0 and 360. So whatever I get in GIMP I just need to halve it in order to get the equivalent OpenCV Hue value.) 10 | 11 | Note: I downloaded the video `big_blue_ball_machine_8HZPb7ulu08.mp4` from Youtube. 12 | 13 | Some screenshots: 14 | 15 | Frame: 16 | 17 | ![shoot_1_frame.png](./screenshots/shoot_1_frame.png) 18 | 19 | Mask: 20 | 21 | ![shoot_1_mask.png](./screenshots/shoot_1_mask.png) 22 | 23 | Result: 24 | 25 | ![shoot_1_res.png](./screenshots/shoot_1_res.png) 26 | 27 | 28 | # Demo convert GBR to HSV 29 | 30 | The code `demo_gbr_to_hsv` illustrates quick conversion from one color space (GBR) to another (HSV). 31 | -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/big_blue_ball_machine_8HZPb7ulu08.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/big_blue_ball_machine_8HZPb7ulu08.mp4 -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/demo_gbr_to_hsv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 13:33:15 2015 4 | Illustrate converting from GBR to HSV color space. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | green = np.uint8([[[0,255,0 ]]]) 12 | hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV) 13 | print hsv_green 14 | # [[[ 60 255 255]]] -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/images/blue_ball_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/images/blue_ball_1.PNG -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/screenshots/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/screenshots/Thumbs.db -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_frame.png -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_mask.png -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/changing-colorspaces/screenshots/shoot_1_res.png -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/show_color_conversion_methods.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Spyder Editor 4 | 5 | This is a temporary script file. 6 | """ 7 | 8 | import cv2 9 | flags = [i for i in dir(cv2) if i.startswith('COLOR_')] 10 | #print flags 11 | for i in flags: 12 | print i -------------------------------------------------------------------------------- /image_processing_in_opencv/changing-colorspaces/track_blue_ball.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat May 23 16:39:27 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | #%% 12 | cap = cv2.VideoCapture("big_blue_ball_machine_8HZPb7ulu08.mp4") 13 | cap.isOpened() 14 | #%% 15 | while(1): 16 | 17 | # Take each frame 18 | _, frame = cap.read() 19 | 20 | # Convert BGR to HSV 21 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 22 | 23 | # define range of blue color in HSV 24 | lower_blue = np.array([96,41,44]) 25 | upper_blue = np.array([160,255,255]) 26 | 27 | # Threshold the HSV image to get only blue colors 28 | mask = cv2.inRange(hsv, lower_blue, upper_blue) 29 | 30 | # Bitwise-AND mask and original image 31 | res = cv2.bitwise_and(frame,frame, mask= mask) 32 | 33 | cv2.imshow('frame',frame) 34 | cv2.imshow('mask',mask) 35 | cv2.imshow('res',res) 36 | if cv2.waitKey(25) & 0xFF == ord('q'): # hit "q to exit. 37 | break 38 | 39 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/README.md: -------------------------------------------------------------------------------- 1 | # Contours in OpenCV 2 | 3 | See [OpenCV-Python - Contours in OpenCV](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_table_of_contents_imgproc/py_table_of_contents_imgproc.html) for the original tutorials. 4 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/README.md: -------------------------------------------------------------------------------- 1 | # Contours Features 2 | 3 | See [OpenCV-Python - Contour Features](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html#contour-features) for the original tutorials. 4 | 5 | # Moments 6 | 7 | The code `demo_moments.py` illustrate computation of the internal area bounded by a contour. 8 | 9 | Sample Image: 10 | 11 | ![blue1.png](./screenshots/blue1.png) 12 | 13 | Computed moments: 14 | 15 | ``` 16 | {'mu02': 61222871.79252696, 'mu03': -40137.822982788086, 'm11': 650567591.9166666, 'nu02': 0.07628711803059755, 'm12': 106985566150.75, 'mu21': 50080.6704750061, 'mu20': 66620763.09886503, 'nu20': 0.08301319211282009, 'm30': 132152169588.75, 'nu21': 3.707592743768182e-07, 'mu11': 1205.5144815444946, 'mu12': -143020.32474708557, 'nu11': 1.5021383814341916e-06, 'nu12': -1.058813936024084e-06, 'm02': 699019932.8333333, 'm03': 123257942828.5, 'm00': 28329.0, 'm01': 4250665.0, 'mu30': 159372.7953338623, 'nu30': 1.1798752171833967e-06, 'nu03': -2.9714997788599144e-07, 'm10': 4335767.5, 'm20': 730212129.3333333, 'm21': 109566134107.41667} 17 | ``` 18 | 19 | # Contour Area 20 | 21 | The code `demo_area.py` illustrate computation of the internal area bounded by a contour. 22 | 23 | Sample Image: 24 | 25 | ![blue1.png](./screenshots/blue1.png) 26 | 27 | Computed area (in pixels): `28329.0` 28 | 29 | # Contour Perimeter 30 | 31 | The code `demo_perimeter.py` illustrate computation of a contour perimeter. 32 | 33 | Sample Image: 34 | 35 | ![blue1.png](./screenshots/blue1.png) 36 | 37 | Computed perimeter (in pixels): `631.126977205` 38 | 39 | # Contour Approximation 40 | 41 | The code `demo_contour_approx.py` illustrate computation of approximated contour points at varying epsilon factor (i.e. proportion of perimeter). This is essentially the maximum distance of approximated contour from the actual object boundary line allowable - the smaller the epsilon factor, the more accurate the contour points (but more costly - as more points are required). 42 | 43 | Sample Image: 44 | 45 | ![blue0.png](./screenshots/blue0.png) 46 | 47 | Output at Epsilon Factor `0.5`: 48 | 49 | ![approx_plate_contour_epsi_0p5.png](./screenshots/approx_plate_contour_epsi_0p5.png) 50 | 51 | Output at Epsilon Factor `0.1`: 52 | 53 | ![approx_plate_contour_epsi_0p1.png](./screenshots/approx_plate_contour_epsi_0p1.png) 54 | 55 | Output at Epsilon Factor `0.05`: 56 | 57 | ![approx_plate_contour_epsi_0p05.png](./screenshots/approx_plate_contour_epsi_0p05.png) 58 | 59 | Output at Epsilon Factor `0.01`: 60 | 61 | ![approx_plate_contour_epsi_0p01.png](./screenshots/approx_plate_contour_epsi_0p01.png) 62 | 63 | Output at Epsilon Factor `0.001`: 64 | 65 | ![approx_plate_contour_epsi_0p001.png](./screenshots/approx_plate_contour_epsi_0p001.png) 66 | 67 | # Convex Hull and Checking Convexity 68 | 69 | The code `demo_contour_convexity.py` illustrate the creation of Convex Hull contour, and checking the hull convexity (`True` or `False`). 70 | 71 | Output: 72 | 73 | ![hull1.png](./screenshots/hull1.png) 74 | 75 | The `cv2.isContourConvex(hull)` step in the code returns `True` - indicating that the image is a convex shape. 76 | 77 | # Bounding Rectangle 78 | 79 | The code `demo_bounding_rectangle.py` illustrate both straight and rotated bounding rectangles. 80 | 81 | Output: 82 | 83 | ![bounding_rectangle.png](./screenshots/bounding_rectangle.png) 84 | 85 | # Minimum Enclosing Circle 86 | 87 | The code `demo_min_enclosing_circle.py` illustrate minimum enclosing circle. 88 | 89 | Output: 90 | 91 | ![min_circle.png](./screenshots/min_circle.png) 92 | 93 | # Fit an eclipse 94 | 95 | The code `demo_fit_eclipse.py` illustrate fitting a rotated eclipse to a shape. It is essentially a rotated rectangle, but with a eclipse instead. 96 | 97 | Output: 98 | 99 | ![fit_eclipse.png](./screenshots/fit_eclipse.png) 100 | 101 | # Fit a line 102 | 103 | The code `demo_fit_line.py` illustrate fitting a line to a shape. 104 | 105 | Output: 106 | 107 | ![fit_line.png](./screenshots/fit_line.png) 108 | 109 | # Bonus: Trackbar Contour Approximation App 110 | 111 | The code: `trackbar_contour_approx.py`. 112 | 113 | This is my attempt to enhance the Contour Approximation Program (See the Contour Approximation Section above) by adding a trackbar corresponding to the epsilon factor. 114 | 115 | Due to the fact that trackbar takes on integer values only, if we are to vary at decimal levels (e.g. 0.001, 0.01, 0.1, etc.), I've figured that if I have a step internally within the code that divide integer trackbar by some sort of scaling factor, say 1000. For example, Say on the trackbar I have an integer value of 5, to convert that to 0.005, I would require a scaling factor of 1000. i.e. `5 / 1000 = 0.005`. 116 | 117 | Some snaoshots: 118 | 119 | ![tb_approx_1.png](./screenshots/tb_approx_1.png) 120 | 121 | ![tb_approx_2.png](./screenshots/tb_approx_2.png) 122 | 123 | ![tb_approx_3.png](./screenshots/tb_approx_3.png) 124 | 125 | ![tb_approx_4.png](./screenshots/tb_approx_4.png) 126 | 127 | ![tb_approx_5.png](./screenshots/tb_approx_5.png) 128 | 129 | ![tb_approx_6.png](./screenshots/tb_approx_6.png) 130 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue0.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/blue_thunder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/blue_thunder.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_area.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | #%% 9 | import cv2 10 | import numpy as np 11 | 12 | #%% 13 | img = cv2.imread('blue1.png', 0) 14 | 15 | #%% 16 | ret, thresh = cv2.threshold(img, 0, 255, 0) 17 | mask = thresh.copy() 18 | #%% 19 | thresh, contours, hierarchy = cv2.findContours(thresh, 1, 2) 20 | #%% 21 | cv2.imshow("img", img) 22 | cv2.imshow("mask", mask) 23 | cv2.imshow("thresh", thresh) 24 | cv2.waitKey() 25 | cv2.destroyAllWindows() 26 | 27 | #%% 28 | cnt = contours[0] 29 | area = cv2.contourArea(cnt) 30 | print area -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_bounding_rectangle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate bounding rectangle (straight and rotated) 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | img = cv2.imread('blue_thunder.png') 12 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 13 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 14 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 15 | cnt = contours[0] 16 | 17 | # Straight bounding rectangle 18 | x, y, w, h = cv2.boundingRect(cnt) 19 | img_bound_s = img.copy() 20 | img_bound_s = cv2.rectangle(img_bound_s, (x, y), (x+w, y+h), (0, 255, 0), 2) 21 | 22 | # Rotated bounding rectangle 23 | rect = cv2.minAreaRect(cnt) 24 | box = cv2.boxPoints(rect) 25 | box = np.int0(box) 26 | img_bound_r = img.copy() 27 | img_bound_r = cv2.drawContours(img_bound_r, [box], 0, (0, 0, 255), 2) 28 | 29 | # Display all 30 | cv2.imshow("Original", img) 31 | cv2.imshow("Straight Bounding Rectangle", img_bound_s) 32 | cv2.imshow("Rotated Bounding Rectangle", img_bound_r) 33 | cv2.waitKey() 34 | cv2.destroyAllWindows() 35 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_contour_approx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate a simple contour approximation example. 5 | Try playing around with "factor" - the smaller the more accurate (and costly). 6 | (whilst keeping "threshold" constant) 7 | @author: Johnny 8 | """ 9 | 10 | 11 | import cv2 12 | import numpy as np 13 | 14 | img = cv2.imread('blue0.png') 15 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 16 | 17 | threshold = 50 # Adjust this if neccessary 18 | ret, img_thresh = cv2.threshold(img_gray, threshold, 255, cv2.THRESH_BINARY) 19 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 20 | cnt = contours[0] # note that in this example there is only one contour 21 | perimeter = cv2.arcLength(cnt, True) 22 | 23 | # configure approx factor (with repect to perimeter) - the lower, the more accurate 24 | factor = 0.001 # vary this to see the effect (the smaller the more accurate but costly) 25 | epsilon = factor*perimeter 26 | approx = cv2.approxPolyDP(cnt, epsilon, True) 27 | 28 | # Prepare a blank canvas to draw on... 29 | img_blank = np.zeros(img.shape, np.uint8) 30 | 31 | # Draw all contour points only 32 | img_approx_points = img_blank.copy() 33 | cv2.drawContours(img_approx_points, approx, -1, (0, 0, 255), 3) 34 | 35 | # Draw the first contour line only (There is only one for this example) 36 | img_approx_line = img_blank.copy() 37 | cv2.drawContours(img_approx_line, [approx], 0, (0, 255, 0), 1) 38 | 39 | # Display a unified picture 40 | img_unified = img.copy() # original 41 | cv2.drawContours(img_unified, [approx], 0, (0, 255, 0), 1) # line 42 | cv2.drawContours(img_unified, approx, -1, (0, 0, 255), 3) # points 43 | 44 | # Display in windows... 45 | cv2.imshow("img", img) 46 | cv2.imshow("img_gray", img_gray) 47 | cv2.imshow("img_thresh", img_thresh) 48 | cv2.imshow("img_approx_points", img_approx_points) 49 | cv2.imshow("img_approx_line", img_approx_line) 50 | cv2.imshow("img_unified", img_unified) 51 | cv2.waitKey() 52 | cv2.destroyAllWindows() 53 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_contour_convexity.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate contouring an image with Hull Convexity. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | img = cv2.imread('blue2.png') 12 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 13 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 14 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 15 | cnt = contours[0] 16 | hull = cv2.convexHull(cnt) 17 | 18 | # check hull convexity 19 | k = cv2.isContourConvex(hull) 20 | print k 21 | 22 | # Create the hull contour image 23 | img_blank = np.zeros(img.shape, np.uint8) 24 | img_hull = img_blank.copy() 25 | cv2.drawContours(img_hull, hull, -1, (0, 0, 255), 3) # plot points 26 | cv2.drawContours(img_hull, [hull], 0, (0, 255, 0), 1) # draw line 27 | 28 | # Overlay hull contour on original image 29 | img_unified = img.copy() 30 | cv2.drawContours(img_unified, hull, -1, (0, 0, 255), 3) 31 | cv2.drawContours(img_unified, [hull], 0, (0, 255, 0), 1) 32 | 33 | # Display all 34 | cv2.imshow("img", img) 35 | cv2.imshow("img_hull", img_hull) 36 | cv2.imshow("img_unified", img_unified) 37 | cv2.waitKey() 38 | cv2.destroyAllWindows() 39 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_fit_eclipse.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate fitting an eclipse to a shape. Essentially a rotated rectangle (but eclipse shape). 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | 12 | img = cv2.imread('blue_thunder.png') 13 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 14 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 15 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 16 | cnt = contours[0] 17 | 18 | # Fit a rotated eclipse 19 | ellipse = cv2.fitEllipse(cnt) 20 | img_eclipse = img.copy() 21 | img_eclipse = cv2.ellipse(img_eclipse, ellipse, (0, 255, 0), 2) 22 | 23 | # Display all 24 | cv2.imshow("Original", img) 25 | cv2.imshow("Fit an eclipse", img_eclipse) 26 | cv2.waitKey() 27 | cv2.destroyAllWindows() 28 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_fit_line.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate fitting a line to a shape. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | 12 | img = cv2.imread('blue_thunder.png') 13 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 14 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 15 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 16 | cnt = contours[0] 17 | 18 | # Fit a line 19 | rows, cols = img.shape[:2] 20 | [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) 21 | lefty = int((-x*vy/vx) + y) 22 | righty = int(((cols-x)*vy/vx)+y) 23 | img_line = img.copy() 24 | img_line = cv2.line(img_line, (cols-1, righty), (0, lefty), (0, 255, 0), 2) 25 | 26 | # Display all 27 | cv2.imshow("Original", img) 28 | cv2.imshow("Fit a line", img_line) 29 | cv2.waitKey() 30 | cv2.destroyAllWindows() 31 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_min_enclosing_circle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Illustrate Minimum Enclosing Circle. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | 12 | img = cv2.imread('blue_thunder.png') 13 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 14 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 15 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 16 | cnt = contours[0] 17 | 18 | # Minimum Enclosing Circle 19 | (x, y), radius = cv2.minEnclosingCircle(cnt) 20 | center = (int(x), int(y)) 21 | radius = int(radius) 22 | img_circle = img.copy() 23 | img_circle = cv2.circle(img_circle, center, radius, (0, 255, 0), 2) 24 | 25 | # Display all 26 | cv2.imshow("Original", img) 27 | cv2.imshow("Minimum Enclosing Circle", img_circle) 28 | cv2.waitKey() 29 | cv2.destroyAllWindows() 30 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_moments.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | #%% 9 | import cv2 10 | import numpy as np 11 | 12 | #%% 13 | img = cv2.imread('blue1.png', 0) 14 | 15 | #%% 16 | ret, thresh = cv2.threshold(img, 0, 255, 0) 17 | mask = thresh.copy() 18 | #%% 19 | thresh, contours, hierarchy = cv2.findContours(thresh, 1, 2) 20 | #%% 21 | cv2.imshow("img", img) 22 | cv2.imshow("mask", mask) 23 | cv2.imshow("thresh", thresh) 24 | cv2.waitKey() 25 | cv2.destroyAllWindows() 26 | 27 | #%% 28 | cnt = contours[0] 29 | M = cv2.moments(cnt) 30 | print M -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/demo_perimeter.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | 9 | #%% 10 | import cv2 11 | import numpy as np 12 | 13 | #%% 14 | img = cv2.imread('blue1.png', 0) 15 | 16 | #%% 17 | ret, thresh = cv2.threshold(img, 0, 255, 0) 18 | mask = thresh.copy() 19 | #%% 20 | thresh, contours, hierarchy = cv2.findContours(thresh, 1, 2) 21 | #%% 22 | cv2.imshow("img", img) 23 | cv2.imshow("mask", mask) 24 | cv2.imshow("thresh", thresh) 25 | cv2.waitKey() 26 | cv2.destroyAllWindows() 27 | 28 | #%% 29 | cnt = contours[0] 30 | perimeter = cv2.arcLength(cnt, True) 31 | print perimeter -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p001.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p01.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p05.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/approx_plate_contour_epsi_0p5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/blue0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/blue0.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/blue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/blue1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/bounding_rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/bounding_rectangle.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/fit_eclipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/fit_eclipse.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/fit_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/fit_line.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/hull1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/hull1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/min_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/min_circle.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_features/screenshots/tb_approx_6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_features/trackbar_contour_approx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 11 13:08:09 2015 4 | Enhance the tutorial contour approximation example by adding trackbars to make experiments easier. 5 | Try playing around with "factor" - the smaller the more accurate (and costly). 6 | @author: Johnny 7 | """ 8 | 9 | 10 | import cv2 11 | import numpy as np 12 | 13 | # this function is needed for the createTrackbar step downstream 14 | def nothing(x): 15 | pass 16 | 17 | # Read image 18 | img = cv2.imread('blue7.png') 19 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 20 | 21 | # Prepare a blank canvas to draw on... 22 | img_blank = np.zeros(img.shape, np.uint8) 23 | 24 | # Control panel 25 | control_panel = "Control"; 26 | cv2.namedWindow(control_panel) 27 | 28 | # add epsilon_factor trackbar to control panel 29 | sliding_eps_factor = 'Epsilon Factor' 30 | eps_scaling = 1000 31 | cv2.createTrackbar(sliding_eps_factor, control_panel, 100, eps_scaling, nothing) 32 | 33 | # add this dummy image to control panel so it become wider 34 | img_control = np.zeros((20, 500), np.uint8) 35 | 36 | # Infinite loop until we hit the escape key on keyboard 37 | while(1): 38 | 39 | # get current positions of the trackbars 40 | value_eps_factor = cv2.getTrackbarPos(sliding_eps_factor, control_panel) 41 | 42 | # apply threshold and create a mask (img_thresh will get overwritten downstream) 43 | ret, img_thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY) 44 | img_mask = img_thresh.copy() 45 | 46 | # identify contours 47 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 48 | cnt = contours[0] # This program only picks out the first contour (a limitation) 49 | perimeter = cv2.arcLength(cnt, True) 50 | factor = (value_eps_factor * 1.) / (eps_scaling * 1.) 51 | epsilon = factor * perimeter 52 | approx = cv2.approxPolyDP(cnt, epsilon, True) 53 | 54 | # Draw all contour points only 55 | img_approx_points = img_blank.copy() 56 | cv2.drawContours(img_approx_points, approx, -1, (0, 0, 255), 3) 57 | 58 | # Draw the first contour line only (There is only one for this example) 59 | img_approx_line = img_blank.copy() 60 | cv2.drawContours(img_approx_line, [approx], 0, (0, 255, 0), 1) 61 | 62 | # Display a unified picture 63 | img_unified = img.copy() 64 | cv2.drawContours(img_unified, [approx], 0, (0, 255, 0), 1) # line 65 | cv2.drawContours(img_unified, approx, -1, (0, 0, 255), 3) # points 66 | 67 | # Display in windows... 68 | cv2.imshow(control_panel, img_control) 69 | cv2.imshow("img", img) 70 | cv2.imshow("img_gray", img_gray) 71 | cv2.imshow("img_mask", img_mask) 72 | cv2.imshow("img_approx_points", img_approx_points) 73 | cv2.imshow("img_approx_line", img_approx_line) 74 | cv2.imshow("img_unified", img_unified) 75 | k = cv2.waitKey(1) & 0xFF 76 | if k == 27: # hit escape to quit 77 | break 78 | 79 | cv2.destroyAllWindows() 80 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/Contour.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 18 09:34:32 2015 4 | A Contour Class that describe contour properties and methods. 5 | Limitations: 6 | - can only take on an image that contains 1 contour line. 7 | @author: Johnny 8 | """ 9 | #%% 10 | import cv2 11 | import numpy as np 12 | 13 | 14 | class Contour(object): 15 | 16 | def __init__(self, an_image_file): 17 | 18 | self.file_name = an_image_file 19 | self.img = self.get_img(self.file_name) 20 | self.img_gray = self.get_img_gray(self.img) 21 | self.img_thresh = self.get_img_thresh(self.img_gray) 22 | self.coordinates = self.get_coordinates(self.img_thresh) 23 | self.aspect_ratio = self.get_aspect_ratio(self.coordinates) 24 | self.extent = self.get_extent(self.coordinates) 25 | self.solidity = self.get_solidity(self.coordinates) 26 | self.equivalent_diameter = self.get_equivalent_diameter(self.coordinates) 27 | self.area = self.get_area(self.coordinates) 28 | self.orientation = self.get_orientation(self.coordinates) 29 | self.mask = self.get_mask(self.img_gray, self.coordinates) 30 | self.pixel_points = self.get_pixel_points(self.img_gray, self.mask) 31 | self.min_max_loc = self.get_min_max_loc(self.img_gray, self.mask) 32 | self.mean_val = self.get_mean_val(self.img, self.mask) 33 | self.extreme_points = self.get_extream_points(self.coordinates) 34 | 35 | def get_img(self, an_image_file): 36 | img = cv2.imread(an_image_file) 37 | return img 38 | 39 | def get_img_gray(self, img): 40 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 41 | return img_gray 42 | 43 | def get_img_thresh(self, img_gray): 44 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 45 | return img_thresh 46 | 47 | def get_coordinates(self, img_thresh): 48 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 49 | return contours[0] 50 | 51 | def get_aspect_ratio(self, cnt): 52 | x, y, w, h = cv2.boundingRect(cnt) 53 | aspect_ratio = float(w)/h 54 | return aspect_ratio 55 | 56 | def get_extent(self, cnt): 57 | area = cv2.contourArea(cnt) 58 | x, y, w, h = cv2.boundingRect(cnt) 59 | rect_area = w*h 60 | extent = float(area) / rect_area 61 | return extent 62 | 63 | def get_solidity(self, cnt): 64 | area = cv2.contourArea(cnt) 65 | hull = cv2.convexHull(cnt) 66 | hull_area = cv2.contourArea(hull) 67 | solidity = float(area)/hull_area 68 | return solidity 69 | 70 | def get_equivalent_diameter(self, cnt): 71 | area = cv2.contourArea(cnt) 72 | equivalent_diameter = np.sqrt(4*area/np.pi) 73 | return equivalent_diameter 74 | 75 | def get_area(self, cnt): 76 | area = cv2.contourArea(cnt) 77 | return area 78 | 79 | def get_orientation(self, cnt): 80 | (x, y), (MA, ma), angle = cv2.fitEllipse(cnt) 81 | orientation = ((x, y), (MA, ma), angle) 82 | return orientation 83 | 84 | def get_mask(self, img_gray, cnt): 85 | mask = np.zeros(img_gray.shape, np.uint8) 86 | cv2.drawContours(mask, [cnt], 0, 255, -1) 87 | return mask 88 | 89 | def get_pixel_points(self, img_gray, mask): 90 | pixel_points = np.transpose(np.nonzero(mask)) 91 | # pixel_points = cv2.findNonZero(mask) 92 | return pixel_points 93 | 94 | def get_min_max_loc(self, img_gray, mask): 95 | min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(img_gray, mask=mask) 96 | min_max_loc = (min_val, max_val, min_loc, max_loc) 97 | return min_max_loc 98 | 99 | def get_mean_val(self, img, mask): 100 | mean_val = cv2.mean(img, mask=mask) 101 | return mean_val 102 | 103 | def get_extream_points(self, cnt): 104 | leftmost = tuple(cnt[cnt[:, :, 0].argmin()][0]) 105 | rightmost = tuple(cnt[cnt[:, :, 0].argmax()][0]) 106 | topmost = tuple(cnt[cnt[:, :, 1].argmin()][0]) 107 | bottommost = tuple(cnt[cnt[:, :, 1].argmax()][0]) 108 | extreme_points = { 109 | "left": leftmost, 110 | "right": rightmost, 111 | "top": topmost, 112 | "bottom": bottommost 113 | } 114 | return extreme_points 115 | 116 | def show_image(self, img): 117 | cv2.imshow("img", img) 118 | cv2.waitKey() 119 | cv2.destroyAllWindows() 120 | 121 | #%% 122 | # Inline code 123 | if __name__ == '__main__': 124 | a = Contour("blue_thunder.png") 125 | print(a.file_name) 126 | print(len(a.coordinates)) 127 | print(a.aspect_ratio) 128 | print(a.extent) 129 | print(a.solidity) 130 | print(a.equivalent_diameter) 131 | print(a.area) 132 | print(a.orientation) 133 | print(len(a.pixel_points), " ", a.pixel_points[0]) 134 | print(a.min_max_loc) 135 | print(a.mean_val) 136 | print(a.extreme_points) 137 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/Contour.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/Contour.pyc -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/README.md: -------------------------------------------------------------------------------- 1 | # Contour Properties 2 | 3 | See [OpenCV-Python Tutorials - Contour Properties](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html#contour-properties) for the original tutorials. 4 | 5 | # The Contour class 6 | 7 | Demonstration codes: `Contour.py`. 8 | 9 | As I've noticed there are lots of properties to explore in this chapter, for ease of experimenting, I have created `Contour.py` which essentially contain the `Contour` class. It contains all the methods needed to enable us to easily create a Contour object and obtain the following properties: 10 | 11 | - Aspect Ratio 12 | - Extent 13 | - Solidity 14 | - Equivalent Diameter 15 | - Orientation 16 | - Mask and Pixel Points 17 | - Max-Min values and Locations 18 | - Mean Color / Intensity 19 | - Extreme Points 20 | 21 | To use the class, simply do this (make sure the current directory is set to where the codes are stored): 22 | 23 | ``` 24 | In [1]: from Contour import Contour 25 | 26 | In [2]: a = Contour("blue1.png") 27 | 28 | In [3]: print a.extreme_points 29 | {'top': (145, 57), 'right': (250, 159), 'bottom': (144, 243), 'left': (56, 142)} 30 | 31 | In [4]: dir(a) 32 | Out[4]: 33 | ['__class__', 34 | '__delattr__', 35 | '__dict__', 36 | '__doc__', 37 | '__format__', 38 | '__getattribute__', 39 | '__hash__', 40 | '__init__', 41 | '__module__', 42 | '__new__', 43 | '__reduce__', 44 | '__reduce_ex__', 45 | '__repr__', 46 | '__setattr__', 47 | '__sizeof__', 48 | '__str__', 49 | '__subclasshook__', 50 | '__weakref__', 51 | 'area', 52 | 'aspect_ratio', 53 | 'coordinates', 54 | 'equivalent_diameter', 55 | 'extent', 56 | 'extreme_points', 57 | 'file_name', 58 | 'get_area', 59 | 'get_aspect_ratio', 60 | 'get_coordinates', 61 | 'get_equivalent_diameter', 62 | 'get_extent', 63 | 'get_extream_points', 64 | 'get_img', 65 | 'get_img_gray', 66 | 'get_img_thresh', 67 | 'get_mask', 68 | 'get_mean_val', 69 | 'get_min_max_loc', 70 | 'get_orientation', 71 | 'get_pixel_points', 72 | 'get_solidity', 73 | 'img', 74 | 'img_gray', 75 | 'img_thresh', 76 | 'mask', 77 | 'mean_val', 78 | 'min_max_loc', 79 | 'orientation', 80 | 'pixel_points', 81 | 'show_image', 82 | 'solidity'] 83 | ``` 84 | 85 | # Plot Extreme Points 86 | 87 | Demonstration codes: `plot_extreme_points.py` (that uses the `Contour` class from `Contour.py`). 88 | 89 | To illustrate plotting the extreme points (leftmost, rightmost, topmost, bottommost) to a given image, I've created `plot_extreme_points.py` that essentially import the `Contour` class (from `Contour.py`), followed by doing the plotting. (Change the file names for experimenting purposes). 90 | 91 | Some screenshots: 92 | 93 | ![extreme_blue0.png](./screenshots/extreme_blue0.png) 94 | 95 | ![extreme_blue1.png](./screenshots/extreme_blue1.png) 96 | 97 | ![extreme_blue2.png](./screenshots/extreme_blue2.png) 98 | 99 | ![extreme_blue3.png](./screenshots/extreme_blue3.png) 100 | 101 | ![extreme_blue4.png](./screenshots/extreme_blue4.png) 102 | 103 | ![extreme_blue5.png](./screenshots/extreme_blue5.png) 104 | 105 | ![extreme_blue6.png](./screenshots/extreme_blue6.png) 106 | 107 | ![extreme_blue7.png](./screenshots/extreme_blue7.png) 108 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue0.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/blue_thunder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/blue_thunder.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/demo_contour_properties.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 18 09:34:32 2015 4 | Illustrate computation of various contour properties. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | 11 | #%% 12 | def get_a_contour(an_image_file): 13 | img = cv2.imread(an_image_file) 14 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 15 | ret, img_thresh = cv2.threshold(img_gray, 50, 255, cv2.THRESH_BINARY) 16 | image, contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 17 | cnt = contours[0] 18 | return cnt 19 | 20 | #%% 21 | # Aspect Ratio 22 | def get_aspect_ratio(a_contour): 23 | x,y,w,h = cv2.boundingRect(a_contour) 24 | aspect_ratio = float(w)/h 25 | return aspect_ratio 26 | 27 | #%% 28 | # Area 29 | def get_area(a_contour): 30 | area = cv2.contourArea(a_contour) 31 | x, y, w, h = cv2.boundingRect(a_contour) 32 | rect_area = w*h 33 | extent = float(area) / rect_area 34 | return extent 35 | 36 | # Solidity 37 | def get_solidity(a_contour): 38 | area = cv2.contourArea(a_contour) 39 | hull = cv2.convexHull(a_contour) 40 | hull_area = cv2.contourArea(hull) 41 | solidity = float(area)/hull_area 42 | return solidity 43 | 44 | #%% 45 | # Inline code 46 | cnt = get_a_contour("blue_thunder.png") 47 | print("Aspect Ratio: ", get_aspect_ratio(cnt)) 48 | print("Extent: ", get_area(cnt)) 49 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/plot_extreme_points.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 18 13:41:01 2015 4 | Test playing with the Contour class (inspired by OpenCV-Python - Contour Properties lesson) 5 | @author: Johnny 6 | """ 7 | #%% 8 | from Contour import Contour 9 | #%% 10 | import cv2 11 | import numpy as np 12 | #%% 13 | a = Contour("blue1.png") 14 | #%% 15 | pts = a.extreme_points 16 | #%% 17 | cnt = a.coordinates 18 | #%% 19 | img = a.img 20 | #%% 21 | for pt in pts: 22 | cv2.circle(img, pts[pt], 3, (0, 0, 255), -1) 23 | cv2.putText(img, pt, pts[pt], cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 2, cv2.LINE_AA) 24 | 25 | cv2.imshow("img", img) 26 | cv2.waitKey() 27 | cv2.destroyAllWindows() 28 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue0.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contour_properties/screenshots/extreme_blue7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/README.md: -------------------------------------------------------------------------------- 1 | # Contours: Getting Started 2 | 3 | See [OpenCV-Python - Contours: Getting Started](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html#contours-getting-started) for the original tutorials. 4 | 5 | # Simple Tutorial Demo 6 | 7 | The code `demo_find_countours.py` illustrate the tutorial demo - which "hardcode" a threshold value between 0 and 255. This simple demo uses a threshold value of 170. Running the code gives the following: 8 | 9 | ![demo_output.png](./screenshots/demo_output.png) 10 | 11 | # Bonus Exercise: Adjustable Threshold with Trackbar 12 | 13 | I've taken the liberty to enhance the demo code and incorporate a trackbar. So we get to play around with the threshold (between 0 and 255) and view the result on the fly. 14 | 15 | The code `trackbar_countours.py` illustrate this. 16 | 17 | [![youtube_video_link](./screenshots/youtube_thumb.png)](http://www.youtube.com/watch?v=iq996xGFfhI) 18 | 19 | ![track_1.png](./screenshots/track_1.png) 20 | 21 | ![track_2.png](./screenshots/track_2.png) 22 | 23 | ![track_3.png](./screenshots/track_3.png) 24 | 25 | ![track_4.png](./screenshots/track_4.png) 26 | 27 | ![track_5.png](./screenshots/track_5.png) 28 | 29 | ![track_6.png](./screenshots/track_6.png) 30 | 31 | ![track_7.png](./screenshots/track_7.png) 32 | 33 | ![track_8.png](./screenshots/track_8.png) 34 | 35 | ![track_9.png](./screenshots/track_9.png) 36 | 37 | ![track_10.png](./screenshots/track_10.png) 38 | 39 | ![track_11.png](./screenshots/track_11.png) 40 | 41 | When done, hit the "Esc" key on the keyboard to quit. 42 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/box.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/box_4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/demo_find_countours.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jun 07 17:48:34 2015 4 | 5 | @author: Johnny 6 | 7 | Illustrate the tutorial contour demo. 8 | """ 9 | 10 | import numpy as np 11 | import cv2 12 | 13 | 14 | img = cv2.imread('tom_cruise.jpg') 15 | img_bak = img.copy() 16 | 17 | imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 18 | ret, thresh = cv2.threshold(imgray, 170, 255, cv2.THRESH_BINARY) 19 | image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 20 | img = cv2.drawContours(img, contours, -1, (0, 255, 0), 1) 21 | cv2.imshow("Countour Mask", image) 22 | cv2.imshow("Countor Plotter", img) 23 | cv2.waitKey() 24 | k = cv2.waitKey(0) & 0xFF 25 | cv2.destroyAllWindows() 26 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/demo_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/demo_output.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_10.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_11.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_8.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/track_9.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/youtube_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/screenshots/youtube_thumb.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/tom_cruise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_getting_started/tom_cruise.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_getting_started/trackbar_countours.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jun 07 17:48:34 2015 4 | 5 | @author: Johnny 6 | 7 | An enhanced version of the original simple tutorial contour demo - added 8 | trackbar to vary threshold - so we get to see contour lines at various 9 | grayscale (between 0 and 255). 10 | """ 11 | 12 | import numpy as np 13 | import cv2 14 | 15 | 16 | # this function is needed for the createTrackbar step downstream 17 | def nothing(x): 18 | pass 19 | 20 | # read image 21 | img = cv2.imread('tom_cruise.jpg') 22 | imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 23 | 24 | window_name = 'Contour Plotter' 25 | 26 | # Initialize window to show 27 | cv2.namedWindow(window_name) 28 | 29 | # add ON/OFF switch to "contourer" 30 | switch = '0 : OFF \n1 : ON' 31 | cv2.createTrackbar(switch, window_name, 0, 1, nothing) 32 | 33 | # add threshold slidebar to "contourer" 34 | th = 'Threshold' 35 | cv2.createTrackbar(th, window_name, 0, 255, nothing) 36 | 37 | # Infinite loop until we hit the escape key on keyboard 38 | while(1): 39 | 40 | out_image = img.copy() 41 | # get current positions of the trackbars 42 | s = cv2.getTrackbarPos(switch, window_name) 43 | t = cv2.getTrackbarPos(th, window_name) 44 | 45 | # re-generate image based on trackbar values 46 | if s == 0: 47 | """ do nothing """ 48 | else: 49 | """ re-plot contours """ 50 | ret, thresh = cv2.threshold(imgray, t, 255, cv2.THRESH_BINARY) 51 | image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 52 | out_image = cv2.drawContours(out_image, contours, -1, (0, 255, 0), 1, CV_AA) 53 | 54 | cv2.imshow(window_name, out_image) 55 | k = cv2.waitKey(1) & 0xFF 56 | if k == 27: # hit escape to quit 57 | break 58 | 59 | cv2.destroyAllWindows() 60 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/README.md: -------------------------------------------------------------------------------- 1 | # Contours - More Functions 2 | 3 | See [OpenCV-Python - Contours: More Functions](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_more_functions/py_contours_more_functions.html#contours-more-functions) for the original tutorial. 4 | 5 | # Convexity Defects 6 | 7 | Tutorial demo code: `demo_convexity_defect.py`. 8 | 9 | Screenshot Output: 10 | 11 | ![blue3_defects.png](./screenshots/blue3_defects.png). 12 | 13 | I've also created an alternative `visualize_convexity_defect.py` which may be used to loop through a number of sample images and process in a serial mode. 14 | 15 | # Point Polygon Test 16 | 17 | Check whether a point is outside / on-the / inside the contour... 18 | 19 | When a point is outside the contour: 20 | 21 | ``` 22 | In [4]: cv2.pointPolygonTest(cnt,(150,150),True) 23 | Out[4]: 24.748737341529164 24 | ``` 25 | 26 | When a point is on the contour: 27 | 28 | ``` 29 | In [16]: cv2.pointPolygonTest(cnt,(183,133),True) 30 | Out[16]: 0.0 31 | ``` 32 | 33 | When a point is inside the contour: 34 | 35 | ``` 36 | In [5]: cv2.pointPolygonTest(cnt,(50,50),True) 37 | Out[5]: -85.37564055396598 38 | ``` 39 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue0.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue1.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue5.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue6.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue6_rotated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue6_rotated.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/blue7.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/demo_convexity_defect.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 23 13:02:26 2015 4 | Original tutorial demo on convexity defect. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | 12 | img = cv2.imread('blue3.png') 13 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 14 | ret, thresh = cv2.threshold(img_gray, 50, 255, 0) 15 | image, contours, hierarchy = cv2.findContours(thresh, 2, 1) 16 | cnt = contours[0] 17 | 18 | hull = cv2.convexHull(cnt, returnPoints=False) 19 | defects = cv2.convexityDefects(cnt, hull) 20 | 21 | for i in range(defects.shape[0]): 22 | s, e, f, d = defects[i, 0] 23 | start = tuple(cnt[s][0]) 24 | end = tuple(cnt[e][0]) 25 | far = tuple(cnt[f][0]) 26 | cv2.line(img, start, end, [0, 255, 0], 2) 27 | cv2.circle(img, far, 5, [0, 0, 255], -1) 28 | 29 | cv2.imshow('img', img) 30 | cv2.waitKey(0) 31 | cv2.destroyAllWindows() 32 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/demo_match_shapes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Spyder Editor 4 | 5 | This is a temporary script file. 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | img1 = cv2.imread('blue6.png', 0) 12 | img2 = cv2.imread('blue6_rotated.png', 0) 13 | img3 = cv2.imread('blue5.png', 0) 14 | 15 | ret1, thresh1 = cv2.threshold(img1, 50, 255, 0) 16 | ret2, thresh2 = cv2.threshold(img2, 50, 255, 0) 17 | ret3, thresh3 = cv2.threshold(img3, 50, 255, 0) 18 | 19 | image1, contours1, hierarchy1 = cv2.findContours(thresh1, 2, 1) 20 | image2, contours2, hierarchy2 = cv2.findContours(thresh2, 2, 1) 21 | image3, contours3, hierarchy3 = cv2.findContours(thresh3, 2, 1) 22 | 23 | cnt1 = contours1[0] 24 | cnt2 = contours2[0] 25 | cnt3 = contours3[0] 26 | 27 | ret_1_1 = cv2.matchShapes(cnt1, cnt1, 1, 0.0) 28 | ret_1_2 = cv2.matchShapes(cnt1, cnt2, 1, 0.0) 29 | ret_1_3 = cv2.matchShapes(cnt1, cnt3, 1, 0.0) 30 | 31 | 32 | print "Match Shape Hu Moment Values" 33 | print "img1 vs img1: " + str(ret_1_1) 34 | print "img1 vs img2: " + str(ret_1_2) 35 | print "img1 vs img3: " + str(ret_1_3) 36 | -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/screenshots/blue3_defects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/contours_in_opencv/contours_more_functions/screenshots/blue3_defects.png -------------------------------------------------------------------------------- /image_processing_in_opencv/contours_in_opencv/contours_more_functions/visualize_convexity_defect.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 23 12:33:49 2015 4 | Visualize convexity defect. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | def vis_convexity_defect(image_file): 12 | 13 | img = cv2.imread(image_file) 14 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 15 | ret, thresh = cv2.threshold(img_gray, 50, 255, 0) 16 | image, contours, hierarchy = cv2.findContours(thresh, 2, 1) 17 | cnt = contours[0] 18 | 19 | hull = cv2.convexHull(cnt, returnPoints=False) 20 | defects = cv2.convexityDefects(cnt, hull) 21 | 22 | for i in range(defects.shape[0]): 23 | s, e, f, d = defects[i, 0] 24 | start = tuple(cnt[s][0]) 25 | end = tuple(cnt[e][0]) 26 | far = tuple(cnt[f][0]) 27 | cv2.line(img, start, end, [0, 255, 0], 2) 28 | cv2.circle(img, far, 5, [0, 0, 255], -1) 29 | 30 | iname = 'Convexity Defect - ' + image_file 31 | cv2.imshow(iname, img) 32 | cv2.waitKey(0) 33 | cv2.destroyAllWindows() 34 | 35 | # Build a list of image names to test - these files must exist in curret working directory. 36 | image_files = [] 37 | for i in range(8): 38 | image_file = 'blue' + str(i) + '.png' 39 | image_files.append(image_file) 40 | 41 | # Inline code to test run a series of images 42 | for image_file in image_files: 43 | vis_convexity_defect(image_file) 44 | -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/README.md: -------------------------------------------------------------------------------- 1 | # Geometric Tansformations of Images 2 | 3 | See [OpenCV-Python Tutorials - Geometric Tansformations of Images](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_geometric_transformations/py_geometric_transformations.html#geometric-transformations) for the original tutorials. 4 | 5 | # Resize 6 | 7 | Run code `resize_image.py`. 8 | 9 | Before: 10 | 11 | ![resize_before.png](./screenshots/resize_before.png) 12 | 13 | After: 14 | 15 | ![resize_after.png](./screenshots/resize_after.png) 16 | 17 | # Translate 18 | 19 | Run code `translate_image.py`. 20 | 21 | Before: 22 | 23 | ![translate_before.png](./screenshots/translate_before.png) 24 | 25 | After: 26 | 27 | ![translate_after.png](./screenshots/translate_after.png) 28 | 29 | # Rotate 30 | 31 | Run code `rotate_image.py`. 32 | 33 | Before: 34 | 35 | ![rotate_before.png](./screenshots/rotate_before.png) 36 | 37 | After: 38 | 39 | ![rotate_after.png](./screenshots/rotate_after.png) 40 | 41 | # Affine Transform 42 | 43 | Run code `affine_transform_image.py`. 44 | 45 | Before vs after 46 | 47 | ![affine_transform.png](./screenshots/affine_transform.png) 48 | 49 | 50 | # Perspective Transform 51 | 52 | Run code `perspective_transform_image.py`. 53 | 54 | Before vs after 55 | 56 | ![perspective_transform.png](./screenshots/perspective_transform.png) 57 | 58 | # Conclusion 59 | 60 | Use this section for quick memory refresn of the various potential useful image transforms: 61 | 62 | - resize 63 | - translate 64 | - rotate 65 | - affine transform (3 points) 66 | - perspective transform (4 points) 67 | -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/affine_transform_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 15:58:19 2015 4 | Illustrate affine transformation of an image. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | img_bgr = cv2.imread('messi.jpg') 13 | img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB); 14 | 15 | rows,cols,ch = img_rgb.shape 16 | 17 | # Map 3 points (triangle vertices) from space 1 to space 2. 18 | pts1 = np.float32([[50,50],[200,50],[50,200]]) 19 | pts2 = np.float32([[10,100],[200,50],[100,250]]) 20 | 21 | M = cv2.getAffineTransform(pts1,pts2) 22 | 23 | dst_rgb = cv2.warpAffine(img_rgb,M,(cols,rows)) 24 | 25 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Input') 26 | plt.subplot(122),plt.imshow(dst_rgb),plt.title('Output') 27 | plt.show() 28 | -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/messi.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/perspective_transform_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 16:20:05 2015 4 | Illustrate Perspective Transformation of an image. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | #%% 13 | img_bgr = cv2.imread('messi.jpg') 14 | img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB); 15 | rows,cols,ch = img_rgb.shape 16 | print "(x, y) : " + str((cols, rows)) 17 | 18 | #%% 19 | # Map 4 points (quadrangle vertices) from space 1 to space 2 (think JotNot) 20 | pts1 = np.float32([[95, 88],[381, 5],[189, 472],[669, 460]]) 21 | pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]]) 22 | 23 | M = cv2.getPerspectiveTransform(pts1,pts2) 24 | 25 | dst_rgb = cv2.warpPerspective(img_rgb,M,(300,300)) 26 | 27 | #%% 28 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Input') 29 | plt.subplot(122),plt.imshow(dst_rgb),plt.title('Output') 30 | plt.show() -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/resize_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 14:01:10 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | #%% 12 | img = cv2.imread('messi.jpg') 13 | print img is not None 14 | cv2.imshow("img",img) 15 | k = cv2.waitKey(0) & 0xFF 16 | cv2.destroyAllWindows() 17 | #%% 18 | res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC) 19 | cv2.imshow("res",res) 20 | k = cv2.waitKey(0) & 0xFF 21 | cv2.destroyAllWindows() 22 | #%% 23 | #OR 24 | 25 | height, width = img.shape[:2] 26 | res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC) 27 | cv2.imshow("res",res) 28 | k = cv2.waitKey(0) & 0xFF 29 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/rotate_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 15:12:08 2015 4 | Illustrate rotation of an image. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | 10 | #%% 11 | img = cv2.imread('messi.jpg',0) 12 | print img is not None 13 | #%% 14 | cv2.imshow("img",img) 15 | k = cv2.waitKey(0) & 0xFF 16 | cv2.destroyAllWindows() 17 | #%% 18 | rows,cols = img.shape 19 | print (cols, rows) 20 | #%% 21 | # cv2.getRotationMatrix2D((x_center, y_center),degree_rotation_anticlockwise,scale) 22 | # Default center location is top-left of image. 23 | M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1) 24 | M 25 | #%% 26 | dst = cv2.warpAffine(img,M,(cols,rows)) 27 | dst 28 | #%% 29 | cv2.imshow("dst",dst) 30 | k = cv2.waitKey(0) & 0xFF 31 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/affine_transform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/affine_transform.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/perspective_transform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/perspective_transform.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/resize_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/resize_after.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/resize_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/resize_before.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/rotate_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/rotate_after.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/rotate_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/rotate_before.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/translate_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/translate_after.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/screenshots/translate_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/geometric_transformations_of_images/screenshots/translate_before.png -------------------------------------------------------------------------------- /image_processing_in_opencv/geometric_transformations_of_images/translate_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun May 24 15:02:49 2015 4 | Illustrate translation of an image, using cv2.warpAffine. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | #%% 12 | img = cv2.imread('messi.jpg',0) 13 | print img is not None 14 | cv2.imshow('img',img) 15 | cv2.waitKey(0) 16 | cv2.destroyAllWindows() 17 | #%% 18 | rows,cols = img.shape 19 | #%% 20 | M = np.float32([[1,0,100],[0,1,50]]) 21 | dst = cv2.warpAffine(img,M,(cols,rows)) 22 | 23 | #%% 24 | cv2.imshow('dst',dst) 25 | cv2.waitKey(0) 26 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/README.md: -------------------------------------------------------------------------------- 1 | # Image Gradients 2 | 3 | See [OpenCV-Python - Image Gradients](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_gradients/py_gradients.html#gradients) for the original tutorials. 4 | 5 | # Compare depths: 8U vs 64F 6 | 7 | ## Sobel-x - 8U vs 64F 8 | 9 | The full code: `compare_depths_8u_vs_64f_sobel_x.py` 10 | 11 | ```python 12 | import cv2 13 | import numpy as np 14 | from matplotlib import pyplot as plt 15 | 16 | img = cv2.imread('box.png',0) 17 | 18 | # Output dtype = cv2.CV_8U 19 | sobelx8u = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=3) 20 | # Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U 21 | sobelx64f = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) 22 | abs_sobelx64f = np.absolute(sobelx64f) 23 | sobelx64f_8u = np.uint8(abs_sobelx64f) 24 | ``` 25 | 26 | ![compare_depths_8u_vs_64f_sobel_x_box.png](./screenshots/compare_depths_8u_vs_64f_sobel_x_box.png) 27 | 28 | Note: 29 | 30 | - at depth 8U: slope is detected ok when go from black to white (positive slope). When going from white to black, the slope is negative and floored to zero - i.e. no edge is detected in that case. 31 | - at depth 64F, take the absolte figure and convert back to 8U, the above problem goes away. i.e. negative slope is also picked up. 32 | 33 | ## Laplacian - 8U vs 64F 34 | 35 | The full code: `compare_depths_8u_vs_64f_laplacian.py` 36 | 37 | ```python 38 | import cv2 39 | import numpy as np 40 | from matplotlib import pyplot as plt 41 | 42 | img = cv2.imread('box.png',0) 43 | 44 | # Output dtype = cv2.CV_8U 45 | laplacian8u = cv2.Laplacian(img, cv2.CV_8U) 46 | # Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U 47 | laplacian64f = cv2.Laplacian(img, cv2.CV_64F) 48 | abs_laplacian64f = np.absolute(laplacian64f) 49 | laplacian64f_8u = np.uint8(abs_laplacian64f) 50 | ``` 51 | 52 | Notes: 53 | 54 | - looks like the Laplacian method is unaffected by the negative slope issue (as mentioned in the sobel test previously). i.e. be the depth 8U or 64F, all edges are detected ok. 55 | 56 | ![compare_depths_8u_vs_64f_laplacian_box.png](./screenshots/compare_depths_8u_vs_64f_laplacian_box.png) 57 | 58 | # Compare Methods at Depth 8U 59 | 60 | The full code: `compare_methods_at_depth_8u.py` 61 | 62 | ```python 63 | import cv2 64 | from matplotlib import pyplot as plt 65 | 66 | img = cv2.imread('davemark_sudoku.jpg', 0) 67 | 68 | laplacian = cv2.Laplacian(img, cv2.CV_8U) 69 | sobelx = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=3) 70 | sobely = cv2.Sobel(img, cv2.CV_8U, 0, 1, ksize=3) 71 | scharrx = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=-1) 72 | scharry = cv2.Sobel(img, cv2.CV_8U, 0, 1, ksize=-1) 73 | ``` 74 | 75 | ![compare_methods_at_depth_8u_sudoku.png](./screenshots/compare_methods_at_depth_8u_sudoku.png) 76 | 77 | Notes: 78 | 79 | - for the Sobel / Scharr methods, the negative slopes are not picked up (from white to black). Only the slopes from black to white are picked up. Reason for this is explained previously under the section "Sobel-x - 8U vs 64F" (which also apply to Sobel in the y direction as well). For instance, the number "1" in the sudoku appears only as a line (the right edge that goes from black to white). 80 | - Laplacian method seems ok. e.g. the letter 1 is displayed ok. 81 | - The Scharr method seems to produce slightly brighter image than Sobel method, for some unknown reasons. 82 | 83 | # Compare Methods at Depth 64F 84 | 85 | The full code: `compare_methods_at_depth_64f.py` 86 | 87 | ```python 88 | import cv2 89 | import numpy as np 90 | from matplotlib import pyplot as plt 91 | 92 | img = cv2.imread('davemark_sudoku.jpg',0) 93 | 94 | # Detect slopes in x and y directions with cv2.Laplacian with depth cv2.CV_64F and convert back to cv2.CV_8U 95 | laplacian64f = cv2.Laplacian(img,cv2.CV_64F) 96 | abs_laplacian64f = np.absolute(laplacian64f) 97 | laplacian64f_8u = np.uint8(abs_laplacian64f) 98 | 99 | # Detect slopes in x direction with cv2.Sobel with depth cv2.CV_64F and convert back to cv2.CV_8U 100 | sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) 101 | abs_sobelx64f = np.absolute(sobelx64f) 102 | sobelx64f_8u = np.uint8(abs_sobelx64f) 103 | 104 | # Detect slopes in y direction with cv2.Sobel with depth cv2.CV_64F and convert back to cv2.CV_8U 105 | sobely64f = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) 106 | abs_sobely64f = np.absolute(sobely64f) 107 | sobely64f_8u = np.uint8(abs_sobely64f) 108 | 109 | # Detect slopes in x direction with cv2.Scharr with depth cv2.CV_64F and convert back to cv2.CV_8U 110 | scharrx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=-1) 111 | abs_scharrx64f = np.absolute(scharrx64f) 112 | scharrlx64f_8u = np.uint8(abs_scharrx64f) 113 | 114 | # Detect slopes in y direction with cv2.Scharr with depth cv2.CV_64F and convert back to cv2.CV_8U 115 | scharry64f = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=-1) 116 | abs_scharry64f = np.absolute(scharry64f) 117 | scharry64f_8u = np.uint8(abs_scharry64f) 118 | ``` 119 | 120 | ![compare_methods_at_depth_64f_sudoku.png](./screenshots/compare_methods_at_depth_64f_sudoku.png) 121 | 122 | Notes: 123 | 124 | - Both positive and negative slopes are now picked up. For instance, the number "1" in the sudoku appears as a line (the left edge that goes from white to black - the negative slope) plus another line (the right edge that goes from black to white - the positive slope). 125 | - Laplacian method seems ok. e.g. the letter 1 is displayed ok. 126 | - The Scharr method seems to produce very blurred output comparing with the Sobel method, for some unknown reasons. 127 | 128 | # Conclusion 129 | 130 | The example we have used correspond to 3-by-3 kernels. For Apple-to-apple comparison purposes. 131 | 132 | When choosing depths, tt might be wise to use depth 64F, take absolute value, and convert back to 8U (rather than just taking depth 8U straight away). This will increase the chance that all edges are captured (regardless of positive or negative slopes). This might not matter as much for the laplacian method. 133 | 134 | - Sobel x detects slope is the x direction. 135 | - Sobel y detects slope is the y direction. 136 | - Laplacian detects slope in both x and y directions. 137 | - the Scharr method is essentially a more accurate version of Sobel, with ksize of -1 (i.e. 3-by-3 kernel) 138 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/box.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/box_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/box_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/box_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/box_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/box_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/box_4.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/compare_depths_8u_vs_64f_laplacian.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 28 14:07:44 2015 4 | Illustrate these regarding the cv2.Sobel method: 5 | 6 | - using depth cv2.CV_8U will pick on only positive slope (black to white), 7 | but not negative slope (white to black). 8 | example: sobelx8u 9 | 10 | - using higher order depth cv2.CV_64F, take absolte value, then convert back 11 | to cv2.CV_8U, will pick up both positive and negative slopes. 12 | example: sobelx64f_8u 13 | 14 | @author: Johnny 15 | """ 16 | 17 | import cv2 18 | import numpy as np 19 | from matplotlib import pyplot as plt 20 | 21 | img = cv2.imread('box.png',0) 22 | 23 | # Output dtype = cv2.CV_8U 24 | laplacian8u = cv2.Laplacian(img, cv2.CV_8U) 25 | # Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U 26 | laplacian64f = cv2.Laplacian(img, cv2.CV_64F) 27 | abs_laplacian64f = np.absolute(laplacian64f) 28 | laplacian64f_8u = np.uint8(abs_laplacian64f) 29 | 30 | plt.subplot(1, 3, 1), plt.imshow(img, cmap='gray') 31 | plt.title('Original\n(img)'), plt.xticks([]), plt.yticks([]) 32 | plt.subplot(1, 3, 2), plt.imshow(laplacian8u, cmap='gray') 33 | plt.title('Laplacian\nDepth: cv2.CV_8U\n(laplacian8u)'), plt.xticks([]), plt.yticks([]) 34 | plt.subplot(1, 3, 3), plt.imshow(laplacian64f_8u, cmap='gray') 35 | plt.title('Laplacian\nDepth: abs(cv2.CV_64F)\n(laplacian64f_8u)'), plt.xticks([]), plt.yticks([]) 36 | plt.show() 37 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/compare_depths_8u_vs_64f_sobel_x.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 28 14:07:44 2015 4 | Illustrate these regarding the cv2.Sobel method: 5 | 6 | - using depth cv2.CV_8U will pick on only positive slope (black to white), 7 | but not negative slope (white to black). 8 | example: sobelx8u 9 | 10 | - using higher order depth cv2.CV_64F, take absolte value, then convert back 11 | to cv2.CV_8U, will pick up both positive and negative slopes. 12 | example: sobelx64f_8u 13 | 14 | @author: Johnny 15 | """ 16 | 17 | import cv2 18 | import numpy as np 19 | from matplotlib import pyplot as plt 20 | 21 | img = cv2.imread('box.png',0) 22 | 23 | # Output dtype = cv2.CV_8U 24 | sobelx8u = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=3) 25 | # Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U 26 | sobelx64f = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) 27 | abs_sobelx64f = np.absolute(sobelx64f) 28 | sobelx64f_8u = np.uint8(abs_sobelx64f) 29 | 30 | plt.subplot(1, 3, 1), plt.imshow(img, cmap='gray') 31 | plt.title('Original\n(img)'), plt.xticks([]), plt.yticks([]) 32 | plt.subplot(1, 3, 2), plt.imshow(sobelx8u, cmap='gray') 33 | plt.title('Sobel-x\nDepth: cv2.CV_8U\n(sobelx8u)'), plt.xticks([]), plt.yticks([]) 34 | plt.subplot(1, 3, 3), plt.imshow(sobelx64f_8u, cmap='gray') 35 | plt.title('Sobel-x\nDepth: abs(cv2.CV_64F)\n(sobelx64f_8u)'), plt.xticks([]), plt.yticks([]) 36 | plt.show() 37 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/compare_methods_at_depth_64f.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 28 13:55:09 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | img = cv2.imread('davemark_sudoku.jpg',0) 13 | 14 | # Detect slopes in x and y directions with cv2.Laplacian with depth cv2.CV_64F and convert back to cv2.CV_8U 15 | laplacian64f = cv2.Laplacian(img,cv2.CV_64F) 16 | abs_laplacian64f = np.absolute(laplacian64f) 17 | laplacian64f_8u = np.uint8(abs_laplacian64f) 18 | 19 | # Detect slopes in x direction with cv2.Sobel with depth cv2.CV_64F and convert back to cv2.CV_8U 20 | sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) 21 | abs_sobelx64f = np.absolute(sobelx64f) 22 | sobelx64f_8u = np.uint8(abs_sobelx64f) 23 | 24 | # Detect slopes in y direction with cv2.Sobel with depth cv2.CV_64F and convert back to cv2.CV_8U 25 | sobely64f = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) 26 | abs_sobely64f = np.absolute(sobely64f) 27 | sobely64f_8u = np.uint8(abs_sobely64f) 28 | 29 | # Detect slopes in x direction with cv2.Scharr with depth cv2.CV_64F and convert back to cv2.CV_8U 30 | scharrx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=-1) 31 | abs_scharrx64f = np.absolute(scharrx64f) 32 | scharrlx64f_8u = np.uint8(abs_scharrx64f) 33 | 34 | # Detect slopes in y direction with cv2.Scharr with depth cv2.CV_64F and convert back to cv2.CV_8U 35 | scharry64f = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=-1) 36 | abs_scharry64f = np.absolute(scharry64f) 37 | scharry64f_8u = np.uint8(abs_scharry64f) 38 | 39 | titles = [ 40 | 'Original\n(img)', 'Sobel-x\n(sobelx64f_8u)', 'Scharr-x\n(scharrx64f_8u)', 41 | 'Laplacian\n(laplacian64f_8u)', 'Sobel-y\n(sobely64f_8u)', 'Scharr-y\n(scharry64f_8u)',] 42 | 43 | 44 | images = [img, sobelx64f_8u, scharrlx64f_8u, 45 | laplacian64f_8u, sobely64f_8u, scharry64f_8u] 46 | 47 | for i in xrange(6): 48 | plt.subplot(2, 3, i+1), plt.imshow(images[i], 'gray') 49 | plt.title(titles[i]) 50 | plt.xticks([]), plt.yticks([]) 51 | 52 | plt.show() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/compare_methods_at_depth_8u.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 28 13:55:09 2015 4 | 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | from matplotlib import pyplot as plt 10 | 11 | img = cv2.imread('davemark_sudoku.jpg', 0) 12 | 13 | laplacian = cv2.Laplacian(img, cv2.CV_8U) 14 | sobelx = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=3) 15 | sobely = cv2.Sobel(img, cv2.CV_8U, 0, 1, ksize=3) 16 | scharrx = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=-1) 17 | scharry = cv2.Sobel(img, cv2.CV_8U, 0, 1, ksize=-1) 18 | 19 | titles = [ 20 | 'Original\n(img)', 'Sobel-x\n(sobelx)', 'Scharr-x\n(scharrx)', 21 | 'Laplacian\n(laplacian)', 'Sobel-y\n(sobely)', 'Scharr-y\n(scharry)'] 22 | 23 | images = [img, sobelx, scharrx, 24 | laplacian, sobely, scharry] 25 | 26 | for i in xrange(6): 27 | plt.subplot(2, 3, i+1), plt.imshow(images[i], 'gray') 28 | plt.title(titles[i]) 29 | plt.xticks([]), plt.yticks([]) 30 | 31 | plt.show() 32 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/davemark_sudoku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/davemark_sudoku.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/screenshots/compare_depths_8u_vs_64f_laplacian_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/screenshots/compare_depths_8u_vs_64f_laplacian_box.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/screenshots/compare_depths_8u_vs_64f_sobel_x_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/screenshots/compare_depths_8u_vs_64f_sobel_x_box.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/screenshots/compare_methods_at_depth_64f_sudoku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/screenshots/compare_methods_at_depth_64f_sudoku.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_gradients/screenshots/compare_methods_at_depth_8u_sudoku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_gradients/screenshots/compare_methods_at_depth_8u_sudoku.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/README.md: -------------------------------------------------------------------------------- 1 | # Image Pyramids 2 | 3 | See [OpenCV-Python Tutorials - Image Pyramids](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_pyramids/py_pyramids.html#pyramids) for the original tutorials. 4 | 5 | Image Pyramid as a picture: 6 | 7 | ![image_pyramid.png](./screenshots/image_pyramid.png) 8 | 9 | # cv2.pyrDown and cv2.pyrUp 10 | 11 | See the [official OpenCV documentation on cv2.pyrDown and cv2.pyrUp](http://docs.opencv.org/modules/imgproc/doc/filtering.html) for more info. 12 | 13 | - `cv2.pyrDown`: Blurs an image and downsamples (half the size) it. 14 | - `cv2.pyrUp`: Upsamples (double the size) an image and then blurs it. 15 | 16 | ## Demo with Grayscale Image 17 | 18 | This demo code `pyramid.py` illustrate the use of `cv2.pyrDown` and `cv2.pyrUp`. 19 | 20 | Illustration: 21 | 22 | 1. Starting with an original image 23 | 2. pyrDown 1st time to blur and downsample it. 24 | 3. pyrDown 2nd time to blur and downsample it. 25 | 4. pyrDown 3rd time to blur and downsample it. 26 | 5. pyrUp 1st time to upsample an image and then blur it. 27 | 6. pyrUp 2st time to upsample an image and then blur it. 28 | 7. pyrUp 3st time to upsample an image and then blur it. 29 | 8. The resulting image become the same size as the original, but blurred (due to all the lost of pixels during the blurring processes). 30 | 31 | Output: 32 | 33 | ![image_pyramid_down3_up3.png](./screenshots/image_pyramid_down3_up3.png) 34 | 35 | ## Demo with Edged Image 36 | 37 | This demo code `pyramid_edged_image.py` essentially is the same as the above `pyramid.py`. I merely replace the original grayscale image with an edged image, created using the Cunny Edge Detector, as mentioned in [the OpenCV-Python Tutorials - Cunny Edge Detection](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_canny/py_canny.html#canny) chapter. 38 | 39 | i.e. this one line is inserted to the code: 40 | 41 | ```.python 42 | edges = cv2.Canny(img, 100, 200) 43 | ``` 44 | 45 | (and we replace the original image with this one) 46 | 47 | This is the output: 48 | 49 | ![image_pyramid_down3_up3_edged_image.png](./screenshots/image_pyramid_down3_up3_edged_image.png) 50 | 51 | 52 | # Pyramid Blending 53 | 54 | ## The code 55 | 56 | The code `pyramid_image_blending.py` illustrate blending two images (left and right) together, using a combination of Gussian and Laplacian Pyramids. 57 | 58 | ## How does the blending process work? 59 | 60 | I've compiled the explanation of the blending process by compiling the materials taken from [this page by University of Wisconsin-Madison](http://pages.cs.wisc.edu/~csverma/CS766_09/ImageMosaic/imagemosaic.html) and the [OpenCV-Python Tutorials - Image Pyramids). All credits go to these guys. 61 | 62 | --- 63 | 64 | Laplacian pyramid is an algorithm using Gaussian to blend the image while keeping the significant feature in the mean time. It downsizes the image into different levels (sizes) with Gaussian. Later it expands the Gaussian in to the lower lever and subtracts from the image in that lever to acquire the Laplacian image. 65 | 66 | ![pyramid_steps_1.jpg](./screenshots/pyramid_steps_1.jpg) 67 | 68 | After generating Laplacian pyramids for the overlap images A and B, we combine the two images in different Laplacian levels by combining partial images from each of them. 69 | 70 | ![pyramid_steps_2.jpg](./screenshots/pyramid_steps_2.jpg) 71 | 72 | ![pyramid_steps_3.jpg](./screenshots/pyramid_steps_3.jpg) 73 | 74 | Afterward, we expand the LS from the top level (N) to the next level (N-1) and add it to the original Laplacian image in the corresponding layer to generate the latest Laplacian image in the corresponding layer. We repeat this step until reaching ground level and the final result will be the blending image 75 | 76 | ## The Output 77 | 78 | The output produced by the code (with N set to 6): 79 | 80 | ![pyramid_blending.png](./screenshots/pyramid_blending.png) 81 | 82 | --- 83 | 84 | It has taken me a while to understand this. My suggestion is to have the code and the above diagrams in front of you side-by-side. Follow it through and eventually things shall become clear. 85 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/apple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/apple.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/messi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/messi.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/orange.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/orange.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/pyramid.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 04 14:12:15 2015 4 | Illusrate the use of cv2.pyrDown to lower resolution and 5 | cv2.pyrUp to increase resolution 6 | @author: Johnny 7 | """ 8 | 9 | import cv2 10 | 11 | 12 | img = cv2.imread('messi.jpg', 0) 13 | d1u0 = cv2.pyrDown(img) 14 | d2u0 = cv2.pyrDown(d1u0) 15 | d3u0 = cv2.pyrDown(d2u0) 16 | d3u1 = cv2.pyrUp(d3u0) 17 | d3u2 = cv2.pyrUp(d3u1) 18 | d3u3 = cv2.pyrUp(d3u2) 19 | 20 | # display images 21 | cv2.imshow('img', img) 22 | cv2.imshow('d1u0', d1u0) 23 | cv2.imshow('d2u0', d2u0) 24 | cv2.imshow('d3u0', d3u0) 25 | cv2.imshow('d3u1', d3u1) 26 | cv2.imshow('d3p2', d3u2) 27 | cv2.imshow('d3u3', d3u3) 28 | 29 | # hit any keys to close the displayed images 30 | k = cv2.waitKey(0) & 0xFF 31 | cv2.destroyAllWindows() 32 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/pyramid_edged_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 04 14:12:15 2015 4 | Illusrate the use of cv2.pyrDown to lower resolution and 5 | cv2.pyrUp to increase resolution - against edged images. 6 | @author: Johnny 7 | """ 8 | 9 | import cv2 10 | 11 | 12 | img = cv2.imread('messi.jpg', 0) 13 | edges = cv2.Canny(img, 100, 200) 14 | d1u0 = cv2.pyrDown(edges) 15 | d2u0 = cv2.pyrDown(d1u0) 16 | d3u0 = cv2.pyrDown(d2u0) 17 | d3u1 = cv2.pyrUp(d3u0) 18 | d3u2 = cv2.pyrUp(d3u1) 19 | d3u3 = cv2.pyrUp(d3u2) 20 | 21 | # display images 22 | cv2.imshow('edges', edges) 23 | cv2.imshow('d1u0', d1u0) 24 | cv2.imshow('d2u0', d2u0) 25 | cv2.imshow('d3u0', d3u0) 26 | cv2.imshow('d3u1', d3u1) 27 | cv2.imshow('d3p2', d3u2) 28 | cv2.imshow('d3u3', d3u3) 29 | 30 | # hit any keys to close the displayed images 31 | k = cv2.waitKey(0) & 0xFF 32 | cv2.destroyAllWindows() 33 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/pyramid_image_blending.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 04 19:32:01 2015 4 | 5 | @author: Johnny 6 | 7 | This is taken from the OpenCV-Python Tutorials. 8 | Illustrate Image blend with Laplacian Pyrimaid Image Blending. 9 | 10 | References: 11 | 12 | https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_pyramids/py_pyramids.html#pyramids 13 | http://pages.cs.wisc.edu/~csverma/CS766_09/ImageMosaic/imagemosaic.html 14 | 15 | """ 16 | #%% 17 | import cv2 18 | import numpy as np 19 | 20 | #%% set pyramid level 21 | n = 6 22 | 23 | #%% 24 | A = cv2.imread('apple.jpg') 25 | B = cv2.imread('orange.jpg') 26 | 27 | #%% 28 | # generate Gaussian pyramid for A - from base to tip. 29 | G = A.copy() 30 | gpA = [G] 31 | for i in xrange(n): 32 | G = cv2.pyrDown(G) 33 | gpA.append(G) 34 | 35 | 36 | #%% 37 | 38 | # generate Gaussian pyramid for B - from base to tip. 39 | G = B.copy() 40 | gpB = [G] 41 | for i in xrange(n): 42 | G = cv2.pyrDown(G) 43 | gpB.append(G) 44 | 45 | #%% 46 | # generate Laplacian Pyramid for A - from tip to base 47 | lpA = [gpA[n]] 48 | for i in xrange(n, 0, -1): 49 | GE = cv2.pyrUp(gpA[i]) 50 | L = cv2.subtract(gpA[i-1], GE) 51 | lpA.append(L) 52 | #%% 53 | # generate Laplacian Pyramid for B - from tip to base 54 | lpB = [gpB[n]] 55 | for i in xrange(n, 0, -1): 56 | GE = cv2.pyrUp(gpB[i]) 57 | L = cv2.subtract(gpB[i-1], GE) 58 | lpB.append(L) 59 | 60 | #%% 61 | # Now add left and right halves of images in each level - from tip to base. 62 | LS = [] 63 | for la, lb in zip(lpA, lpB): 64 | rows, cols, dpt = la.shape 65 | ls = np.hstack((la[:, 0:cols/2], lb[:, cols/2:])) 66 | LS.append(ls) 67 | 68 | #%% 69 | # now reconstruct (Laplacian Pyramid Blending) - tip to base. 70 | ls_ = LS[0] 71 | for i in xrange(1, n+1): 72 | ls_ = cv2.pyrUp(ls_) 73 | ls_ = cv2.add(ls_, LS[i]) 74 | 75 | #%% 76 | # image with direct connecting each half 77 | real = np.hstack((A[:, :cols/2], B[:, cols/2:])) 78 | 79 | #%% 80 | # Display images. Hit any keys to close the displayed images 81 | cv2.imshow('Left Image', A) 82 | cv2.imshow('Right Image', B) 83 | cv2.imshow('Pyramid Blending', ls_) 84 | cv2.imshow('Direct Connection', real) 85 | k = cv2.waitKey(0) & 0xFF 86 | cv2.destroyAllWindows() 87 | -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/image_pyramid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/image_pyramid.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/image_pyramid_down3_up3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/image_pyramid_down3_up3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/image_pyramid_down3_up3_edged_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/image_pyramid_down3_up3_edged_image.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/pyramid_blending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/pyramid_blending.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_1.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_2.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_pyramids/screenshots/pyramid_steps_3.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/README.md: -------------------------------------------------------------------------------- 1 | # Image Thresholding 2 | 3 | See [OpenCV-Python Tutorials - Image Thresholding](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#thresholding) for the original tutorials. 4 | 5 | # Create a Simple Gradient Image 6 | 7 | It turns out that the sample tutorial requires us to have a gradient image that looks like this: 8 | 9 | ![gradient.png](./screenshots/gradient.png) 10 | 11 | So I have created this code `create_gradient_png.py` that will automaticaly create this image (enter "s" whilst the image is displayed will save it as `gradient.png` in the same directory - which I have already done.) 12 | 13 | # Sample Thresholding 14 | 15 | Code: `demo_image_thresholding.py` 16 | 17 | Screenshots: 18 | 19 | ![gradient_image_thresholding.png](./screenshots/gradient_image_thresholding.png) 20 | 21 | # Adaptive Thresholding 22 | 23 | Code: `sudoku_image_adaptive_thresholding.png` 24 | 25 | Screenshots: 26 | 27 | ![sudoku_image_adaptive_thresholding.png](./screenshots/sudoku_image_adaptive_thresholding.png) 28 | 29 | Note: I obtain the input image `davemark_sudoku.jpg` from [this blog post by Dave Mark](http://www.davemark.com/?p=1164) - via a simple Google image search. 30 | 31 | # Otsu Binarization 32 | 33 | Code: `demo_otsu_binarization.py` 34 | 35 | Screenshots: 36 | 37 | ![twitter_image_otsu_binarization.png](./screenshots/twitter_image_otsu_binarization.png) 38 | 39 | Note: I obtain the input image `davemark_sudoku.jpg` from [this psmag.com blog post](http://www.psmag.com/nature-and-technology/whispering-town-square-can-twitter-provide-escape-noise-90493) - via a simple Google image search. 40 | 41 | # How Otsu Binarization Works 42 | 43 | Code: `demo_find_otsu_threshold_value.py` 44 | 45 | The code shows how the OpenCV Otsu Binarization works by comparing the theortical value with the actual OpenCV Otsu Binarization computed value. 46 | 47 | # Conclusion 48 | 49 | Here we have successfully executed some demos on image thresholdings. -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/create_gradient_png.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 13:56:33 2015 4 | My attempt to create a sample grayscale sample image for the image 5 | thresholding exercises. 6 | @author: Johnny 7 | """ 8 | 9 | #%% 10 | import numpy as np 11 | import cv2 12 | #%% 13 | # Create a list containing the 256 (grascale) scalar 14 | line = [] 15 | for i in xrange(256): 16 | line.append(i) 17 | #%% 18 | # Repeat this line for many rows. So we have a n-by-n list 19 | line_page = [] 20 | for i in xrange(len(line)): 21 | line_page.append(line) 22 | #%% 23 | # Convert the n-by-n list to a NumMpy array 24 | img = np.asarray(line_page, dtype=np.uint8) 25 | print img 26 | print img.shape 27 | print img.dtype 28 | #%% 29 | # Show image. type "s" to save image. 30 | cv2.imshow("img_grayscale", img) 31 | k = cv2.waitKey(0) & 0xFF 32 | if k == ord('s'): # wait for 's' key to save and exit 33 | cv2.imwrite("gradient.png",img) 34 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/davemark_sudoku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/davemark_sudoku.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/demo_find_otsu_threshold_value.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 18:00:14 2015 4 | Illustrate how to find Otsu's Binarization. 5 | @author: Johnny 6 | """ 7 | 8 | img = cv2.imread('noisy_twitter_colored.jpg',0) 9 | blur = cv2.GaussianBlur(img,(5,5),0) 10 | 11 | # find normalized_histogram, and its cumulative distribution function 12 | hist = cv2.calcHist([blur],[0],None,[256],[0,256]) 13 | hist_norm = hist.ravel()/hist.max() 14 | Q = hist_norm.cumsum() 15 | 16 | bins = np.arange(256) 17 | 18 | fn_min = np.inf 19 | thresh = -1 20 | 21 | for i in xrange(1,256): 22 | p1,p2 = np.hsplit(hist_norm,[i]) # probabilities 23 | q1,q2 = Q[i],Q[255]-Q[i] # cum sum of classes 24 | b1,b2 = np.hsplit(bins,[i]) # weights 25 | 26 | # finding means and variances 27 | m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2 28 | v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2 29 | 30 | # calculates the minimization function 31 | fn = v1*q1 + v2*q2 32 | if fn < fn_min: 33 | fn_min = fn 34 | thresh = i 35 | 36 | # find otsu's threshold value with OpenCV function 37 | ret, otsu = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 38 | print thresh,ret -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/demo_image_adaptive_thresholding.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 14:31:58 2015 4 | Illustrate Adaptive thresholding. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | img = cv2.imread('davemark_sudoku.jpg',0) 13 | img = cv2.medianBlur(img,5) 14 | 15 | ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) 16 | th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\ 17 | cv2.THRESH_BINARY,11,2) 18 | th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\ 19 | cv2.THRESH_BINARY,11,2) 20 | 21 | titles = ['Original Image', 'Global Thresholding (v = 127)', 22 | 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding'] 23 | images = [img, th1, th2, th3] 24 | 25 | for i in xrange(4): 26 | plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') 27 | plt.title(titles[i]) 28 | plt.xticks([]),plt.yticks([]) 29 | plt.show() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/demo_image_thresholding.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 14:22:37 2015 4 | Illustrate the 5 image thresholding options. 5 | @author: Johnny 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | 12 | # Note: the input is a grayscale image 13 | img = cv2.imread('gradient.png',0) 14 | ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) 15 | ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) 16 | ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) 17 | ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) 18 | ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) 19 | 20 | titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] 21 | images = [img, thresh1, thresh2, thresh3, thresh4, thresh5] 22 | 23 | for i in xrange(6): 24 | plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') 25 | plt.title(titles[i]) 26 | plt.xticks([]),plt.yticks([]) 27 | 28 | plt.show() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/demo_otsu_binarization.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 18:00:14 2015 4 | Illustrate Otsu's Binarization. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | # Load image as grayscale 13 | img = cv2.imread('noisy_twitter_colored.jpg',0) 14 | print img is not None 15 | #%% 16 | # global thresholding 17 | ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) 18 | 19 | # Otsu's thresholding 20 | ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 21 | 22 | # Otsu's thresholding after Gaussian filtering 23 | blur = cv2.GaussianBlur(img,(5,5),0) 24 | ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 25 | 26 | # plot all the images and their histograms 27 | images = [img, 0, th1, 28 | img, 0, th2, 29 | blur, 0, th3] 30 | titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)', 31 | 'Original Noisy Image','Histogram',"Otsu's Thresholding", 32 | 'Gaussian filtered Image','Histogram',"Otsu's Thresholding"] 33 | 34 | for i in xrange(3): 35 | plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray') 36 | plt.title(titles[i*3]), plt.xticks([]), plt.yticks([]) 37 | plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256) 38 | plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([]) 39 | plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray') 40 | plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([]) 41 | plt.show() -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/gradient.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/noisy_twitter_colored.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/noisy_twitter_colored.jpg -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/screenshots/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/screenshots/gradient.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/screenshots/gradient_image_thresholding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/screenshots/gradient_image_thresholding.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/screenshots/sudoku_image_adaptive_thresholding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/screenshots/sudoku_image_adaptive_thresholding.png -------------------------------------------------------------------------------- /image_processing_in_opencv/image_thresholding/screenshots/twitter_image_otsu_binarization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/image_thresholding/screenshots/twitter_image_otsu_binarization.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/README.md: -------------------------------------------------------------------------------- 1 | # Morphological Transformations 2 | 3 | See [OpenCV-Python Tutorials - Morphological Transformations](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops) for the original tutorial. 4 | 5 | # The Smily Face Example 6 | 7 | Demo code: `compare_morph.py` 8 | 9 | Say we have this grayscale smily face image: 10 | 11 | ![smily_original_noisy.png](./screenshots/smily_original_noisy.png) 12 | 13 | Notice these noises: 14 | 15 | - white dots in the (black) background. 16 | - black dots in the (white) foreground. 17 | 18 | We can use Morphological Transformations to detect and/or remove these noises. 19 | 20 | For this illustration, we use a 5-by-5 kernal. 21 | 22 | ``` 23 | import cv2 24 | import numpy as np 25 | 26 | kernel = np.ones((5, 5), np.uint8) 27 | img = cv2.imread('smily_original_noisy.png', 0) 28 | erosion = cv2.erode(img, kernel, iterations=1) 29 | dilation = cv2.dilate(img, kernel, iterations=1) 30 | gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) 31 | opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 32 | closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) 33 | tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) 34 | blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel) 35 | ``` 36 | 37 | Here is the output (see `compare_morph.py` for the complete code): 38 | 39 | ![compare_morphology_options.png](./screenshots/compare_morphology_options.png) 40 | 41 | This is just a basic illustration. To truely understand noise and learn how to remove / extract them, we believe more sophisticated methods may be required. 42 | 43 | # Structuring Element 44 | 45 | These two methods are equivalent in the creation of a 5-by-5 (all ones) kernal: 46 | 47 | `cv2` method: 48 | 49 | ``` 50 | In [32]: cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) 51 | Out[32]: 52 | array([[1, 1, 1, 1, 1], 53 | [1, 1, 1, 1, 1], 54 | [1, 1, 1, 1, 1], 55 | [1, 1, 1, 1, 1], 56 | [1, 1, 1, 1, 1]], dtype=uint8) 57 | ``` 58 | 59 | `numpy` Method: 60 | 61 | ``` 62 | In [33]: np.ones((5, 5), np.uint8) 63 | Out[33]: 64 | array([[1, 1, 1, 1, 1], 65 | [1, 1, 1, 1, 1], 66 | [1, 1, 1, 1, 1], 67 | [1, 1, 1, 1, 1], 68 | [1, 1, 1, 1, 1]], dtype=uint8) 69 | ``` 70 | 71 | In the code `compare_morph.py` I have used the cv2 method but also have included the numpy method as a comment - feel free to try out both. You shall get the same result regardless. 72 | 73 | 74 | # Conclusion 75 | 76 | Here we have presented a simple comparison of the various morphological transformations and understand their feature and potential usage / purpose. -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/compare_morph.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 28 10:02:38 2015 4 | Use this code to compare the effect of various morphological transformations. 5 | For this exercise we use a 5-by-5 kernal by can be anything. 6 | Inspred by OpenCV-Python Tutorials - Morphological Transformations 7 | https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops 8 | @author: Johnny 9 | """ 10 | 11 | import cv2 12 | import numpy as np 13 | from matplotlib import pyplot as plt 14 | 15 | # numpy kernal creation method: 16 | # kernel = np.ones((5, 5), np.uint8) 17 | # cv2 kernal creation method: 18 | kernal = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) 19 | 20 | # Note: the input is a grayscale image 21 | img = cv2.imread('smily_original_noisy.png', 0) 22 | erosion = cv2.erode(img, kernel, iterations=1) 23 | dilation = cv2.dilate(img, kernel, iterations=1) 24 | gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) 25 | opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 26 | closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) 27 | tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) 28 | blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel) 29 | 30 | titles = [ 31 | 'original\n(think white soil)', 'erosion\n(losing soil)', 32 | 'dilation\n(gaining soil)', 'gradient\n(dilation - erosion)', 33 | 'opening\n(erode -> dilate)', 'closing\n(dilate -> erode)', 34 | 'tophat\n(original - opening)', 'blackhat\n(original - closing)'] 35 | 36 | images = [img, erosion, dilation, gradient, 37 | opening, closing, tophat, blackhat] 38 | 39 | for i in xrange(8): 40 | plt.subplot(2, 4, i+1), plt.imshow(images[i], 'gray') 41 | plt.title(titles[i]) 42 | plt.xticks([]), plt.yticks([]) 43 | 44 | plt.show() 45 | -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/screenshots/compare_morphology_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/screenshots/compare_morphology_options.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/screenshots/smily_original_noisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/screenshots/smily_original_noisy.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/smily_in_snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/smily_in_snow.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/smily_in_snow_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/smily_in_snow_2.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/smily_in_snow_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/smily_in_snow_3.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/smily_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/smily_original.png -------------------------------------------------------------------------------- /image_processing_in_opencv/morphological_transformations/smily_original_noisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/morphological_transformations/smily_original_noisy.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/README.md: -------------------------------------------------------------------------------- 1 | # Smoothing Images 2 | 3 | See [OpenCV-Python Tutorials - Smoothing Images](https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_filtering/py_filtering.html) for original tutorials. 4 | 5 | # cv2.filter2D 6 | 7 | code: `smooth_image_with_filter2d.py`. 8 | 9 | Screenshots: 10 | 11 | ![filter2d.png](./screenshots/filter2d.png) 12 | 13 | # cv2.blur 14 | 15 | code: `smooth_image_with_blur.py`. 16 | 17 | Screenshots: 18 | 19 | ![blur.png](./screenshots/blur.png) 20 | 21 | # cv2.GaussianBlur 22 | 23 | code: `smooth_image_with_gaussian_blur.py`. 24 | 25 | Screenshots: 26 | 27 | ![gaussian_blur.png](./screenshots/gaussian_blur.png) 28 | 29 | # cv2.medianBlur 30 | 31 | code: `smooth_image_with_median_blur.py`. 32 | 33 | Screenshots: 34 | 35 | ![median_blur.png](./screenshots/median_blur.png) 36 | 37 | # cv2.bilateralFilter 38 | 39 | code: `smooth_image_with_bilateral_filter.py 40 | 41 | Screenshots: 42 | 43 | ![bilateral_filter.png](./screenshots/bilateral_filter.png) 44 | 45 | # Conclusion 46 | 47 | Here we have illustrated a number of image smoothing options. -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/carpet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/carpet.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/opencv_logo_black_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/opencv_logo_black_background.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/opencv_logo_black_background_noisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/opencv_logo_black_background_noisy.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/screenshots/bilateral_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/screenshots/bilateral_filter.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/screenshots/blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/screenshots/blur.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/screenshots/filter2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/screenshots/filter2d.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/screenshots/gaussian_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/screenshots/gaussian_blur.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/screenshots/median_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Atlas7/opencv_python_tutorials/0dfe894e9315608b7e64d60bdf45f16bfedcbc66/image_processing_in_opencv/smoothing_images/screenshots/median_blur.png -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/smooth_image_with_bilateral_filter.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 10:12:03 2015 4 | Illustrate smoothing of an image with 2D Convolution. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | img_bgr = cv2.imread('carpet.png') 13 | print img_bgr is not None 14 | #%% 15 | img_rgb = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2RGB) 16 | #%% 17 | blur_rgb = cv2.bilateralFilter(img_rgb,9,75,75) 18 | #%% 19 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Original') 20 | plt.xticks([]), plt.yticks([]) 21 | plt.subplot(122),plt.imshow(blur_rgb),plt.title('cv2.bilateralFilter') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.show() 24 | -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/smooth_image_with_blur.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 10:12:03 2015 4 | Illustrate smoothing of an image with 2D Convolution. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | img_bgr = cv2.imread('opencv_logo_black_background.png') 13 | print img_bgr is not None 14 | #%% 15 | img_rgb = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2RGB) 16 | #%% 17 | blur_rgb = cv2.blur(img_rgb,(5,5)) 18 | #%% 19 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Original') 20 | plt.xticks([]), plt.yticks([]) 21 | plt.subplot(122),plt.imshow(blur_rgb),plt.title('cv2.blur') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.show() 24 | -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/smooth_image_with_filter2d.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 10:12:03 2015 4 | Illustrate smoothing of an image with 2D Convolution. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | img_bgr = cv2.imread('opencv_logo_black_background.png') 13 | print img_bgr is not None 14 | #%% 15 | img_rgb = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2RGB) 16 | #%% 17 | kernel = np.ones((5,5),np.float32)/25 18 | #%% 19 | dst_rgb = cv2.filter2D(img_rgb,-1,kernel) 20 | #%% 21 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Original') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.subplot(122),plt.imshow(dst_rgb),plt.title('cv2.filter2D') 24 | plt.xticks([]), plt.yticks([]) 25 | plt.show() 26 | -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/smooth_image_with_gaussian_blur.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 10:12:03 2015 4 | Illustrate smoothing of an image with 2D Convolution. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | img_bgr = cv2.imread('opencv_logo_black_background.png') 13 | print img_bgr is not None 14 | #%% 15 | img_rgb = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2RGB) 16 | #%% 17 | blur_rgb = cv2.GaussianBlur(img_rgb,(5,5),0) 18 | #%% 19 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Original') 20 | plt.xticks([]), plt.yticks([]) 21 | plt.subplot(122),plt.imshow(blur_rgb),plt.title('cv2.GaussianBlur') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.show() 24 | -------------------------------------------------------------------------------- /image_processing_in_opencv/smoothing_images/smooth_image_with_median_blur.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon May 25 10:12:03 2015 4 | Illustrate smoothing of an image with 2D Convolution. 5 | @author: Johnny 6 | """ 7 | #%% 8 | import cv2 9 | import numpy as np 10 | from matplotlib import pyplot as plt 11 | #%% 12 | img_bgr = cv2.imread('opencv_logo_black_background_noisy.png') 13 | print img_bgr is not None 14 | #%% 15 | img_rgb = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2RGB) 16 | #%% 17 | median_rgb = cv2.medianBlur(img_rgb,5) 18 | #%% 19 | plt.subplot(121),plt.imshow(img_rgb),plt.title('Original') 20 | plt.xticks([]), plt.yticks([]) 21 | plt.subplot(122),plt.imshow(median_rgb),plt.title('cv2.medianBlur') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.show() 24 | --------------------------------------------------------------------------------