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的ORM框架SQLAlchemy入门教程
Apr 28 Python
python使用正则表达式检测密码强度源码分享
Jun 11 Python
Python使用pickle模块存储数据报错解决示例代码
Jan 26 Python
django初始化数据库的实例
May 27 Python
python组合无重复三位数的实例
Nov 13 Python
Python中fnmatch模块的使用详情
Nov 30 Python
Python实现的调用C语言函数功能简单实例
Mar 13 Python
python实现手机销售管理系统
Mar 19 Python
python定时按日期备份MySQL数据并压缩
Apr 19 Python
python爬虫 批量下载zabbix文档代码实例
Aug 21 Python
python之yield和Generator深入解析
Sep 18 Python
Python confluent kafka客户端配置kerberos认证流程详解
Oct 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
浅析PKI加密解密 OpenSSL
2013/07/01 PHP
php中mysql连接和基本操作代码(快速测试使用,简单方便)
2014/04/25 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
php使用COPY函数更新配置文件的方法
2015/06/18 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
2020/04/06 PHP
jQuery实现的立体文字渐变效果
2010/05/17 Javascript
jquery 操作日期、星期、元素的追加的实现代码
2012/02/07 Javascript
javascript 文件的同步加载与异步加载实现原理
2012/12/13 Javascript
js 输出内容到新窗口具体实现代码
2013/05/31 Javascript
JS实现当前页居中分页效果的方法
2015/06/18 Javascript
js实现无限级树形导航列表效果代码
2015/09/23 Javascript
微信jssdk在iframe页面失效问题的解决措施
2016/03/03 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
Vue 与 Vuex 的第一次接触遇到的坑
2018/08/16 Javascript
layui 设置table 行的高度方法
2018/08/17 Javascript
layUI使用layer.open,在content打开数据表格,获取值并返回的方法
2019/09/26 Javascript
[03:38]2014DOTA2西雅图国际邀请赛 VG战队巡礼
2014/07/07 DOTA
Python访问MySQL封装的常用类实例
2014/11/11 Python
把MySQL表结构映射为Python中的对象的教程
2015/04/07 Python
Unicode和Python的中文处理
2017/03/19 Python
基于python元祖与字典与集合的粗浅认识
2017/08/23 Python
python的unittest测试类代码实例
2017/12/07 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
Django使用中间件解决前后端同源策略问题
2019/09/02 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
pytorch 批次遍历数据集打印数据的例子
2019/12/30 Python
CSS3解析抖音LOGO制作的方法步骤
2019/04/11 HTML / CSS
ProBikeKit德国:在线公路自行车专家
2018/06/03 全球购物
QA工程师岗位职责
2013/11/20 职场文书
就业自荐信
2013/12/04 职场文书
物流专员岗位职责
2014/02/17 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
宫崎骏十大动画电影,宫崎骏好看的动画电影排名
2022/03/22 日漫