OPENCV基础操作

提示:本专栏所用版本仅供参考,其他版本也可

版本
python Python 3.9.3
opencv 4.5.5
matplotlib 3.4.3
numpy 1.19.5
QQ学习群 点击加群:928357277

学习目录

  • 提问环节
    • 1:什么是图像轮廓
    • 2:图像轮廓和边缘检测的区别
    • 3:如何进行图像检测
  • 查找轮廓
    • 参数mode表
    • 参数method表
    • 代码演示
  • 轮廓绘制
    • 代码演示
  • 轮廓矩特征
    • 使用零阶矩计算轮廓面积
    • 使用函数计算轮廓周长面积
    • Hu矩:
      • 基于Hu矩的形状匹配
        • 图表:比较方法参数
      • 计算俩个图像不同的匹配度
  • 轮廓拟合
    • 绘制矩形包围框
    • 绘制最小包围矩形框
    • 绘制最小包围圆形
    • 绘制最优拟合圆
    • 绘制最优拟合直线
      • 图表:距离类型参数
    • 绘制最小外包三角形
    • 绘制逼近多边形

提问环节

1:什么是图像轮廓

答:是图像中非常重要个一个特征信息,通过对图像的检测,我们能够获得图像的大小,位置,方向等。

2:图像轮廓和边缘检测的区别

答:图像轮廓可以检测到完整的,连续的边缘信息,同时还能获得图像的各种特征信息,如大小,位置,方向等

3:如何进行图像检测

答:为了检测完整的,连续的边缘信息,openCv提供了findContours()轮廓查找函数,和drawContours()轮廓绘制函数

查找轮廓

c,h = cv2.findContours(image,mode,method)
注意:在opencv4之前该函数有三个返回值:image,c,h

返回值为轮廓信息c,和图像的拓扑信息h
参数Mode为轮廓的检索模式
参数method为轮廓的近似方法

参数mode表

参数 说明
cv2.RETR_LIST 检测到的轮廓不建立等级关系
cv2.RETR_EXTERNAL 检测所有外轮廓
cv2.RETR_CCOMP 检索素有轮廓并组织为两级层次结构
cv2.RETR_TREE 建立等级数结构的轮廓

参数method表

参数 说明
cv2.CHAIN_APPROX_NONE 存储所有轮廓点,两点位置差不超过1
cv2.CHAIN_APPROX_SIMPLE 只保留该方向的终点坐标
cv2.CHAIN_APPROX_TC89_L1 ten_chinl chain近似算法风格
cv2.CHAIN_APPROX_TC89_KCOS ten_chinl chain近似算法风格

代码演示

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as np轮廓获取img  = cv2.imread('1.jpg',0)#对图像进行二值化处理
r,img = cv2.threshold(img,180,255,cv2.THRESH_BINARY)
# print(data.shape)
#返回轮廓信息,拓扑信息,检测轮廓的模式为只检测外轮廓,方式为存储所有的轮廓蒂娜
c,h = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)a = len(c)
print(a)#打印轮廓数量
print(c[a-1].shape)#打印最后一个轮廓的信息for X in range(a):#打印每个轮廓的拓扑信息"""Next , Previous , First_Child , Parent"""print(X,":",h[X])

运行结果:

07\exercise> python .\opencv3.py
轮廓数量 1
(2300, 1, 2)
0 : [[-1 -1 -1 -1]]

第一行为轮廓数量,第二行为当前轮廓信息,第三行为当前的轮廓拓扑信息

轮廓绘制

image = cv2.drawContours(image,contours,contourIdx,color[,thickness[,lineType[,hierachy[,maxlevel[,offset]]]]])参数依次为:原始图像,轮廓信息,边缘索引,绘制颜色,画笔粗细,线形,层次信息,轮廓深度,偏移位置

参数依次为:原始图像,轮廓信息,边缘索引,绘制颜色,画笔粗细,线形,层次信息,轮廓深度,偏移位置

代码演示

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg  = cv2.imread('1.jpg',0)#对图像进行二值化处理
r,img = cv2.threshold(img,180,255,cv2.THRESH_BINARY_INV)
# print(data.shape)
#返回轮廓信息,拓扑信息,检测轮廓的模式为只检测外轮廓,方式为存储所有的轮廓蒂娜
c,h = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)image = cv2.drawContours(img,c,-1,(255,255,255),-1)#绘制实心轮廓,提取前景色
cv2.imshow('img',image)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

