opencv 图像轮廓的实现示例


Posted in Python onJuly 08, 2020

图像轮廓

Contours:轮廓
轮廓是将没有连着一起的边缘连着一起。
边缘检测检测出边缘,边缘有些未连接在一起。

opencv 图像轮廓的实现示例

注意问题
1.对象为二值图像,首先进行阈值分割或者边缘检测。
2.查找轮廓需要更改原始图像,通常使用原始图像的一份进行拷贝。
3.在opencv里,是从黑色背景里找白色。因此对象必须是白色,背景为黑色。

方法

  • cv2.findContours()
  • cv2.drawContours()

通过cv2.findContours() 查找轮廓在哪里,再通过 cv2.drawContours()将查找的轮廓绘制出来。

contours,hierarchy=cv2.findContours(image,mode,method)
contours:轮廓
hierarchy:图像的拓扑信息(轮廓层次)(存储上一个轮廓,父轮廓…)
image:原始图像
mode:轮廓检索方式
method:轮廓的近似方法

opencv 图像轮廓的实现示例

opencv 图像轮廓的实现示例

r=cv2.drawContours(image, contours, contourIdx, color[, thickness])

r:目标图像
image:原始图像
contours: 所有的输入轮廓边缘数组
contourIdx :需要绘制的边缘索引,如果全部绘制为-1。如果有多个目标,可以绘制第一个目标0,第二个目标1,第三个目标2.。。
color:绘制的颜色,为BGR格式的SCalar
thickness:可选,绘制的密度,即轮廓的画笔粗细

import cv2
import numpy as np
o = cv2.imread('lena256.bmp')
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)#BGR-灰度
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#二值图像
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
co=o.copy()#对原始图像进行绘制
r=cv2.drawContours(co,contours,-1,(0,127,127),4)#co为复制图像,轮廓会修改原始图像
cv2.imshow("original",o)
cv2.imshow("contours",r)
cv2.waitKey()

opencv 图像轮廓的实现示例

cv2.cvtColor(input_image, flag)用于颜色空间转换。
input_image:需要转换的图像
flag:转换类型
cv2.COLOR_BGR2GRAY : BGR -灰度
cv2.COLOR_BGR2RGB:BGR-RGB
cv2.COLOR_BGR2HSV:BGR-HSV

最小外接圆

函数cv2.minEnclosingCircle() 可以帮我们找到一个对象的外切圆。它是所有能够包括对象的圆中面积最小的一个。

案例:现有下面这样一张图片,要求将图片中心的花朵标记出来。

opencv 图像轮廓的实现示例

代码:

import numpy as np
import cv2 as cv

img=cv.imread("image.jpg",0)

