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中用于去除空格的三个函数的使用小结
Apr 07 Python
python创建一个最简单http webserver服务器的方法
May 08 Python
python开发利器之ulipad的使用实践
Mar 16 Python
Python实现基于PIL和tesseract的验证码识别功能示例
Jul 11 Python
Python使用sax模块解析XML文件示例
Apr 04 Python
一篇文章彻底搞懂Python中可迭代(Iterable)、迭代器(Iterator)与生成器(Generator)的概念
May 13 Python
Ubuntu18.04下python版本完美切换的解决方法
Jun 14 Python
django自带serializers序列化返回指定字段的方法
Aug 21 Python
利用python生成照片墙的示例代码
Apr 09 Python
Python3自定义json逐层解析器代码
May 11 Python
python中delattr删除对象方法的代码分析
Dec 15 Python
python实现excel公式格式化的示例代码
Dec 23 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中Memcache操作类及用法实例
2014/12/12 PHP
PHPExcel内存泄漏问题解决方法
2015/01/23 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
Laravel4中的Validator验证扩展用法详解
2016/07/26 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
javascript iframe内的函数调用实现方法
2009/07/19 Javascript
js实现上传图片预览的方法
2015/02/09 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
2015/10/22 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
解析Javascript单例模式概念与实例
2016/12/05 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
vue2.0 axios前后端数据处理实例代码
2017/06/30 Javascript
bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)
2017/11/17 Javascript
vue+mousemove实现鼠标拖动功能(拖动过快失效问题解决方法)
2018/08/24 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
[02:40]DOTA2英雄基础教程 先知
2013/11/29 DOTA
[02:57]DOTA2英雄基础教程 风行者
2014/01/16 DOTA
使用Python的web.py框架实现类似Django的ORM查询的教程
2015/05/02 Python
Python中列表、字典、元组数据结构的简单学习笔记
2016/03/20 Python
python实现各进制转换的总结大全
2017/06/18 Python
Pycharm 设置自定义背景颜色的图文教程
2018/05/23 Python
详解pandas的外部数据导入与常用方法
2019/05/01 Python
python处理document文档保留原样式
2019/09/23 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
Python实现捕获异常发生的文件和具体行数
2020/04/25 Python
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
食品行业求职人的自我评价
2014/01/19 职场文书
幼儿园开学家长寄语
2014/01/19 职场文书
条幅标语大全
2014/06/20 职场文书
限期整改通知书
2015/04/22 职场文书
中秋晚会致辞
2015/07/31 职场文书
培训心得体会怎么写
2016/01/25 职场文书
七年级作文之秋游
2019/10/21 职场文书
详解Oracle块修改跟踪功能
2021/11/07 Oracle
使用SQL实现车流量的计算的示例代码
2022/02/28 SQL Server
delete in子查询不走索引问题分析
2022/07/07 MySQL