轮廓矩特征

轮廓矩特征:moments()
语法格式:cv2.moments(array[,binaryImage])
参数为:点集array,图像二值化处理标志
返回值为轮廓矩:

轮廓矩包括:
1、空间矩(零阶矩(m00),一阶矩(m10,m01),二阶矩(m20,m11,m02),三阶矩)
2、中心矩(二阶中心矩(mu20,mu11,mu02),三阶中心矩)
3、归一化中心矩(二阶Hu矩(nu20,nu11,nu02),三阶Hu矩)
各矩阵都有自己独特的用法,比如说m00矩可以用来比较面积大小,归一化中心矩可以描述平移,缩放不变性。

使用零阶矩计算轮廓面积

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as np
img  = cv2.imread('1.jpg',0)#对图像进行二值化处理
r,img = cv2.threshold(img,180,255,cv2.THRESH_BINARY_INV)
# print(data.shape)
#返回轮廓信息,拓扑信息,检测轮廓的模式为只检测外轮廓,方式为存储所有的轮廓蒂娜
c,h = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)#计算轮廓的面积
a = len(c)
for X in range(a):print(X,"的面积:%d" %cv2.moments(c[X])['m00'])image = cv2.drawContours(img,c,-1,(255,255,255),-1)#绘制实心轮廓,提取前景色
cv2.imshow('img',image)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

0 的面积:1914
1 的面积:2455
2 的面积:3662
3 的面积:2882
4 的面积:3104
5 的面积:6100
6 的面积:23765
7 的面积:23287
8 的面积:9
9 的面积:23680

使用函数计算轮廓周长面积

当然,我们还可以通过openCv提供的其他函数来进行面积计算

计算面积:retval = cv2.contourAera(contour[,oriented])
计算长度:retcal = cv2.arcLength(contour,colsed)

Hu矩:

HU矩是归一化中心矩的线性组合。Hu矩阵在图像旋转,缩放,平移等操作后,仍能保持矩阵的不变特性,经常被用来识别图像的特征
在OpenCV中使用HuMomente()得到Hu矩,返回值为monments()函数的返回值作为参数,返回7个Hu矩值
== hu = cv2.HuMoments(m) ==
关于得到7个矩值的计算方式,有想了解的可以自行百度

基于Hu矩的形状匹配

函数支持:cv2.matchShapes(contour1,contour2,method,parameter)
参数为:第一个轮廓或者灰度图像,第二个轮廓或者灰度图像,比较方法,扩展参数(扩展参数仅支持opencv4.1.0及之后版本)

图表:比较方法参数

计算俩个图像不同的匹配度