#为了显示方便,这里将图片进行缩放
x,y=img.shape
img=cv.resize(img,(y//2,x//2))
#将图片二值化,由于前景物体是黑色的,因此在二值化时采用cv.THRESH_TOZERO_INV这种方式
ret,thresh=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
#寻找图片中的轮廓,mode=cv.RETR_EXTERNAL,这是为了寻找最外层的轮廓
im,contour,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)

#cv.minEnclosingCircle函数的参数要求是ndarray类型,因此这里将找到的
# 轮廓中的所有的点存放在一个列表中,然后使用这个列表创建数组
point_list=[]
for i in contour:
  for j in i:
    point_list.append(j[0])
point_array=np.array(point_list)

#使用最小外接圆函数,返回值为这个圆的圆心坐标和圆半径长度
(x,y),radius=cv.minEnclosingCircle(point_array)

#图片上的坐标均为整数,圆的半径也要求是整数,因此将它们强制转换为int类型
center=(int(x),int(y))
color=cv.cvtColor(img,cv.COLOR_GRAY2BGR)
color=cv.circle(color,center,radius=int(radius),color=(0,0,255),thickness=2)
#显示图片
cv.imshow("color",color)
cv.waitKey(0)
cv.destroyAllWindows()

程序结果:

opencv 图像轮廓的实现示例

凸包

凸包与轮廓近似相似,但不同,虽然有些情况下它们给出的结果是一样的。函数cv2.convexHull() 可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷。一般来说,凸性曲线总是凸出来的,至少是平的。在opencv中使用函数cv.convexhull来寻找轮廓的凸包,该函数的定义为:

hull=cv.convexHull( points[, hull[, clockwise[, returnPoints]]])

这个函数的参数如下:

Points:我们需要传入的轮廓

Hull:输出,通常不需要

clockwise: 取向标志,如果为True,凸包的方向是顺时针方向,否则为逆时针方向;

returnPoints: 默认为True. 它会返回凸包上点的坐标。如果设置为False,就会返回与凸包点对应的轮廓上的点。

还是上面的这副图片,我们对上面的代码稍加修改,可以得到凸包的形状,代码如下:

import numpy as np
import cv2 as cv

img=cv.imread("image.jpg",0)

#为了显示方便,这里将图片进行缩放
x,y=img.shape
img=cv.resize(img,(y//2,x//2))
#将图片二值化,由于前景物体是黑色的,因此在二值化时采用cv.THRESH_TOZERO_INV这种方式
ret,thresh=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
#寻找图片中的轮廓,mode=cv.RETR_EXTERNAL,这是为了寻找最外层的轮廓
im,contour,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)

#cv.minEnclosingCircle函数的参数要求是ndarray类型,因此这里将找到的
# 轮廓中的所有的点存放在一个列表中,然后使用这个列表创建数组
point_list=[]
for i in contour:
  for j in i:
    point_list.append(j[0])
point_array=np.array(point_list)

#寻找凸包,返回值是凸包上的点
hull=cv.convexHull(point_array,returnPoints=True)
color=cv.cvtColor(img,cv.COLOR_GRAY2BGR)

#将凸包绘制出来,需要注意的是:这里需要将凸包上点的坐标写成一个
#列表传入函数cv.ploylines,否则绘制出来的只是凸包上的一系列点
color=cv.polylines(color,[hull],True,(0,0,255),2)
#显示图片
cv.imshow("color",color)
cv.waitKey(0)
cv.destroyAllWindows()

程序运行结果为:

opencv 图像轮廓的实现示例

图像掩模和像素点

有时我们需要构成对象的所有像素点,我们可以将图像的所有轮廓提取出来,然后使用函数cv.drawContours()将轮廓内的区域填充为指定的颜色。然后使用cv.findNonZeros()函数将非零像素点的坐标提取出来,这样就得到了构成对象的像素点。我们还是在上面的图片上进行操作,代码如下:

import numpy as np
import cv2 as cv

img=cv.imread("image.jpg",0)

#为了显示方便,这里将图片进行缩放
x,y=img.shape
img=cv.resize(img,(y//2,x//2))
#将图片二值化,由于前景物体是黑色的,因此在二值化时采用cv.THRESH_TOZERO_INV这种方式
ret,thresh=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
#寻找图片中的轮廓,mode=cv.RETR_EXTERNAL,这是为了寻找最外层的轮廓
im,contour,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
#创建一个填充轮廓内像素点的画板,背景颜色为黑色,这里我们使用numpy创建一个全零的二维数组
mask=np.zeros(img.shape,dtype=np.uint8)
#将参数thickness设置为-1,这样cv.drawContours函数就会将轮廓内的像素点填充为指定的颜色
mask=cv.drawContours(mask,contour,contourIdx=-1,color=(255,255,255),thickness=-1)

#寻找mask内非零像素点,将其存放为一个numpy数组
NonZeroPoints=np.array(cv.findNonZero(mask))
#形状变换,将其改变为一个二维数组,数组的每一行存放一个非零像素点的坐标
NonZeroPoints=NonZeroPoints.reshape((-1,2))
#验证我们提取出来的像素点坐标是否正确,我们使用变量
#column和row分别存放非零像素点在图像中坐标的列数和行数
column=NonZeroPoints[:,0]
row=NonZeroPoints[:,1]
#在新的画板上将这些点绘制出来,将这些坐标对应的像素点的值设为255
mask1=np.zeros(img.shape)
mask1[row,column]=255
#显示结果
cv.imshow("mask",mask)
cv.imshow("mask1",mask1)
cv.waitKey(0)
cv.destroyAllWindows()

程序运行结果:

opencv 图像轮廓的实现示例

通过上面两幅图的对比结果,我们可以看到:对象的组成像素点被正确地提取出来了。

到此这篇关于opencv 图像轮廓的实现示例的文章就介绍到这了,更多相关opencv 图像轮廓内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
详解Python中with语句的用法
Apr 15 Python
python分割列表(list)的方法示例
May 07 Python
python中列表和元组的区别
Dec 18 Python
Face++ API实现手势识别系统设计
Nov 21 Python
Django 框架模型操作入门教程
Nov 05 Python
python单向循环链表原理与实现方法示例
Dec 03 Python
Python多线程thread及模块使用实例
Apr 28 Python
如何实现更换Jupyter Notebook内核Python版本
May 18 Python
python中如何写类
Jun 29 Python
python装饰器三种装饰模式的简单分析
Sep 04 Python
Python可变集合和不可变集合的构造方法大全
Dec 06 Python
Python socket如何解析HTTP请求内容
Feb 12 Python
opencv 图像滤波(均值,方框,高斯,中值)
Jul 08 #Python
用opencv给图片换背景色的示例代码
Jul 08 #Python
python文件及目录操作代码汇总
Jul 08 #Python
Python预测2020高考分数和录取情况
Jul 08 #Python
Python venv虚拟环境配置过程解析
Jul 08 #Python
Python如何实现自带HTTP文件传输服务
Jul 08 #Python
Python第三方包PrettyTable安装及用法解析
Jul 08 #Python
You might like
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
详解PHP函数 strip_tags 处理字符串缺陷bug
2017/06/11 PHP
PHP更安全的密码加密机制Bcrypt详解
2017/06/18 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
javascript天然的迭代器
2010/10/29 Javascript
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
JavaScript实现页面实时显示当前时间的简单实例
2013/07/20 Javascript
javascript中2个感叹号的用法实例详解
2014/09/04 Javascript
JavaScript实现检查页面上的广告是否被AdBlock屏蔽了的方法
2014/11/03 Javascript
使用AOP改善javascript代码
2015/05/01 Javascript
jQuery遍历json的方法(推荐)
2016/06/12 Javascript
简单理解vue中track-by属性
2016/10/26 Javascript
JavaScript判断浏览器对CSS3属性是否支持的多种方法
2016/11/13 Javascript
微信小程序进行微信支付的步骤昂述
2016/12/01 Javascript
puppeteer实现html截图的示例代码
2019/01/10 Javascript
jquery 键盘事件 keypress() keydown() keyup()用法总结
2019/10/23 jQuery
vue2.0 解决抽取公用js的问题
2020/07/31 Javascript
[37:50]VP vs TNC Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
Python中的列表知识点汇总
2015/04/14 Python
Python中生成器和yield语句的用法详解
2015/04/17 Python
详解Python的Lambda函数与排序
2016/10/25 Python
[原创]python爬虫(入门教程、视频教程)
2018/01/08 Python
对python中的logger模块全面讲解
2018/04/28 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
在python中计算ssim的方法(与Matlab结果一致)
2019/12/19 Python
详解px单位html5响应式方案
2018/03/08 HTML / CSS
澳大利亚领先的在线礼品网站:Gifts Australia
2020/08/15 全球购物
联强国际笔试题面试题
2013/07/10 面试题
中介业务员岗位职责
2014/04/09 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
公民授权委托书范本
2014/09/17 职场文书
个人纪律作风整改措施思想汇报
2014/10/12 职场文书
2015人事行政工作总结范文
2015/05/21 职场文书
致三级跳运动员加油稿
2015/07/21 职场文书
2019通用版劳动合同范本!
2019/07/11 职场文书