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中请使用isinstance()判断变量类型
Aug 25 Python
举例讲解Python设计模式编程中对抽象工厂模式的运用
Mar 02 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
Jan 14 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
Mar 01 Python
python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例
Jun 17 Python
用Python爬取QQ音乐评论并制成词云图的实例
Aug 24 Python
python 类之间的参数传递方式
Dec 20 Python
Python3使用xlrd、xlwt处理Excel方法数据
Feb 28 Python
基于Python实现体育彩票选号器功能代码实例
Sep 16 Python
Python通过类的组合模拟街道红绿灯
Sep 16 Python
Python 利用argparse模块实现脚本命令行参数解析
Dec 28 Python
python邮件中附加文字、html、图片、附件实现方法
Jan 04 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 数学运算验证码实现代码
2009/10/11 PHP
php去除头尾空格的2种方法
2015/03/16 PHP
PHP实现获取并生成数据库字典的方法
2016/05/04 PHP
Laravel中的Auth模块详解
2017/08/17 PHP
新手入门常用代码集锦
2007/01/11 Javascript
JavaScript confirm选择判断
2008/10/18 Javascript
关于全局变量和局部变量的那些事
2013/01/11 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
jQuery移动端日期(datedropper)和时间(timedropper)选择器附源码下载
2016/04/19 Javascript
原生JavaScript编写canvas版的连连看游戏
2016/05/29 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
微信小程序 简易计算器实现代码实例
2019/09/02 Javascript
JavaScript实现轮播图片完整代码
2020/03/07 Javascript
Vue时间轴 vue-light-timeline的用法说明
2020/10/29 Javascript
vue项目中企业微信使用js-sdk时config和agentConfig配置方式详解
2020/12/15 Vue.js
[02:11]完美世界DOTA2联赛10月28日赛事精彩集锦:来吧展示实力强劲
2020/10/29 DOTA
Python程序运行原理图文解析
2018/02/10 Python
python矩阵/字典实现最短路径算法
2019/01/17 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
python对象转字典的两种实现方式示例
2019/11/07 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
2019/12/11 Python
pip install 使用国内镜像的方法示例
2020/04/03 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
校园活动策划书范文
2014/01/10 职场文书
小学中秋节活动方案
2014/02/06 职场文书
二手房买卖协议书
2014/04/10 职场文书
新年晚会开场白
2015/05/29 职场文书
2015年教师节新闻稿
2015/07/17 职场文书
2015年科普工作总结
2015/07/23 职场文书
慰问信的写作格式及范文!
2019/06/24 职场文书
修改MySQL的默认密码的四种小方法
2021/05/26 MySQL
JavaScript实现九宫格拖拽效果
2022/06/28 Javascript
GO中sync包自由控制并发示例详解
2022/08/05 Golang