img1 = cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE)#二值化处理
rt,img1 = cv2.threshold(img1,150,255,cv2.THRESH_BINARY)#做出第二章图片
img2 = img1c1,h2 = cv2.findContours(img1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
c2,h2 = cv2.findContours(img2,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) c11 = c1[0]
c22 = c2[0]
#形状匹配
r1 = cv2.matchShapes(c11,c22,cv2.CONTOURS_MATCH_I1,0.0)print("形状匹配度 ", r1)

运行结果:

形状匹配度  0.0

轮廓拟合

为了方便计算得到一个接近于轮廓的多边形,我们需要对轮廓进行轮廓拟合操作

绘制矩形包围框

函数:retval = cv2.boundingRect(array)
返回值为边界左上角顶点的坐标值及矩形边界的宽度和高度,参数为灰度图像或者轮廓
还可以写作四个返回值的形式:x,y,w,h = cv2.boundingRect

代码:

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg = cv2.imread('1.jpg')imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框
print(len(c))
x,y,w,h = cv2.boundingRect(c[10])
#矩形边框点集
rect = np.array([[[x,y]],[[x+w,y]],[[x+w,y+h]],[[x,y+h]]])
#绘制
# cv2.rectangle(imgGray,(x,y),(x+w,y+h),(255,255,255),2)
cv2.drawContours(imgGray,[rect],-1,(255,255,255),2)
cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

绘制最小包围矩形框

retval = minAreaRect(points)
返回值为矩形特征信息(最小外接矩形的中心,(宽度,高度),旋转角度)
参数为轮廓

代码:

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg = cv2.imread('1.jpg')imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框
print(len(c))
#矩形边框点集
rect = cv2.minAreaRect(c[10])
points = cv2.boxPoints(rect)#返回值转换函数
points = np.int0(points)# 结果取整数
#绘制
# cv2.rectangle(imgGray,(x,y),(x+w,y+h),(255,255,255),2)
cv2.drawContours(imgGray,[points],-1,(255,255,255),2)
cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

绘制最小包围圆形

center,radius = cv2.minEnclosingCircle(points)
返回值为圆形中心,圆形半径

绘制最优拟合圆

retval = cv2.fitEllipse(points)
返回值为RotateRect类型的值,包含外接矩形的质心、宽、高、旋转角度等参数信息,对应椭圆的中心点,轴长度,旋转角度
参数为轮廓信息
使用代码:

#使用下面代码代码替换绘制部分即可ellipse = cv2.fitEllipse(c[10])cv2.ellipse(img,ellipse,(1,255,1),3)

绘制最优拟合直线

line = cv2.fitLine(points,disType,param,reps,aeps)
返回值为最优拟合直线参数
参数为轮廓,距离类型,距离参数,用于拟合直线所需要的的径向精度【0.01】,用于拟合直线所需要的的角度精度【0.01】

图表:距离类型参数

使用代码:

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg = cv2.imread('1.jpg')imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框print(len(c))
#矩形边框点集
rows,cols = imgGray.shape[:2]
[vx,vy,x,y] = cv2.fitLine(c[10],cv2.DIST_L2,0,0.01,0.01)#计算左右距离
lefty = int((-x*vy/vx)+y)
righty = int(((cols-x)*vy/vx)+y)#绘制直线
cv2.line(imgGray,(cols-1,righty),(0,lefty),(0,255,0),2)cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

绘制最小外包三角形

retval,triangle = minEnclosingTriangle(points)
返回值为:最小外包三角形的面积retval、最小外包三角形的三个顶点集triangle
参数为轮廓信息

使用代码:

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg = cv2.imread('1.jpg')imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框print(len(c))
#获取三角形信息,最小外包面积和三个顶点集
area,trgl = cv2.minEnclosingTriangle(c[10])#绘制三角形
for i in range(3):cv2.line(imgGray,tuple([int(trgl[i][0][0]),int(trgl[i][0][1])]),tuple([int(trgl[(i + 1 )% 3][0][0]),int(trgl[(i + 1 )% 3][0][1])]),(255,255,255),2)#显示图片
cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

绘制逼近多边形

approxCurve = cv2.approxPolyDp(curve,epsilon,colsed)
返回值为逼近多边形的点集
参数为:轮廓curve、精度epsilon[原始轮廓的边界点与逼近多边形边界之间的最大距离]、是否封闭标志colsed

使用代码:

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as npimg = cv2.imread('1.jpg')imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框print(len(c))
# 设置epsilon = 0.1为周长
imgGrayL  = imgGray.copy()#复制一个矩阵
epslion = 0.1*cv2.arcLength(c[10],True)
approx = cv2.approxPolyDP(c[10],epslion,True)
imgGrayL = cv2.drawContours(imgGrayL,[approx],0,(0,255,255),2)
# 设置epsilon = 0.05为周长
imgGrayL2  = imgGray.copy()#复制一个矩阵
epslion = 0.05*cv2.arcLength(c[10],True)
approx = cv2.approxPolyDP(c[10],epslion,True)
imgGrayL2 = cv2.drawContours(imgGrayL2,[approx],0,(0,0,255),2)imgcom = np.hstack((imgGrayL,imgGrayL2))
#显示图片
cv2.imshow('imgGrayL',imgcom)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

如果你也喜欢编程,点击群号加入我们的QQ大家庭 928357277吧!

openCV专栏(八):图像轮廓:绘制轮廓相关推荐

  1. 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形

    FindContours 在二值图像中寻找轮廓  int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_cont ...

  2. OpenCV_11 轮廓检测:图像的轮廓+绘制轮廓+轮廓近似+边界矩形+椭圆拟合+直线拟合

    1 图像的轮廓 轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度.轮廓是图像目标的外部特征,这种特征对于我们进行图像分析,目标识别和理解等更深层次的处理都有很重要的意义. ...

  3. 计算机视觉OpenCV(五):图像金字塔与轮廓检测

    目录 图像金字塔 1. 高斯金字塔(Gaussian Pyramid) 2. 拉普拉斯金字塔(Laplacian Pyramid) 图像轮廓 1. 查找检测物体的轮廓 2. 绘制轮廓 3. 轮廓特征 ...

  4. opencv之在图像上绘制标记---drawMarker

    核心函数 drawMarker(img, position, color, markerType=None, markerSize=None, thickness=None, line_type=No ...

  5. python画函数图像网格_使用opencv python在图像上绘制网格线

    这是我的问题解决方案.利用它.import matplotlib.pyplot as plt import matplotlib.ticker as plticker try: from PIL im ...

  6. opencv补全边缘_为什么OpenCV中绘制的轮廓不能填充图像边缘的轮廓?

    编辑:我绕过了这个问题,在图像中添加了一个2位帧,然后使用我的代码,最后剪切图像以删除多余的帧.这是一个丑陋的解决方案,但它的工作! 我遇到了一个问题,我不确定这是一个错误还是我缺乏经验.我会尽量把它 ...

  7. 【opencv】(6) 图像轮廓处理

    各位同学好,今天和大家分享一下opencv中如何获取图像轮廓,以及对轮廓的一些其他操作.内容有: (1)轮廓检测:cv2.findContours():(2)轮廓绘制:cv2.drawContours ...

  8. OpenCV学习笔记(十七):查找并绘制轮廓:findContours(),drawContours(),approxPolyDP()

    OpenCV学习笔记(十七):查找并绘制轮廓:findContours() 1.findContours() 函数 该函数使用Suzuki85算法从二值图像中检索轮廓.轮廓线是一种用于形状分析.目标检 ...

  9. OpenCV:07图像轮廓

    图像轮廓 什么是图形轮廓 查找轮廓 绘制轮廓 计算轮廓的面积和周长 轮廓面积 轮廓周长 多边形逼近 凸包 轮廓拟合 外接矩形 最小外接矩形 最大外接矩形 外接圆 边缘检测`Canny` 霍夫变换 直线 ...

最新文章

  1. linux系统python 2.6 安装pip_详解CentOS升级Python2.6到Python2.7并安装pip
  2. 进程外COM组件的一个实例
  3. [openstack]依赖提交
  4. Ubuntu安装Samba实现跟windows文件共享
  5. 第三节:框架前期准备篇之利用Newtonsoft.Json改造MVC默认的JsonResult
  6. Web2.0十大Ajax安全漏洞以及成因
  7. 随想录(windows静态库和动态库)
  8. 清华AI画虾师,想当现代齐白石
  9. 西瓜笔记(五上)--线性模型
  10. Eclipse+CDT+MinGW 配置 C/C++ 开发环境
  11. java对接PayPal支付(v1)
  12. 2021年中国研究生数学建模竞赛B题——空气质量预报二次建模
  13. 微信公众平台——用户管理
  14. 换了5G手机不会用5G网络?赶快来补课!
  15. 神经网络中的反向传播
  16. 图像处理-opencv去水印(如有图片侵权,请及时联系)
  17. 不使用Ultra Liberarion软件导出BXL文件的方法
  18. 扫雷游戏9*9(详细到具体每一步)
  19. 第十一章 认识与学习BASH【鸟哥linux私房菜学习笔记】
  20. 防止ARP欺骗的简单方法——静态绑定网关

热门文章

  1. 学计算机和英语哪个好考,英语不好,学计算机哪方面比较好?
  2. ds12c887程序C语言,单片机+TM1628+DS12C887时钟源程序
  3. Tkinter 组件详解(七):Entry
  4. Oracle v12.2 Bug 27163928触发ORA-4031 导致实例crash.
  5. 【学习打卡】GradCAM可解释性分析
  6. QT UI控件和事件
  7. AWVS扫描报告分析
  8. 免费录屏软件之OBS Studio
  9. 尔雅戏剧鉴赏 考试答案
  10. Mysql外键作用和用法