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), 欢迎大家关注哦~

原文:https://www.cnblogs.com/jclian91/p/9728488.html

原文地址:https://www.cnblogs.com/Ph-one/p/12080410.html

时间: 2024-11-01 20:47:29

OpenCV入门之寻找图像的凸包(convex hull)的相关文章

opencv笔记(二十四)——得到轮廓之后找到凸包convex hull

当我们得到一张轮廓之后,我们可以对其运用convexHull方法,寻找该轮廓的凸包. 一个轮廓可以有无数个包围它的外壳,而其中表面积最小的一个外壳,就是凸包. void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true ) points是一个contour. vector<Point>类型或者Mat类型 hull是输出,也是一个点集vector<Poin

OpenCV入门教程之七 图像滤波

滤波实际上是信号处理里的一个概念,而图像本身也可以看成是一个二维的信号.其中像素点灰度值的高低代表信号的强弱. 高频:图像中灰度变化剧烈的点. 低频:图像中平坦的,灰度变化不大的点. 根据图像的高频与低频的特征,我们可以设计相应的高通与低通滤波器,高通滤波可以检测图像中尖锐.变化明显的地方:低通滤波可以让图像变得光滑,滤除图像中的噪声. 一.低通滤波 1,blur函数 这个函数是一个平滑图像的函数,它用一个点邻域内像素的平均灰度值来代替该点的灰度. cv::blur(image,result,c

OpenCV入门教程之四 图像直方图

一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比. 图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征.在实际工程中,图像直方图在特征提取.图像匹配等方面都有很好的应用.  二.利用OpenCV计算图像的直方图 OpenCV中计算图像直方图像函数是calcHist,它的参数比较多,下面分析一下它的接口和用法. void calc

OpenCV入门教程之五 图像直方图的应用

正如第4篇文章所说的图像直方图在特征提取方面有着很重要的作用,本文将举两个实际工程中非常实用的例子来说明图像直方图的应用. 一.直方图的反向映射 我们以人脸检测举例,在人脸检测中,我们第一步往往需要先提取图像中皮肤区域来缩小人脸的检测范围,这一般获得皮肤的颜色范围还需要定义阈值并不断的调整,实际中参数太多而不容易控制. 这里我们就可以考虑用直方图的反射映射. 1,收集人脸皮肤样本. 2,拼合样本并计算其颜色直方图. 3,将得到的样本颜色直方图反射映射到待检测的图片中,然后进行阈值化即可. 这里为

25、【opencv入门】轮廓查找与绘制(3)——凸包

一简介 1.凸包 凸包(Convex Hull)是一个计算机几何图形学中的概念, 简单来说, 给定二维平面点集, 凸包就是能够将最外层的点连接起来构成的凸多边形, 它能够包含点集中所有的点.物体的凸包检测场应用在物体识别.手势识别及边界检测等领域. A-H是被标出的凸包缺陷 2.寻找凸包---convexHull() 1 CV_EXPORTS_W void convexHull(InputArray points, OutputArray hull, bool clockwise=false,

【OpenCV入门教程之三】 图像的载入,显示和输出 一站式完全解析

了解过之前老版本OpenCV的童鞋们都应该清楚,对于OpenCV1.0时代的基于 C 语言接口而建的图像存储格式IplImage*,如果在退出前忘记release掉的话,就会造成内存泄露.而且用起来超级麻烦,我们往往在debug的时候,很大一部分时间在纠结手动释放内存的问题.虽然对于小型的程序来说手动管理内存不是问题,但一旦我们写的代码变得越来越庞大,我们便会开始越来越多地纠缠于内存管理的问题,而不是着力解决你的开发目标. 这,就有些舍本逐末的感觉了. 而自从OpenCV踏入2.0时代,用Mat

【OpenCV入门教程之四】 ROI区域图像叠加&amp;初级图像混合 全剖析(转)

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/20911629 作者:毛星云(浅墨)    邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.8 在这篇文章里,我们一起学习了在OpenCV中如何定义感兴趣区域ROI,如何使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像

【OpenCV入门教程之六】 创建Trackbar &amp; 图像对比度、亮度值调整(转)

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/21479533 作者:毛星云(浅墨)    邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本: 2.4.8 这篇文章中我们一起学习了如何在OpenCV中用createTrackbar函数创建和使用轨迹条,以及图像对比度.亮度值的动态调整. 文章首先详细讲解了OpenCV2.0中的新版创建轨迹条的函数c

opencv ,亮度调整【【OpenCV入门教程之六】 创建Trackbar &amp; 图像对比度、亮度值调整

http://blog.csdn.net/poem_qianmo/article/details/21479533 [OpenCV入门教程之六] 创建Trackbar & 图像对比度.亮度值调整 标签: opencvvs2010c++图像处理 2014-03-18 21:43 43189人阅读 评论(99) 收藏 举报  分类: [OpenCV](18)  目录(?)[+] 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qian