OpenCV入门之寻找图像的凸包(convex hull)
介绍
凸包(Convex Hull)是一个计算几何(图形学)中的概念,它的严格的数学定义为:在一个向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。
在图像处理过程中,我们常常需要寻找图像中包围某个物体的凸包。凸包跟多边形逼近很像,只不过它是包围物体最外层的一个凸集,这个凸集是所有能包围这个物体的凸集的交集。如下图所示:

在上图中,绿色线条所包围的凸集即为白色图形的凸包。
在opencv中,通过函数convexHulll能很容易的得到一系列点的凸包,比如由点组成的轮廓,通过convexHull函数,我们就能得到轮廓的凸包。寻找图像的凸包,能够让我们做一些有意思的事情,比如手势识别等。
下面笔者将会通过两个简单例子来展示如何用OpenCV来寻找图像的凸包。
简单例子1 几何图形
首先,我们用以下的Python代码来自己绘制一张简单的多边形的图片(polygon.png),代码如下:
import cv2
import numpy as np
# 新建512*512的空白图片
img = np.zeros((512,512,3), np.uint8)
# 平面点集
pts = np.array([[200,250], [250,300], [300, 270], [270,200], [120, 240]], np.int32)
pts = pts.reshape((-1,1,2))
# 绘制填充的多边形
cv2.fillPoly(img, [pts], (255,255,255))
# 保存图片
cv2.imwrite('F://polygon.png', img)
绘制的图片如下:

接着我们需要寻找这个多边形的凸包,利用OpenCV的convexHull函数,然后再将这个凸包绘制出来,得到直观的展示结果。处理的Python代码如下:
import cv2
# 读取图片并转至灰度模式
imagepath = 'F://convex.png'
img = cv2.imread(imagepath, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 图片轮廓
image, contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]
# 寻找凸包并绘制凸包(轮廓)
hull = cv2.convexHull(cnt)
print(hull)
length = len(hull)
for i in range(len(hull)):
cv2.line(img, tuple(hull[i][0]), tuple(hull[(i+1)%length][0]), (0,255,0), 2)
# 显示图片
cv2.imshow('line', img)
cv2.waitKey()
输出的结果如下:
[[[300 270]]
[[299 271]]
[[254 298]]
[[250 300]]
[[120 240]]
[[122 239]]
[[257 203]]
[[269 200]]
[[270 200]]
[[273 206]]
[[300 269]]]
这是凸包所在的轮廓的点集集合,有了它,我们就能绘制出凸包的轮廓了,如下:

简单例子2 手势图片
接下来,我们将介绍一张稍微难一点的图片——手势图片(finger.jpg),如下所示:

