From b10e4d6d69bb10ec3bae8fc4ca0ed7b47487476b Mon Sep 17 00:00:00 2001 From: ex2tron Date: Wed, 8 Jan 2020 20:21:03 +0800 Subject: [PATCH 01/16] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e68d42d..2a2aa66 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + > 抱歉,由于旧域名和服务器到期,新的还在审核中,导致博客图片和链接均失效,预计还需7左右恢复 + ## OpenCV-Python图像处理教程(源码及素材) ![](http://pic.ex2tron.top/cv2_python_opencv_cover_gif2.gif) From 73fd32fabea394dfd571c29d7963400fdeff62a1 Mon Sep 17 00:00:00 2001 From: extronwang Date: Mon, 13 Jan 2020 14:32:50 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E6=96=B0=E5=9F=9F?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md" | 8 +-- .../README.md" | 6 +-- .../README.md" | 4 +- .../README.md" | 6 +-- .../README.md" | 10 ++-- .../README.md" | 8 +-- .../README.md" | 6 +-- .../README.md" | 8 +-- .../README.md" | 10 ++-- .../README.md" | 12 ++--- .../README.md" | 12 ++--- "13. \350\275\256\345\273\223/README.md" | 6 +-- .../README.md" | 12 ++--- .../README.md" | 18 +++---- .../README.md" | 10 ++-- .../README.md" | 14 +++--- README.md | 49 ++++++++++--------- .../README.md" | 18 +++---- .../README.md" | 26 +++++----- .../README.md" | 26 +++++----- .../cv2_lane_detection_picture.py" | 2 +- .../cv2_lane_detection_video.py" | 2 +- .../README.md" | 8 +-- .../README.md" | 4 +- .../README.md" | 8 +-- .../README.md" | 22 ++++----- .../README.md" | 6 +-- .../README.md" | 4 +- .../README.md" | 16 +++--- .../README.md" | 8 +-- .../README.md" | 12 ++--- .../README.md" | 8 +-- 32 files changed, 185 insertions(+), 184 deletions(-) diff --git "a/01. \347\256\200\344\273\213\344\270\216\345\256\211\350\243\205/README.md" "b/01. \347\256\200\344\273\213\344\270\216\345\256\211\350\243\205/README.md" index d0d579d..2707d49 100644 --- "a/01. \347\256\200\344\273\213\344\270\216\345\256\211\350\243\205/README.md" +++ "b/01. \347\256\200\344\273\213\344\270\216\345\256\211\350\243\205/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程01:简介与安装](http://ex2tron.wang/opencv-python-introduction-and-installation/) -![](http://pic.ex2tron.top/cv2_install_opencv-python.jpg) +![](http://blog.codec.wang/cv2_install_opencv-python.jpg) 相信大部分人知道的OpenCV都是用C++来开发的,那为什么我推荐使用Python呢? @@ -14,7 +14,7 @@ 我举两个简单的例子就一目了然了:一个是读入图片,另一个是调整图片的对比度和亮度: -![](http://pic.ex2tron.top/cv2_python_vs_cplus_speed.jpg) +![](http://blog.codec.wang/cv2_python_vs_cplus_speed.jpg) **可以看到某些情况下Python的运行速度甚至好于C++,代码行数也直接少一半多!**另外,图像是矩阵数据,OpenCV-Python原生支持[Numpy](https://baike.baidu.com/item/numpy),相当于Python中的Matlab,为矩阵运算、科学计算提供了极大的便利性。 @@ -22,7 +22,7 @@ 近些年,人工智能相关技术的快速发展大家有目共睹,不必多说。在编程语言方面,更多人希望的是具备高效开发效率、跨平台、高度扩展性的语言,尤其是一些AI巨头优先推出支持Python语言的深度学习框架,如Facebook的[PyTorch](https://pytorch.org/)、Google的[Tensorflow](https://tensorflow.google.cn/)等,可以说Python是名副其实的“网红语言”了。 -![](http://pic.ex2tron.top/cv2_ai_ml_dl2.jpg) +![](http://blog.codec.wang/cv2_ai_ml_dl2.jpg) 从[TIOBE编程语言排行榜](https://www.tiobe.com/tiobe-index/)也可以看到,Python发展迅猛,已经逼近C++的份额。这个排行榜每月更新,我就不截图了,编写时TOP5:Java/C/C++/Python/C#。 @@ -76,7 +76,7 @@ print(cv2.__version__) # '3.4.1' 为了便于学习OpenCV,我写了一个教学款软件[LearnOpenCVEdu](https://github.com/ex2tron/LearnOpenCVEdu),目前只开发了一部分功能,有兴趣的童鞋可以支持一下噢😊 -![大家随手点个Star吧(●ˇ∀ˇ●)](http://pic.ex2tron.top/cv2_learn_opencv_edu_soft_screenshot.jpg) +![大家随手点个Star吧(●ˇ∀ˇ●)](http://blog.codec.wang/cv2_learn_opencv_edu_soft_screenshot.jpg) > 经验之谈:虽然从一开始我就推荐大家使用OpenCV-Python进行图像处理,但*想要深入理解OpenCV*,C++还是必须的,尤其是**OpenCV源码**! diff --git "a/02. \345\237\272\346\234\254\345\205\203\347\264\240-\345\233\276\347\211\207/README.md" "b/02. \345\237\272\346\234\254\345\205\203\347\264\240-\345\233\276\347\211\207/README.md" index ae17d18..78b337b 100644 --- "a/02. \345\237\272\346\234\254\345\205\203\347\264\240-\345\233\276\347\211\207/README.md" +++ "b/02. \345\237\272\346\234\254\345\205\203\347\264\240-\345\233\276\347\211\207/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程02:基本元素-图片](http://ex2tron.wang/opencv-python-basic-element-image/) -![](http://pic.ex2tron.top/cv2_image_coordinate_channels.jpg) +![](http://blog.codec.wang/cv2_image_coordinate_channels.jpg) 学习如何加载图片,显示并保存图片。图片等可到[源码处](#引用)下载。 @@ -17,7 +17,7 @@ 图像坐标的起始点是在左上角,所以行对应的是y,列对应的是x: -![](http://pic.ex2tron.top/cv2_image_coordinate_channels.jpg) +![](http://blog.codec.wang/cv2_image_coordinate_channels.jpg) ### 加载图片 @@ -54,7 +54,7 @@ cv2.waitKey(0) 参数1是窗口的名字,参数2是要显示的图片。不同窗口之间用窗口名区分,所以窗口名相同就表示是同一个窗口,显示结果如下: -![](http://pic.ex2tron.top/cv2_show_lena_gray.jpg) +![](http://blog.codec.wang/cv2_show_lena_gray.jpg) `cv2.waitKey()`是让程序暂停的意思,参数是等待时间(毫秒ms)。时间一到,会继续执行接下来的程序,传入0的话表示一直等待。等待期间也可以获取用户的按键输入:`k = cv2.waitKey(0)`([练习1](#练习))。 diff --git "a/04. \345\233\276\345\203\217\345\237\272\346\234\254\346\223\215\344\275\234/README.md" "b/04. \345\233\276\345\203\217\345\237\272\346\234\254\346\223\215\344\275\234/README.md" index 210c228..2cbdbe9 100644 --- "a/04. \345\233\276\345\203\217\345\237\272\346\234\254\346\223\215\344\275\234/README.md" +++ "b/04. \345\233\276\345\203\217\345\237\272\346\234\254\346\223\215\344\275\234/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程04:图像基本操作](http://ex2tron.wang/opencv-python-basic-operations/) -![](http://pic.ex2tron.top/cv2_lena_face_roi_crop.jpg) +![](http://blog.codec.wang/cv2_lena_face_roi_crop.jpg) 学习获取和修改像素点的值,ROI感兴趣区域,通道分离合并等基本操作。图片等可到[源码处](#引用)下载。 @@ -78,7 +78,7 @@ print(img.size) # 263*247*3=194883 [ROI](https://baike.baidu.com/item/ROI/1125333#viewPageContent):Region of Interest,感兴趣区域。什么意思呢?比如我们要检测眼睛,因为眼睛肯定在脸上,所以我们感兴趣的只有脸这部分,其他都不care,所以可以单独把脸截取出来,这样就可以大大节省计算量,提高运行速度。 -![只关心脸( ╯□╰ )](http://pic.ex2tron.top/cv2_lena_face_roi_crop.jpg) +![只关心脸( ╯□╰ )](http://blog.codec.wang/cv2_lena_face_roi_crop.jpg) 截取ROI非常简单,指定图片的范围即可(后面我们学了特征后,就可以自动截取辣,(ง •_•)ง): diff --git "a/05. \351\242\234\350\211\262\347\251\272\351\227\264\350\275\254\346\215\242/README.md" "b/05. \351\242\234\350\211\262\347\251\272\351\227\264\350\275\254\346\215\242/README.md" index a23b9f5..ee2521f 100644 --- "a/05. \351\242\234\350\211\262\347\251\272\351\227\264\350\275\254\346\215\242/README.md" +++ "b/05. \351\242\234\350\211\262\347\251\272\351\227\264\350\275\254\346\215\242/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程05:颜色空间转换](http://ex2tron.wang/opencv-python-changing-colorspaces/) -![](http://pic.ex2tron.top/cv2_exercise_tracking_three_colors.jpg) +![](http://blog.codec.wang/cv2_exercise_tracking_three_colors.jpg) 学习如何进行图片的颜色空间转换,视频中追踪特定颜色的物体。图片等可到[源码处](#引用)下载。 @@ -50,7 +50,7 @@ print(flags) 3. 提取蓝色范围的物体 4. 只显示蓝色物体 -![跟踪视频中的蓝色物体](http://pic.ex2tron.top/cv2_blue_object_tracking.jpg) +![跟踪视频中的蓝色物体](http://blog.codec.wang/cv2_blue_object_tracking.jpg) ```python import numpy as np @@ -103,7 +103,7 @@ print(hsv_blue) # [[[120 255 255]]] 1. 尝试在视频中同时提取红色、蓝色、绿色的物体。(效果如下) -![同时追踪3种颜色](http://pic.ex2tron.top/cv2_exercise_tracking_three_colors.jpg) +![同时追踪3种颜色](http://blog.codec.wang/cv2_exercise_tracking_three_colors.jpg) ## 接口文档 diff --git "a/06. \351\230\210\345\200\274\345\210\206\345\211\262/README.md" "b/06. \351\230\210\345\200\274\345\210\206\345\211\262/README.md" index e5d584f..7a4d5db 100644 --- "a/06. \351\230\210\345\200\274\345\210\206\345\211\262/README.md" +++ "b/06. \351\230\210\345\200\274\345\210\206\345\211\262/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程06:阈值分割](http://ex2tron.wang/opencv-python-image-thresholding/) -![](http://pic.ex2tron.top/cv2_threshold_binary_demo.jpg) +![](http://blog.codec.wang/cv2_threshold_binary_demo.jpg) 学习使用不同的阈值方法"二值化"图像。图片等可到[源码处](#引用)下载。 @@ -17,7 +17,7 @@ 固定阈值分割很直接,一句话说就是像素点值大于阈值变成一类值,小于阈值变成另一类值。 -![](http://pic.ex2tron.top/cv2_threshold_binary_demo.jpg) +![](http://blog.codec.wang/cv2_threshold_binary_demo.jpg) ```python import cv2 @@ -63,11 +63,11 @@ for i in range(6): plt.show() ``` -![5种不同的阈值方式结果](http://pic.ex2tron.top/cv2_different_threshold_demo.jpg) +![5种不同的阈值方式结果](http://blog.codec.wang/cv2_different_threshold_demo.jpg) > 经验之谈:很多人误以为阈值分割就是[二值化](https://baike.baidu.com/item/%E4%BA%8C%E5%80%BC%E5%8C%96)。从上图中可以发现,两者并不等同,阈值分割结果是两类值,而不是两个值,所以教程开头我把二值化加了引号。 -![](http://pic.ex2tron.top/cv2_different_thresholds_theory.jpg) +![](http://blog.codec.wang/cv2_different_thresholds_theory.jpg) ### 自适应阈值 @@ -95,7 +95,7 @@ for i in range(4): plt.show() ``` -![自适应阈值对比固定阈值](http://pic.ex2tron.top/cv2_adaptive_vs_global_thresholding.jpg) +![自适应阈值对比固定阈值](http://blog.codec.wang/cv2_adaptive_vs_global_thresholding.jpg) - 参数1:要处理的原图 - 参数2:最大阈值,一般为255 diff --git "a/07. \345\233\276\345\203\217\345\207\240\344\275\225\345\217\230\346\215\242/README.md" "b/07. \345\233\276\345\203\217\345\207\240\344\275\225\345\217\230\346\215\242/README.md" index a3de0bf..4e90f64 100644 --- "a/07. \345\233\276\345\203\217\345\207\240\344\275\225\345\217\230\346\215\242/README.md" +++ "b/07. \345\233\276\345\203\217\345\207\240\344\275\225\345\217\230\346\215\242/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程07:图像几何变换](http://ex2tron.wang/opencv-python-image-geometric-transformation/) -![](http://pic.ex2tron.top/cv2_perspective_transformations_inm.jpg) +![](http://blog.codec.wang/cv2_perspective_transformations_inm.jpg) 学习如何旋转、平移、缩放和翻转图片。图片等可到[源码处](#引用)下载。 @@ -45,7 +45,7 @@ dst = cv2.flip(img, 1) 其中,参数2 = 0:垂直翻转(沿x轴),参数2 > 0: 水平翻转(沿y轴),参数2 < 0: 水平垂直翻转。 -![](http://pic.ex2tron.top/cv2_flip_image_sample.jpg) +![](http://blog.codec.wang/cv2_flip_image_sample.jpg) ### 平移图片 @@ -78,7 +78,7 @@ cv2.imshow('shift', dst) cv2.waitKey(0) ``` -![](http://pic.ex2tron.top/cv2_translation_100_50.jpg) +![](http://blog.codec.wang/cv2_translation_100_50.jpg) ### 旋转图片 @@ -97,7 +97,7 @@ cv2.imshow('rotation', dst) cv2.waitKey(0) ``` -![逆时针旋转45°并缩放](http://pic.ex2tron.top/cv2_rotation_45_degree.jpg) +![逆时针旋转45°并缩放](http://blog.codec.wang/cv2_rotation_45_degree.jpg) ## 小结 diff --git "a/08. \347\273\230\345\233\276\345\212\237\350\203\275/README.md" "b/08. \347\273\230\345\233\276\345\212\237\350\203\275/README.md" index 79a04a3..e40de6b 100644 --- "a/08. \347\273\230\345\233\276\345\212\237\350\203\275/README.md" +++ "b/08. \347\273\230\345\233\276\345\212\237\350\203\275/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程08:绘图功能](http://ex2tron.wang/opencv-python-drawing-function/) -![](http://pic.ex2tron.top/cv2_drawing_functions.jpg) +![](http://blog.codec.wang/cv2_drawing_functions.jpg) 学习画线、圆和矩形等多种几何形状,给图片添加文字。图片等可到[源码处](#引用)下载。 @@ -34,7 +34,7 @@ cv2.imshow('img', img) cv2.waitKey(0) ``` -![绘制各种几何形状](http://pic.ex2tron.top/cv2_drawing_functions.jpg) +![绘制各种几何形状](http://blog.codec.wang/cv2_drawing_functions.jpg) 上图就是本教程绘制的最终效果,下面一步步来看: @@ -139,7 +139,7 @@ cv2.putText(img, 'ex2tron', (10, 500), font, 1. 你能用已学的绘图功能画出OpenCV的logo吗?(提示:椭圆和圆) -![OpenCV logo](http://pic.ex2tron.top/cv2_draw_opencv_logo.jpg) +![OpenCV logo](http://blog.codec.wang/cv2_draw_opencv_logo.jpg) ## 接口文档 diff --git "a/09. \345\233\276\345\203\217\346\267\267\345\220\210/README.md" "b/09. \345\233\276\345\203\217\346\267\267\345\220\210/README.md" index 200eb95..2083536 100644 --- "a/09. \345\233\276\345\203\217\346\267\267\345\220\210/README.md" +++ "b/09. \345\233\276\345\203\217\346\267\267\345\220\210/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程09:图像混合](http://ex2tron.wang/opencv-python-image-blending/) -![](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg) +![](http://blog.codec.wang/cv2_image_blending_6_4.jpg) 学习图片间的数学运算,图像混合。图片等可到[源码处](#引用)下载。 @@ -42,7 +42,7 @@ img2 = cv2.imread('opencv-logo-white.png') res = cv2.addWeighted(img1, 0.6, img2, 0.4, 0) ``` -![图像混合](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg) +![图像混合](http://blog.codec.wang/cv2_image_blending_6_4.jpg) > 经验之谈:α和β都等于1时,就相当于图片相加。 @@ -50,11 +50,11 @@ res = cv2.addWeighted(img1, 0.6, img2, 0.4, 0) 按位操作包括按位与/或/非/异或操作,有什么用途呢?比如说我们要实现下图的效果: -![](http://pic.ex2tron.top/cv2_bitwise_operations_demo.jpg) +![](http://blog.codec.wang/cv2_bitwise_operations_demo.jpg) 如果将两幅图片直接相加会改变图片的颜色,如果用图像混合,则会改变图片的透明度,所以我们需要用按位操作。首先来了解一下[掩膜](https://baike.baidu.com/item/%E6%8E%A9%E8%86%9C/8544392?fr=aladdin)(mask)的概念:掩膜是用一副二值化图片对另外一幅图片进行局部的遮挡,看下图就一目了然了: -![掩膜概念](http://pic.ex2tron.top/cv2_understand_mask.jpg) +![掩膜概念](http://blog.codec.wang/cv2_understand_mask.jpg) 所以我们的思路就是把原图中要放logo的区域抠出来,再把logo放进去就行了: diff --git "a/10. \345\271\263\346\273\221\345\233\276\345\203\217/README.md" "b/10. \345\271\263\346\273\221\345\233\276\345\203\217/README.md" index bc15108..756a1fa 100644 --- "a/10. \345\271\263\346\273\221\345\233\276\345\203\217/README.md" +++ "b/10. \345\271\263\346\273\221\345\233\276\345\203\217/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程10:平滑图像](http://ex2tron.wang/opencv-python-smoothing-images/) -![](http://pic.ex2tron.top/cv2_bilateral_vs_gaussian.jpg) +![](http://blog.codec.wang/cv2_bilateral_vs_gaussian.jpg) 学习模糊/平滑图像,消除噪点。图片等可到[源码处](#引用)下载。 @@ -72,7 +72,7 @@ blur = cv2.boxFilter(img, -1, (3, 3), normalize=True) 前面两种滤波方式,卷积核内的每个值都一样,也就是说图像区域中每个像素的权重也就一样。高斯滤波的卷积核权重并不相同:中间像素点权重最高,越远离中心的像素权重越小,来,数学时间( ╯□╰ ),还记得标准正态分布的曲线吗? -![](http://pic.ex2tron.top/cv2_gaussian_kernel_function_theory.jpg) +![](http://blog.codec.wang/cv2_gaussian_kernel_function_theory.jpg) 显然这种处理元素间权值的方式更加合理一些。图像是2维的,所以我们需要使用[2维的高斯函数](https://en.wikipedia.org/wiki/Gaussian_filter),比如OpenCV中默认的3×3的高斯卷积核(具体原理和卷积核生成方式请参考文末的[番外小篇](#番外小篇:高斯滤波卷积核)): @@ -96,7 +96,7 @@ gaussian = cv2.GaussianBlur(img, (5, 5), 1) # 高斯滤波 参数3 σx值越大,模糊效果越明显。高斯滤波相比均值滤波效率要慢,但可以有效消除高斯噪声,能保留更多的图像细节,所以经常被称为最有用的滤波器。均值滤波与高斯滤波的对比结果如下(均值滤波丢失的细节更多): -![](http://pic.ex2tron.top/cv2_gaussian_vs_average.jpg) +![](http://blog.codec.wang/cv2_gaussian_vs_average.jpg) ### 中值滤波 @@ -111,7 +111,7 @@ blur = cv2.blur(img, (5, 5)) # 均值滤波 median = cv2.medianBlur(img, 5) # 中值滤波 ``` -![](http://pic.ex2tron.top/cv2_median_vs_average.jpg) +![](http://blog.codec.wang/cv2_median_vs_average.jpg) ### 双边滤波 @@ -124,7 +124,7 @@ gau = cv2.GaussianBlur(img, (5, 5), 0) # 高斯滤波 blur = cv2.bilateralFilter(img, 9, 75, 75) # 双边滤波 ``` -![](http://pic.ex2tron.top/cv2_bilateral_vs_gaussian.jpg) +![](http://blog.codec.wang/cv2_bilateral_vs_gaussian.jpg) 可以看到,双边滤波明显保留了更多边缘信息。 diff --git "a/11. \350\276\271\347\274\230\346\243\200\346\265\213/README.md" "b/11. \350\276\271\347\274\230\346\243\200\346\265\213/README.md" index b4fa8d5..96ee756 100644 --- "a/11. \350\276\271\347\274\230\346\243\200\346\265\213/README.md" +++ "b/11. \350\276\271\347\274\230\346\243\200\346\265\213/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程11:边缘检测](http://ex2tron.wang/opencv-python-edge-detection/) -![](http://pic.ex2tron.top/cv2_canny_edge_detection_threshold.jpg) +![](http://blog.codec.wang/cv2_canny_edge_detection_threshold.jpg) 学习使用Canny获取图像的边缘。图片等可到[源码处](#引用)下载。 @@ -28,7 +28,7 @@ cv2.imshow('canny', np.hstack((img, edges))) cv2.waitKey(0) ``` -![](http://pic.ex2tron.top/cv2_canny_edge_detection.jpg) +![](http://blog.codec.wang/cv2_canny_edge_detection.jpg) `cv2.Canny()`进行边缘检测,参数2、3表示最低、高阈值,下面来解释下具体原理。 @@ -64,7 +64,7 @@ $$ 梯度其实已经表示了轮廓,但为了进一步筛选,可以在上面的四个角度方向上再取局部极大值: -![](http://pic.ex2tron.top/cv2_understand_canny_direction.jpg) +![](http://blog.codec.wang/cv2_understand_canny_direction.jpg) 比如,A点在45°方向上大于B/C点,那就保留它,把B/C设置为0。 @@ -72,7 +72,7 @@ $$ 经过前面三步,就只剩下0和可能的边缘梯度值了,为了最终确定下来,需要设定高低阈值: -![](http://pic.ex2tron.top/cv2_understand_canny_max_min_val.jpg) +![](http://blog.codec.wang/cv2_understand_canny_max_min_val.jpg) - 像素点的值大于最高阈值,那肯定是边缘(上图A) - 同理像素值小于最低阈值,那肯定不是边缘 @@ -94,13 +94,13 @@ cv2.waitKey(0) 代码中我用了[番外篇:Otsu阈值法](/opencv-python-extra-otsu-thresholding/)中的自动阈值分割,如果你不太了解,大可以使用传统的方法,不过如果是下面这种图片,推荐用Otsu阈值法。另外Python中某个值不用的话,就写个下划线'_'。 -![](http://pic.ex2tron.top/cv2_canny_edge_detection_threshold.jpg) +![](http://blog.codec.wang/cv2_canny_edge_detection_threshold.jpg) ## 练习 1. (选做)如果你不太理解高低阈值的效果,创建两个滑动条来调节它们的值看看: -![](http://pic.ex2tron.top/cv2_trackbar_maxval_minval_canny.gif) +![](http://blog.codec.wang/cv2_trackbar_maxval_minval_canny.gif) ## 小结 diff --git "a/12. \350\205\220\350\232\200\344\270\216\350\206\250\350\203\200/README.md" "b/12. \350\205\220\350\232\200\344\270\216\350\206\250\350\203\200/README.md" index 97fb7b4..06813b7 100644 --- "a/12. \350\205\220\350\232\200\344\270\216\350\206\250\350\203\200/README.md" +++ "b/12. \350\205\220\350\232\200\344\270\216\350\206\250\350\203\200/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程12:腐蚀与膨胀](http://ex2tron.wang/opencv-python-erode-and-dilate/) -![](http://pic.ex2tron.top/cv2_understand_morphological.jpg) +![](http://blog.codec.wang/cv2_understand_morphological.jpg) 学习常用形态学操作:腐蚀膨胀,开运算和闭运算。图片等可到[源码处](#引用)下载。 @@ -18,7 +18,7 @@ 形态学操作其实就是**改变物体的形状**,比如腐蚀就是"变瘦",膨胀就是"变胖",看下图就明白了: -![](http://pic.ex2tron.top/cv2_understand_morphological.jpg) +![](http://blog.codec.wang/cv2_understand_morphological.jpg) > 经验之谈:形态学操作一般作用于二值化图,来连接相邻的元素或分离成独立的元素。**腐蚀和膨胀是针对图片中的白色部分!** @@ -26,7 +26,7 @@ 腐蚀的效果是把图片"变瘦",其原理是在原图的小区域内取局部最小值。因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0: -![](http://pic.ex2tron.top/cv2_understand_erosion.jpg) +![](http://blog.codec.wang/cv2_understand_erosion.jpg) 这样原图中边缘地方就会变成0,达到了瘦身目的(小胖福利(●ˇ∀ˇ●)) @@ -49,7 +49,7 @@ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 椭圆结构 kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) # 十字形结构 ``` -![](http://pic.ex2tron.top/cv2_morphological_struct_element.jpg) +![](http://blog.codec.wang/cv2_morphological_struct_element.jpg) ### 膨胀 @@ -77,7 +77,7 @@ img = cv2.imread('j_noise_in.bmp', 0) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # 闭运算 ``` -![](http://pic.ex2tron.top/cv2_morphological_opening_closing.jpg) +![](http://blog.codec.wang/cv2_morphological_opening_closing.jpg) > 经验之谈:很多人对开闭运算的作用不是很清楚(好吧,其实是比较容易混◑﹏◐),但看上图↑,不用怕:如果我们的目标物体外面有很多无关的小区域,就用开运算去除掉;如果物体内部有很多小黑洞,就用闭运算填充掉。 @@ -92,7 +92,7 @@ img = cv2.imread('school.bmp', 0) gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) ``` -![](http://pic.ex2tron.top/cv2_morphological_gradient.jpg) +![](http://blog.codec.wang/cv2_morphological_gradient.jpg) - 顶帽:原图减去开运算后的图:`src - opening` diff --git "a/13. \350\275\256\345\273\223/README.md" "b/13. \350\275\256\345\273\223/README.md" index 3d323ae..ac9cb71 100644 --- "a/13. \350\275\256\345\273\223/README.md" +++ "b/13. \350\275\256\345\273\223/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程13:轮廓](http://ex2tron.wang/opencv-python-contours/) -![](http://pic.ex2tron.top/cv2_understand_contours.jpg) +![](http://blog.codec.wang/cv2_understand_contours.jpg) 学习如何寻找并绘制轮廓。图片等可到[源码处](#引用)下载。 @@ -20,7 +20,7 @@ 谈起轮廓不免想到边缘,它们确实很像。简单的说,**轮廓是连续的,边缘并不全都连续**(下图)。其实边缘主要是作为图像的特征使用,比如可以用边缘特征可以区分脸和手,而轮廓主要用来分析物体的形态,比如物体的周长和面积等,可以说边缘包括轮廓。 -![边缘和轮廓的区别](http://pic.ex2tron.top/cv2_understand_contours.jpg) +![边缘和轮廓的区别](http://blog.codec.wang/cv2_understand_contours.jpg) 寻找轮廓的操作一般用于二值化图,所以通常会使用阈值分割或Canny边缘检测先得到二值图。 @@ -49,7 +49,7 @@ print(len(contours)) # 结果应该为2 函数有3个返回值,image还是原来的二值化图片,hierarchy是轮廓间的层级关系([番外篇:轮廓层级](/opencv-python-extra-contours-hierarchy/)),这两个暂时不用理会。我们主要看contours,它就是找到的轮廓了,以数组形式存储,记录了每条轮廓的所有像素点的坐标(x,y)。 -![](http://pic.ex2tron.top/cv2_find_contours_contours.jpg) +![](http://blog.codec.wang/cv2_find_contours_contours.jpg) ### 绘制轮廓 diff --git "a/14. \350\275\256\345\273\223\347\211\271\345\276\201/README.md" "b/14. \350\275\256\345\273\223\347\211\271\345\276\201/README.md" index 2f19a0f..33b2be7 100644 --- "a/14. \350\275\256\345\273\223\347\211\271\345\276\201/README.md" +++ "b/14. \350\275\256\345\273\223\347\211\271\345\276\201/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程14:轮廓特征](http://ex2tron.wang/opencv-python-contour-features/) -![](http://pic.ex2tron.top/cv2_min_rect_rect_bounding.jpg) +![](http://blog.codec.wang/cv2_min_rect_rect_bounding.jpg) 学习计算轮廓特征,如面积、周长、最小外接矩形等。图片等可到[源码处](#引用)下载。 @@ -15,7 +15,7 @@ 在计算轮廓特征之前,我们先用上一节的代码把轮廓找到: -![](http://pic.ex2tron.top/cv2_31_handwriting_sample.jpg) +![](http://blog.codec.wang/cv2_31_handwriting_sample.jpg) ```python import cv2 @@ -73,7 +73,7 @@ cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00'] # (205, 281) 形状的外接矩形有两种,如下图,绿色的叫外接矩形,表示不考虑旋转并且能包含整个轮廓的矩形。蓝色的叫最小外接矩,考虑了旋转: -![](http://pic.ex2tron.top/cv2_min_rect_rect_bounding.jpg) +![](http://blog.codec.wang/cv2_min_rect_rect_bounding.jpg) ```python x, y, w, h = cv2.boundingRect(cnt) # 外接矩形 @@ -98,7 +98,7 @@ cv2.drawContours(img_color1, [box], 0, (255, 0, 0), 2) cv2.circle(img_color2, (x, y), radius, (0, 0, 255), 2) ``` -![](http://pic.ex2tron.top/cv2_min_enclosing_circle.jpg) +![](http://blog.codec.wang/cv2_min_enclosing_circle.jpg) ### 拟合椭圆 @@ -109,13 +109,13 @@ ellipse = cv2.fitEllipse(cnt) cv2.ellipse(img_color2, ellipse, (255, 255, 0), 2) ``` -![](http://pic.ex2tron.top/cv2_fitting_ellipse.jpg) +![](http://blog.codec.wang/cv2_fitting_ellipse.jpg) ### 形状匹配 `cv2.matchShapes()`可以检测两个形状之间的相似度,返回**值越小,越相似**。先读入下面这张图片: -![](http://pic.ex2tron.top/cv2_match_shape_shapes.jpg) +![](http://blog.codec.wang/cv2_match_shape_shapes.jpg) ```python img = cv2.imread('shapes.jpg', 0) diff --git "a/15. \347\233\264\346\226\271\345\233\276/README.md" "b/15. \347\233\264\346\226\271\345\233\276/README.md" index 694f5d9..cac4610 100644 --- "a/15. \347\233\264\346\226\271\345\233\276/README.md" +++ "b/15. \347\233\264\346\226\271\345\233\276/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程15:直方图](http://ex2tron.wang/opencv-python-histograms/) -![](http://pic.ex2tron.top/cv2_understand_histogram.jpg) +![](http://blog.codec.wang/cv2_understand_histogram.jpg) 学习计算并绘制直方图,直方图均衡化等。图片等可到[源码处](#引用)下载。 @@ -18,7 +18,7 @@ 直方图简单来说就是图像中每个像素值的个数统计,比如说一副灰度图中像素值为0的有多少个,1的有多少个……直方图是一种分析图片的手段: -![](http://pic.ex2tron.top/cv2_understand_histogram.jpg) +![](http://blog.codec.wang/cv2_understand_histogram.jpg) 在计算直方图之前,有几个术语先来了解一下: @@ -81,7 +81,7 @@ plt.plot(hist) plt.show() ``` -![](http://pic.ex2tron.top/cv2_calc_draw_histogram.jpg) +![](http://blog.codec.wang/cv2_calc_draw_histogram.jpg) 从直方图上可以看到图片的大部分区域集中在150偏白的附近,这其实并不是很好的效果,下面我们来看看如何改善它。 @@ -91,7 +91,7 @@ plt.show() 一副效果好的图像通常在直方图上的分布比较均匀,直方图均衡化就是用来改善图像的全局亮度和对比度。其实从观感上就可以发现,前面那幅图对比度不高,偏灰白。对均衡化算法感兴趣的同学可参考:[维基百科:直方图均衡化](https://zh.wikipedia.org/wiki/%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%9D%87%E8%A1%A1%E5%8C%96) -![](http://pic.ex2tron.top/cv2_understand_histogram_equalization.jpg) +![](http://blog.codec.wang/cv2_understand_histogram_equalization.jpg) ```python equ = cv2.equalizeHist(img) @@ -104,9 +104,9 @@ cv2.imshow('equalization', np.hstack((img, equ))) # 并排显示 cv2.waitKey(0) ``` -![](http://pic.ex2tron.top/cv2_before_after_equalization.jpg) +![](http://blog.codec.wang/cv2_before_after_equalization.jpg) -![均衡化前后的直方图对比](http://pic.ex2tron.top/cv2_before_after_equalization_histogram.jpg) +![均衡化前后的直方图对比](http://blog.codec.wang/cv2_before_after_equalization_histogram.jpg) 可以看到均衡化后图片的亮度和对比度效果明显好于原图。 @@ -114,7 +114,7 @@ cv2.waitKey(0) 不难看出来,直方图均衡化是应用于整幅图片的,会有什么问题呢?看下图: -![](http://pic.ex2tron.top/cv2_understand_adaptive_histogram.jpg) +![](http://blog.codec.wang/cv2_understand_adaptive_histogram.jpg) 很明显,因为全局调整亮度和对比度的原因,脸部太亮,大部分细节都丢失了。 @@ -126,13 +126,13 @@ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) cl1 = clahe.apply(img) ``` -![](http://pic.ex2tron.top/cv2_adaptive_histogram.jpg) +![](http://blog.codec.wang/cv2_adaptive_histogram.jpg) ## 练习 1. `cv2.calcHist()`函数中的参数3是指要计算的区域(mask:目标区域白色,其余黑色),编写一个只计算图片左上角200×200区域直方图的程序。 -![](http://pic.ex2tron.top/cv2_histogram_mask.jpg) +![](http://blog.codec.wang/cv2_histogram_mask.jpg) ## 小结 diff --git "a/16. \346\250\241\346\235\277\345\214\271\351\205\215/README.md" "b/16. \346\250\241\346\235\277\345\214\271\351\205\215/README.md" index 4c85ca4..1bc6455 100644 --- "a/16. \346\250\241\346\235\277\345\214\271\351\205\215/README.md" +++ "b/16. \346\250\241\346\235\277\345\214\271\351\205\215/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程16:模板匹配](http://ex2tron.wang/opencv-python-template-matching/) -![](http://pic.ex2tron.top/cv2_understand_template_matching.jpg) +![](http://blog.codec.wang/cv2_understand_template_matching.jpg) 学习使用模板匹配在图像中寻找物体。图片等可到[源码处](#引用)下载。 @@ -17,7 +17,7 @@ [模板匹配](https://baike.baidu.com/item/模板匹配)就是用来在大图中找小图,也就是说在一副图像中寻找另外一张模板图像的位置: -![](http://pic.ex2tron.top/cv2_understand_template_matching.jpg) +![](http://blog.codec.wang/cv2_understand_template_matching.jpg) 用`cv2.matchTemplate()`实现模板匹配。首先我们来读入图片和模板: @@ -43,7 +43,7 @@ right_bottom = (left_top[0] + w, left_top[1] + h) # 右下角 cv2.rectangle(img, left_top, right_bottom, 255, 2) # 画出矩形位置 ``` -![](http://pic.ex2tron.top/cv2_ccoeff_matching_template.jpg) +![](http://blog.codec.wang/cv2_ccoeff_matching_template.jpg) ### 原理 @@ -82,7 +82,7 @@ for pt in zip(*loc[::-1]): # *号表示可选参数 cv2.rectangle(img_rgb, pt, right_bottom, (0, 0, 255), 2) ``` -![](http://pic.ex2tron.top/cv2_template_matching_multi.jpg) +![](http://blog.codec.wang/cv2_template_matching_multi.jpg) 第3步有几个Python/Numpy的重要知识,来大致看下: @@ -94,7 +94,7 @@ print(np.where(x > 5)) # 结果(先y坐标,再x坐标):(array([2, 2, 2]), array([0, 1, 2])) ``` -![](http://pic.ex2tron.top/cv2_np_where_function.jpg) +![](http://blog.codec.wang/cv2_np_where_function.jpg) - [zip()](https://docs.python.org/3/library/functions.html#zip)函数,功能强大到难以解释,举个简单例子就知道了: diff --git "a/17. \351\234\215\345\244\253\345\217\230\346\215\242/README.md" "b/17. \351\234\215\345\244\253\345\217\230\346\215\242/README.md" index 5e177e2..850a5db 100644 --- "a/17. \351\234\215\345\244\253\345\217\230\346\215\242/README.md" +++ "b/17. \351\234\215\345\244\253\345\217\230\346\215\242/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程17:霍夫变换](http://ex2tron.wang/opencv-python-hough-transform/) -![](http://pic.ex2tron.top/cv2_understand_hough_transform.jpg) +![](http://blog.codec.wang/cv2_understand_hough_transform.jpg) 学习使用霍夫变换识别出图像中的直线和圆。图片等可到[源码处](#引用)下载。 @@ -18,11 +18,11 @@ 霍夫变换常用来在图像中提取直线和圆等几何形状,我来做个简易的解释: -![](http://pic.ex2tron.top/cv2_understand_hough_transform.jpg) +![](http://blog.codec.wang/cv2_understand_hough_transform.jpg) 学过几何的都知道,直线可以分别用直角坐标系和极坐标系来表示: -![](http://pic.ex2tron.top/cv2_line_expression_in_coordinate.jpg) +![](http://blog.codec.wang/cv2_line_expression_in_coordinate.jpg) 那么经过某个点(x0,y0)的所有直线都可以用这个式子来表示: @@ -32,7 +32,7 @@ $$ 也就是说每一个(r,θ)都表示一条经过(x0,y0)直线,那么同一条直线上的点必然会有同样的(r,θ)。如果将某个点所有的(r,θ)绘制成下面的曲线,那么同一条直线上的点的(r,θ)曲线会相交于一点: - ![](http://pic.ex2tron.top/cv2_curve_of_r_theta.jpg) + ![](http://blog.codec.wang/cv2_curve_of_r_theta.jpg) OpenCV中首先计算(r,θ) 累加数,累加数超过一定值后就认为在同一直线上。 @@ -77,7 +77,7 @@ for line in lines: cv2.line(drawing, (x1, y1), (x2, y2), (0, 0, 255)) ``` -![](http://pic.ex2tron.top/cv2_hough_line_function.jpg) +![](http://blog.codec.wang/cv2_hough_line_function.jpg) ### 统计概率霍夫直线变换 @@ -104,7 +104,7 @@ for line in lines: `cv2.LINE_AA`在之前绘图功能中讲解过,表示抗锯齿线型。 -![](http://pic.ex2tron.top/cv2_hough_lines_p_function.jpg) +![](http://blog.codec.wang/cv2_hough_lines_p_function.jpg) ### 霍夫圆变换 @@ -131,7 +131,7 @@ for i in circles[0, :]: cv2.circle(drawing, (i[0], i[1]), 2, (0, 0, 255), 3) # 画出圆心 ``` -![](http://pic.ex2tron.top/cv2_hough_circles_function.jpg) +![](http://blog.codec.wang/cv2_hough_circles_function.jpg) ## 小结 diff --git a/README.md b/README.md index 2a2aa66..a332582 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ - > 抱歉,由于旧域名和服务器到期,新的还在审核中,导致博客图片和链接均失效,预计还需7左右恢复 -## OpenCV-Python图像处理教程(源码及素材) -![](http://pic.ex2tron.top/cv2_python_opencv_cover_gif2.gif) +> 教程地址:[codec.wang](http://codec.wang) + + +## OpenCV-Python图像处理教程(源码及素材) -> 教程地址:[ex2tron's Blog](http://ex2tron.wang) +![](http://blog.codec.wang/cv2_python_opencv_cover_gif2.gif) p.s. 各目录下的README均为教程内容,但Github不支持公式的显示,所以推荐下方的博客链接。 @@ -12,28 +13,28 @@ p.s. 各目录下的README均为教程内容,但Github不支持公式的显示 #### 入门篇 -1. [简介与安装](http://ex2tron.wang/opencv-python-introduction-and-installation/)(了解安装OpenCV-Python) | [番外篇1:代码性能优化](http://ex2tron.wang/opencv-python-extra-code-optimization/) -2. [基本元素-图片](http://ex2tron.wang/opencv-python-basic-element-image/)(图片载入/显示/保存) | [番外篇2:无损保存和Matplotlib使用](http://ex2tron.wang/opencv-python-extra-high-quality-save-and-using-matplotlib/) -3. [打开摄像头](http://ex2tron.wang/opencv-python-open-camera/)(打开摄像头捕获图片/播放保存视频) | [番外篇3:滑动条](http://ex2tron.wang/opencv-python-extra-trackbar/) -4. [图像基本操作](http://ex2tron.wang/opencv-python-basic-operations/)(访问像素点/ROI/通道分离合并/图片属性) -5. [颜色空间转换](http://ex2tron.wang/opencv-python-changing-colorspaces/)(颜色空间转换/追踪特定颜色物体) -6. [阈值分割](http://ex2tron.wang/opencv-python-image-thresholding/)(阈值分割/二值化) | [番外篇4:Otsu阈值法](http://ex2tron.wang/opencv-python-extra-otsu-thresholding/) -7. [图像几何变换](http://ex2tron.wang/opencv-python-image-geometric-transformation/)(旋转/平移/缩放/翻转) | [番外篇5:仿射变换与透视变换](http://ex2tron.wang/opencv-python-extra-warpaffine-warpperspective/) -8. [绘图功能](http://ex2tron.wang/opencv-python-drawing-function/)(画线/画圆/画矩形/添加文字) | [番外篇6:鼠标绘图](http://ex2tron.wang/opencv-python-extra-drawing-with-mouse/) +1. [简介与安装](http://codec.wang/opencv-python-introduction-and-installation/)(了解安装OpenCV-Python) | [番外篇1:代码性能优化](http://codec.wang/opencv-python-extra-code-optimization/) +2. [基本元素-图片](http://codec.wang/opencv-python-basic-element-image/)(图片载入/显示/保存) | [番外篇2:无损保存和Matplotlib使用](http://codec.wang/opencv-python-extra-high-quality-save-and-using-matplotlib/) +3. [打开摄像头](http://codec.wang/opencv-python-open-camera/)(打开摄像头捕获图片/播放保存视频) | [番外篇3:滑动条](http://codec.wang/opencv-python-extra-trackbar/) +4. [图像基本操作](http://codec.wang/opencv-python-basic-operations/)(访问像素点/ROI/通道分离合并/图片属性) +5. [颜色空间转换](http://codec.wang/opencv-python-changing-colorspaces/)(颜色空间转换/追踪特定颜色物体) +6. [阈值分割](http://codec.wang/opencv-python-image-thresholding/)(阈值分割/二值化) | [番外篇4:Otsu阈值法](http://codec.wang/opencv-python-extra-otsu-thresholding/) +7. [图像几何变换](http://codec.wang/opencv-python-image-geometric-transformation/)(旋转/平移/缩放/翻转) | [番外篇5:仿射变换与透视变换](http://codec.wang/opencv-python-extra-warpaffine-warpperspective/) +8. [绘图功能](http://codec.wang/opencv-python-drawing-function/)(画线/画圆/画矩形/添加文字) | [番外篇6:鼠标绘图](http://codec.wang/opencv-python-extra-drawing-with-mouse/) -[**挑战任务:画动态时钟**](http://ex2tron.wang/opencv-python-clock-drawing/) | [**拓展挑战:PyQt5编写GUI界面**](http://ex2tron.wang/opencv-python-using-pyqt5-create-gui/) +[**挑战任务:画动态时钟**](http://codec.wang/opencv-python-clock-drawing/) | [**拓展挑战:PyQt5编写GUI界面**](http://codec.wang/opencv-python-using-pyqt5-create-gui/) #### 基础篇 -1. [图像混合](http://ex2tron.wang/opencv-python-image-blending/)(算数运算/混合/按位运算) | [番外篇7:亮度与对比度](http://ex2tron.wang/opencv-python-extra-contrast-brightness/) -2. [平滑图像](http://ex2tron.wang/opencv-python-smoothing-images/)(卷积/滤波/模糊/降噪) | [番外篇8:卷积基础(图片边框)](http://ex2tron.wang/opencv-python-extra-padding-and-convolution/) -3. [边缘检测](http://ex2tron.wang/opencv-python-edge-detection/)(Canny/Sobel) | [番外篇9:图像梯度](http://ex2tron.wang/opencv-python-extra-image-gradients/) -4. [腐蚀与膨胀](http://ex2tron.wang/opencv-python-erode-and-dilate/)(形态学操作/腐蚀/膨胀/开运算/闭运算) -5. [轮廓](http://ex2tron.wang/opencv-python-contours/) (寻找/绘制轮廓) | [番外篇10:轮廓层级](http://ex2tron.wang/opencv-python-extra-contours-hierarchy/) -6. [轮廓特征](http://ex2tron.wang/opencv-python-contour-features/) (面积/周长/最小外接矩(圆)/形状匹配) | [番外篇11:凸包及更多轮廓特征](http://ex2tron.wang/opencv-python-extra-convex-hull/) -7. [直方图](http://ex2tron.wang/opencv-python-histograms/)(计算绘制直方图/均衡化) -8. [模板匹配](http://ex2tron.wang/opencv-python-template-matching/)(大图中找小图) -9. [ 霍夫变换](http://ex2tron.wang/opencv-python-hough-transform/)(提取直线/圆) - -[**挑战任务:车道检测**](http://ex2tron.wang/opencv-python-lane-road-detection/) +1. [图像混合](http://codec.wang/opencv-python-image-blending/)(算数运算/混合/按位运算) | [番外篇7:亮度与对比度](http://codec.wang/opencv-python-extra-contrast-brightness/) +2. [平滑图像](http://codec.wang/opencv-python-smoothing-images/)(卷积/滤波/模糊/降噪) | [番外篇8:卷积基础(图片边框)](http://codec.wang/opencv-python-extra-padding-and-convolution/) +3. [边缘检测](http://codec.wang/opencv-python-edge-detection/)(Canny/Sobel) | [番外篇9:图像梯度](http://codec.wang/opencv-python-extra-image-gradients/) +4. [腐蚀与膨胀](http://codec.wang/opencv-python-erode-and-dilate/)(形态学操作/腐蚀/膨胀/开运算/闭运算) +5. [轮廓](http://codec.wang/opencv-python-contours/) (寻找/绘制轮廓) | [番外篇10:轮廓层级](http://codec.wang/opencv-python-extra-contours-hierarchy/) +6. [轮廓特征](http://codec.wang/opencv-python-contour-features/) (面积/周长/最小外接矩(圆)/形状匹配) | [番外篇11:凸包及更多轮廓特征](http://codec.wang/opencv-python-extra-convex-hull/) +7. [直方图](http://codec.wang/opencv-python-histograms/)(计算绘制直方图/均衡化) +8. [模板匹配](http://codec.wang/opencv-python-template-matching/)(大图中找小图) +9. [ 霍夫变换](http://codec.wang/opencv-python-hough-transform/)(提取直线/圆) + +[**挑战任务:车道检测**](http://codec.wang/opencv-python-lane-road-detection/) diff --git "a/\346\214\221\346\210\230\344\273\273\345\212\2411\357\274\232\347\224\273\345\212\250\346\200\201\346\227\266\351\222\237/README.md" "b/\346\214\221\346\210\230\344\273\273\345\212\2411\357\274\232\347\224\273\345\212\250\346\200\201\346\227\266\351\222\237/README.md" index e709fce..722a21f 100644 --- "a/\346\214\221\346\210\230\344\273\273\345\212\2411\357\274\232\347\224\273\345\212\250\346\200\201\346\227\266\351\222\237/README.md" +++ "b/\346\214\221\346\210\230\344\273\273\345\212\2411\357\274\232\347\224\273\345\212\250\346\200\201\346\227\266\351\222\237/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程挑战任务:画动态时钟](http://ex2tron.wang/opencv-python-clock-drawing/) -![](http://pic.ex2tron.top/cv2_draw_clock_dynamic_sample.gif) +![](http://blog.codec.wang/cv2_draw_clock_dynamic_sample.gif) 挑战任务:使用OpenCV绘制一个随系统时间动态变化的时钟。 @@ -10,7 +10,7 @@ > **完成如下图所展示的动态时钟,时钟需随系统时间变化,中间显示当前日期。** -![](http://pic.ex2tron.top/cv2_draw_clock_dynamic_sample.gif) +![](http://blog.codec.wang/cv2_draw_clock_dynamic_sample.gif) 其实本次任务涉及的OpenCV知识并不多,但有助于提升大家的编程实践能力。 @@ -24,7 +24,7 @@ 本次挑战任务旨在提升大家的动手实践能力,解决实际问题,所以我们得先有个解题思路和方案。观察下常见的时钟表盘: -![](http://pic.ex2tron.top/cv2_draw_clock_actual_clock_sample.jpg) +![](http://blog.codec.wang/cv2_draw_clock_actual_clock_sample.jpg) 整个表盘其实只有3根表针在动,所以可以先画出静态表盘,然后获取系统当前时间,根据时间实时动态绘制3根表针就解决了。 @@ -50,7 +50,7 @@ img[:] = (255, 255, 255) cv2.circle(img, center, radius, (0, 0, 0), thickness=5) ``` -![](http://pic.ex2tron.top/cv2_draw_clock_blank_circle.jpg) +![](http://blog.codec.wang/cv2_draw_clock_blank_circle.jpg) 前面我们使用OpenCV画直线的时候,需知道直线的起点和终点坐标,那么画72根线就变成了获取72组坐标。 @@ -61,7 +61,7 @@ $$ y=r\times \sin\alpha \end{matrix} $$ -![](http://pic.ex2tron.top/cv2_draw_clock_center_shift.jpg) +![](http://blog.codec.wang/cv2_draw_clock_center_shift.jpg) 先只考虑将坐标系原点移动到左上角,角度依然是平面坐标系中的逆时针计算,那么新坐标是: @@ -74,7 +74,7 @@ $$ 对于60条分/秒刻线,刻线间的夹角是360°/60=6°,对于小时刻线,角度是360°/12=30°,这样就得到了72组起点坐标,那怎么得到终点坐标呢?其实同样的原理,用一个同心的小圆来计算得到B点: -![](http://pic.ex2tron.top/cv2_draw_clock_a_b_position.jpg) +![](http://blog.codec.wang/cv2_draw_clock_a_b_position.jpg) 通过A/B两点就可以画出直线: @@ -105,13 +105,13 @@ for i in range(12): # 到这里基本的表盘图就已经画出来了 ``` -![](http://pic.ex2tron.top/cv2_draw_clock_blank_clock.jpg) +![](http://blog.codec.wang/cv2_draw_clock_blank_clock.jpg) ### 角度换算 接下来算是一个小难点,首先**时钟的起始坐标在正常二维坐标系的90°方向,其次时钟跟图像一样,都是顺时针计算角度的**,所以三者需要统一下: -![](http://pic.ex2tron.top/cv2_draw_clock_different_clock_contrast.jpg) +![](http://blog.codec.wang/cv2_draw_clock_different_clock_contrast.jpg) 因为角度是完全对称的,顺逆时针没有影响,所以平面坐标系完全不用理会,放在这里只是便于大家理解。对于时钟坐标和图像坐标,时钟0的0°对应图像的270°,时钟15的90°对应图像的360°,时钟30的180°对应图像的450°(360°+90°)... @@ -164,7 +164,7 @@ while(1): break ``` -![](http://pic.ex2tron.top/cv2_draw_clock_sample.jpg) +![](http://blog.codec.wang/cv2_draw_clock_sample.jpg) 本此挑战旨在锻炼一步步解决实际问题的思路(虽然有点数学知识( ̄▽ ̄)"),大家再接再厉噢! diff --git "a/\346\214\221\346\210\230\344\273\273\345\212\2412\357\274\232PyQt5\347\274\226\345\206\231GUI\347\225\214\351\235\242/README.md" "b/\346\214\221\346\210\230\344\273\273\345\212\2412\357\274\232PyQt5\347\274\226\345\206\231GUI\347\225\214\351\235\242/README.md" index 7b9fcc4..799b2d6 100644 --- "a/\346\214\221\346\210\230\344\273\273\345\212\2412\357\274\232PyQt5\347\274\226\345\206\231GUI\347\225\214\351\235\242/README.md" +++ "b/\346\214\221\346\210\230\344\273\273\345\212\2412\357\274\232PyQt5\347\274\226\345\206\231GUI\347\225\214\351\235\242/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程拓展挑战:PyQt编写GUI界面](http://ex2tron.wang/opencv-python-using-pyqt5-create-gui/) -![](http://pic.ex2tron.top/cv2_pyqt_gui_sample.jpg) +![](http://blog.codec.wang/cv2_pyqt_gui_sample.jpg) 拓展挑战:编写GUI图像处理应用程序。 @@ -12,7 +12,7 @@ > **了解Python编写[GUI](https://baike.baidu.com/item/GUI)界面的方法,使用PyQt5编写如下的图像处理应用程序,实现打开摄像头、捕获图片、读取本地图片、灰度化和Otsu自动阈值分割的功能。** -![](http://pic.ex2tron.top/cv2_pyqt_gui_sample.jpg) +![](http://blog.codec.wang/cv2_pyqt_gui_sample.jpg) **挑战题不会做也木有关系,但请务必在自行尝试后,再看下面的解答噢,**不然...我也没办法( ̄▽ ̄)" @@ -69,19 +69,19 @@ if __name__ == '__main__': sys.exit(app.exec_()) ``` -![](http://pic.ex2tron.top/cv2_pyqt5_hello_world_sample.jpg) +![](http://blog.codec.wang/cv2_pyqt5_hello_world_sample.jpg) ### 界面设计 根据我们的挑战内容,解决思路是使用Qt Designer来设计界面,使用Python完成代码逻辑。打开designer.exe,会弹出创建新窗体的窗口,我们直接点击“create”: -![](http://pic.ex2tron.top/cv2_pyqt5_designer_main_ui.jpg) +![](http://blog.codec.wang/cv2_pyqt5_designer_main_ui.jpg) 界面的左侧是Qt的常用控件"Widget Box",右侧有一个控件属性窗口"Property Editor",其余暂时用不到。本例中我们只用到了"Push Button"控件和"Label"控件:最上面的三个Label控件用于显示图片,可以在属性窗口调整它的大小,我们统一调整到150×150: -![](http://pic.ex2tron.top/cv2_pyqt5_main_ui_rough.jpg) +![](http://blog.codec.wang/cv2_pyqt5_main_ui_rough.jpg) -![](http://pic.ex2tron.top/cv2_pyqt5_designer_property_windows.jpg) +![](http://blog.codec.wang/cv2_pyqt5_designer_property_windows.jpg) 另外,控件上显示的文字"text"属性和控件的名字"objectName"属性需要修改,便于显示和代码调用。可以按照下面我推荐的命名: @@ -98,7 +98,7 @@ if __name__ == '__main__': 这样大致界面就出来了,很简单: -![](http://pic.ex2tron.top/cv2_pyqt5_main_ui_word.jpg) +![](http://blog.codec.wang/cv2_pyqt5_main_ui_word.jpg) ### 按钮事件 @@ -106,19 +106,19 @@ if __name__ == '__main__': 点击Designer工具栏的"Edit Signals/Slots"按钮,进入槽函数编辑界面,点击旁边的"Edit Widgets"可以恢复正常视图: -![](http://pic.ex2tron.top/cv2_pyqt5_designer_edit_singals_slots.jpg) +![](http://blog.codec.wang/cv2_pyqt5_designer_edit_singals_slots.jpg) 然后点击按钮并拖动,当产生类似于电路中的接地符号时释放鼠标,参看下面动图: -![](http://pic.ex2tron.top/cv2_pyqt5_how_to_create_slots.gif) +![](http://blog.codec.wang/cv2_pyqt5_how_to_create_slots.gif) 在弹出的配置窗口中,可以看到左侧是按钮的常用事件,我们选择点击事件"clicked()",然后添加一个名为"btnOpenCamera_Clicked()"的槽函数: -![](http://pic.ex2tron.top/cv2_pyqt5_how_to_create_slots2.gif) +![](http://blog.codec.wang/cv2_pyqt5_how_to_create_slots2.gif) 重复上面的步骤,给五个按钮添加五个槽函数,最终结果如下: -![](http://pic.ex2tron.top/cv2_pyqt5_main_click_event.jpg) +![](http://blog.codec.wang/cv2_pyqt5_main_click_event.jpg) 到此,我们就完成了界面设计的所有工作,按下Ctrl+S保存当前窗口为.ui文件。.ui文件其实是按照XML格式标记的内容,可以用文本编辑器将.ui文件打开看看。 @@ -128,7 +128,7 @@ if __name__ == '__main__': 打开cmd命令行,切换到ui文件的保存目录。Windows下有个小技巧,可以在目录的地址栏输入cmd,一步切换到当前目录: -![](http://pic.ex2tron.top/cv2_pyqt5_pyuic_quick_cmd.gif) +![](http://blog.codec.wang/cv2_pyqt5_pyuic_quick_cmd.gif) 然后执行这条指令: @@ -273,7 +273,7 @@ if __name__ == "__main__": sys.exit(app.exec_()) ``` -![](http://pic.ex2tron.top/cv2_pyqt_gui_sample2.jpg) +![](http://blog.codec.wang/cv2_pyqt_gui_sample2.jpg) 本文只是抛砖引玉,介绍了PyQt5的简单使用,想要深入学习,可以参考本文开头的参考资料噢(●ˇ∀ˇ●) diff --git "a/\346\214\221\346\210\230\344\273\273\345\212\2413\357\274\232\350\275\246\351\201\223\346\243\200\346\265\213/README.md" "b/\346\214\221\346\210\230\344\273\273\345\212\2413\357\274\232\350\275\246\351\201\223\346\243\200\346\265\213/README.md" index 8ee097e..308ae8e 100644 --- "a/\346\214\221\346\210\230\344\273\273\345\212\2413\357\274\232\350\275\246\351\201\223\346\243\200\346\265\213/README.md" +++ "b/\346\214\221\346\210\230\344\273\273\345\212\2413\357\274\232\350\275\246\351\201\223\346\243\200\346\265\213/README.md" @@ -1,6 +1,6 @@ # [OpenCV-Python教程挑战任务:车道检测](http://ex2tron.wang/opencv-python-lane-road-detection/) -![](http://pic.ex2tron.top/cv2_lane_detection_result_sample.jpg) +![](http://blog.codec.wang/cv2_lane_detection_result_sample.jpg) 挑战任务:实际公路的车道线检测。图片等可到[源码处](#引用)下载。 @@ -10,11 +10,11 @@ > **1. 在所提供的公路图片上检测出车道线并标记:** -![](http://pic.ex2tron.top/cv2_lane_detection_result_sample.jpg) +![](http://blog.codec.wang/cv2_lane_detection_result_sample.jpg) > **2. 在所提供的公路视频上检测出车道线并标记:** -