opencv python 轮廓特征/凸包/外接矩形/外接圆/拟合矩形/拟合直线/拟合圆

Contour Features

1 图像的矩

cv2.moments()
图像的矩可以帮助计算物体的某些特征,如对象的质心,对象的区域等.

代码

import cv2
import numpy as np

img = cv2.imread('img7.png',0)
ret,thresh = cv2.threshold(img,127,255,0)
im2,contours,hierarchy = cv2.findContours(thresh, 1, 2)

cnt = contours[0]
M = cv2.moments(cnt)
print( M )

输出:{'m00': 283.0, 'm10': 8260.666666666666, 'm01': 34747.666666666664, 'm20': 251349.8333333333, 'm11': 1008063.0, 'm02': 4274513.166666666, 'm30': 7941981.4, 'm21': 30484543.9, 'm12': 123258620.46666667, 'm03': 526819846.70000005, 'mu20': 10223.989595602674, 'mu11': -6208.702394974302, 'mu02': 8080.874165684916, 'mu30': 8302.495426246896, 'mu21': -14552.154961312423, 'mu12': 11791.528133469663, 'mu03': -3268.923251092434, 'nu20': 0.12765785058625623, 'nu11': -0.07752253611575, 'nu02': 0.10089867729257346, 'nu30': 0.006162296011483629, 'nu21': -0.010800931752771139, 'nu12': 0.008751933371317017, 'nu03': -0.0024262672459139235}

此刻,可以提取有用的数据,如面积,质心等.
质心由关系给出:

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

2轮廓面积

cv2.contourArea(contour[, oriented])

3轮廓周长

cv2.arcLength(curve, closed)
第二个参数指定形状是否为闭合轮廓

4轮廓近似

它根据我们指定的精度将轮廓形状近似为具有较少顶点数的另一个形状.它是Douglas-Peucker算法的一种实现方式.

cv2.approxPolyDP(curve, epsilon, closed[, approxCurve])

第二个参数epsilon,它是从轮廓到近似轮廓的最大距离.第三个参数指定曲线是否闭合.

下面,在第二幅图像中,绿线表示epsilon =弧长的10%的近似曲线. 第三幅图像显示相同的epsilon =弧长的1%.
代码

import cv2
import numpy as np

img = cv2.imread('img8.png')
cv2.imshow('src',img)
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]

epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
cv2.polylines(img, [approx], True, (0, 0, 255), 2)

cv2.imshow('show',img)
cv2.waitKey()

clipboard.png
clipboard.png
clipboard.png

5凸包

凸包看起来类似轮廓近似,但是它不是(两者在某些情况下可能提供相同的结果).

convexHull(points[, hull[, clockwise[, returnPoints]]]):检查曲线的凸性缺陷并进行修正.

  • points:传入的轮廓
  • hull:输出
  • clockwise:方向标志,如果为True,则顺时针方向输出凸包.
  • returnPoints:默认情况下为True,然后它返回hull points的坐标; 如果为False,则返回与hull points对应的轮廓点的索引

下面的手形图像. 红线表示手的凸包, 双面箭头标记显示凸起缺陷.

clipboard.png

代码

import cv2
import numpy as np

img = cv2.imread('img8.png')

imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]

hull = cv2.convexHull(cnt)

returnPoints = True,得到以下值:

array([[[192, 135]],
       [[  9, 135]],
       [[  9,  12]],
       [[192,  12]]], dtype=int32)

如果想找到凸性缺陷,需要传递returnPoints = False,得到以下结果:

array([[129],
       [ 67],
       [  0],
       [142]], dtype=int32)
       

这些是轮廓中相应点的索引,检查第一个值:

cnt[129]

Out[3]: array([[192, 135]], dtype=int32)

与第一个结果相同.

6 检查凸性

cv2.isContourConvex(contour):检查曲线是否凸起

7 外接矩形

7.1 直边外接矩形

它是一个直的矩形,它不考虑对象的旋转。因此,边界矩形的面积不会最小.
cv.boundingRect()
设(x,y)为矩形的左上角坐标,(w,h)为宽度和高度
代码

import cv2
import numpy as np

img = cv2.imread('img7.png')

imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]

x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

cv2.imshow('show',img)
cv2.waitKey()

clipboard.png

7.2 最小外接矩形

cv.minAreaRect返回一个Box2D结构,其中包含以下detals - (center(x,y),(width,height),rotation of rotation)
cv.boxPoints画上述矩形.

代码

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)

clipboard.png

8 最小封闭圈

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(0,255,0),2)

clipboard.png

9 拟合椭圆

ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(0,255,0),2)

clipboard.png

10 拟合直线

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)

clipboard.png

目前正在学习以及巩固opencv-python知识.

76 声望
37 粉丝
0 条评论
推荐阅读
opencv python 图像修复
Image Inpainting 我们将学习如何通过一种称为修复的方法去除旧照片中的小噪音,笔画等。基本思路很简单:用相邻像素替换那些坏标记,使其看起来像邻域。 cv2.inpaint() cv2.INPAINT_TELEA cv2.INPAINT_NS {代...

sakurala1阅读 7.2k

Ubuntu20.04 从源代码编译安装 python3.10
Ubuntu 22.04 Release DateUbuntu 22.04 Jammy Jellyfish is scheduled for release on April 21, 2022If you’re ready to use Ubuntu 22.04 Jammy Jellyfish, you can either upgrade your current Ubuntu syste...

ponponon1阅读 4k评论 1

日常Python 代码片段整理
1、简单的 HTTP Web 服务器 {代码...} 2、单行循环List {代码...} 3、更新字典 {代码...} 4、拆分多行字符串 {代码...} 5、跟踪列表中元素的频率 {代码...} 6、不使用 Pandas 读取 CSV 文件 {代码...} 7、将列表...

墨城2阅读 301

Unicode 正则表达式(qbit)
前言本文根据《精通正则表达式》和 Unicode Regular Expressions 整理。本文的示例默认以 Python3 为实现语言,用到 Python3 的 re 模块或 regex 库。基本的 Unicode 属性分类 {代码...} 基本的 Unicode 子属性Le...

qbit阅读 4.3k

Python + Sqlalchemy 对数据库的批量插入或更新(Upsert)
由于不同数据库对这种 upsert 的实现机制不同,Sqlalchemy 也就不再试图做一致性的封装了,而是提供了各自的方言 API,具体到 Mysql,就是给 insert statement ,增加了 on_duplicate_key_update 方法。

songofhawk1阅读 1.9k评论 4

封面图
打脸了兄弟们,Go1.20 arena 来了!
大家好,我是煎鱼。大概半年前,我写过一篇文章《Go 要违背初心吗?新提案:手动管理内存》。有兴趣了深入解的同学,可以再回顾一下。当时我们还想着 Go 团队应该不会接纳,至少不会那么快:懒得翻也可以看我再次...

煎鱼阅读 3.2k

uwsgi 注意事项
http 和 http-socket 选项是完全不同的。第一个生成一个额外的进程,转发请求到一系列的worker (将它想象为一种形式的盾牌,与apache或者nginx同级),而第二个设置worker为原生使用http协议。

zed2015阅读 2.2k

目前正在学习以及巩固opencv-python知识.

76 声望
37 粉丝
宣传栏