我们将会来寻找这个手势的凸包。基本的处理思路还是和之前的一致,只是要在二值化以及凸包点集集合的大小上做一些处理,取二值化的阈值为235,凸包点集中的点个数大于5,完整的Python代码如下:
import cv2
# 读取图片并转至灰度模式
imagepath = 'F://finger.jpg'
img = cv2.imread(imagepath, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取阈值为235
ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 寻找图像中的轮廓
image, contours, hierarchy = cv2.findContours(thresh, 2, 1)
# 寻找物体的凸包并绘制凸包的轮廓
for cnt in contours:
hull = cv2.convexHull(cnt)
length = len(hull)
# 如果凸包点集中的点个数大于5
if length > 5:
# 绘制图像凸包的轮廓
for i in range(length):
cv2.line(img, tuple(hull[i][0]), tuple(hull[(i+1)%length][0]), (0,0,255), 2)
cv2.imshow('finger', img)
cv2.waitKey()
检测到的凸包如下图所示:

可以发现,一共检测到2个凸包,一个是整个手势外围的凸包,正好包围整个手,另一个是两个手指形成的内部的图形,类似于O的凸包,这符合我们的预期。
总结
当然,我们在这里只是介绍了OpenCV检测凸包的函数convexHull以及其应用,并没有讲到如何检测凸包的算法。如有机会,笔者将会介绍该算法。欢迎大家交流,祝大家国庆快乐!
注意:本人现已开通微信公众号: 轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~
OpenCV入门之寻找图像的凸包(convex hull)的更多相关文章
- opencv::凸包-Convex Hull
概念介绍 什么是凸包(Convex Hull),在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部. 正式定义:包含点集合S中所有点的最小凸多边形称为凸包 Graham扫描算法 首先选 ...
- opencv 6 图像轮廓与图像分割修复 1 查找并绘制轮廓 寻找物体的凸包
查找并绘制轮廓 寻找轮廓(findContours)函数 绘制轮廓(drawContours()函数) 基础实例程序:轮廓查找 #include <opencv2/opencv.hpp> ...
- 寻找物体的凸包 opencv
凸包的含义: 在二维平面上给定点集,凸包就是将最外层的点连接起来构成的凸多边形.并且这个凸多边形能包含点集中所有的点.OPENCV中: convexHull函数用于寻找图像点集中的凸包.它有六个输入参 ...
- 【OpenCV入门教程之三】 图像的载入,显示和输出 一站式完全解析(转)
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/20537737 作者:毛星云(浅墨) ...
- opencv ,亮度调整【【OpenCV入门教程之六】 创建Trackbar & 图像对比度、亮度值调整
http://blog.csdn.net/poem_qianmo/article/details/21479533 [OpenCV入门教程之六] 创建Trackbar & 图像对比度.亮度值调 ...
- [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...
- 【OpenCV入门指南】第一篇 安装OpenCV
http://blog.csdn.net/morewindows/article/details/8225783/ win10下vs2015配置Opencv3.1.0过程详解(转) http://ww ...
- OpenCV入门学习笔记
OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...
随机推荐
- uva12307(旋转卡壳)
省选前练模板系列 #include<iostream> #include<cmath> #include<cstdio> #include<cstring&g ...
- python opencv 处理文件、摄像头、图形化界面
转换成RGB import cv2 import numpy as ny img = ny.zeros( ( 3 , 3 ),ny.float32) img=cv2.cvtColor(img,cv2. ...
- HDU1262-寻找素数对
//#include<bits/stdc++.h> #include<map> #include<cstdio> #include<string> #i ...
- Linux 搜某个文件里关键字的上下500行到执行文件里
Linux 搜某个文件里关键字的上下500行到执行文件里grep '300000111110' -C 500 ./saastom7061_APP3/logs/sass.log >/app/saa ...
- bash基础特性3(shell编程)
Linux上文本处理三剑客: grep:文本过滤工具 sed:stream editor,文本编辑工具 awk:文本报告生成器 grep -v:显示不能够被pattern匹配到的行 -i:忽略字符大小 ...
- 【转载】关于.NET下开源及商业图像处理(PSD)组件
原创]关于.NET下开源及商业图像处理(PSD)组件 阅读目录 1 前言 2 .NET图像处理组件总结 3.相关资源网址 本博客所有文章分类的总目录:http://www.cnblo ...
- spark-submit(spark版本2.4.2)
spark-submit官方文档 :http://spark.apache.org/docs/latest/submitting-applications.html Launching Applica ...
- 子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践
本文原文内容来自InfoQ的技术分享,本次有修订.勘误和加工,感谢原作者的分享. 1.前言 自从2018年8月20日子弹短信在锤子发布会露面之后(详见<老罗最新发布了“子弹短信”这款IM,主打熟 ...
- 致我们再也回不去的 Github ...
本文原文来自公众号 stormzhang,原作者自称“二流学校毕业.非科班出身.从 0 自学编程到现在的「段子张」”. 1.前言 相信大家都知道了,微软已确认要收购 GitHub 了,Github ...
- PopupWindow 以及拍照、裁剪
实现这样的效果 圆角图片的自定义控件直接拷进来,和com一个等级 想要弹出内容可以使用悬浮窗 layout_pupup <LinearLayout xmlns:android="htt ...