1.矩
图像的矩可以帮助我们计算图像的质心,面积等。# -*- coding: utf-8 -*-
import cv2
import numpy as np
img = cv2.imread('1.jpg')
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy=cv2.findContours(threshcv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
Z = cv2.moments(cnt)
print Z
#计算重心
cx = int(Z['z10']/Z['z00'])
cy = int(Z['z01']/Z['z00'])
2.轮廓面积
轮廓的面积可以使用函数 cv2.contourArea() 计算得到。area = cv2.contourArea(cnt)
3.轮廓周长perimeter = cv.arcLength(cnt,True) #不能强行赋予Flase。
4.轮廓近似
我们假设要在下图中找一个矩形
但是这个图凹凸不平,直接提取轮廓无法提取到一个完美的矩形。因此我们就可以使用cv2.approxPolyDP( )这个函数来近似这个形状了。这个函数的第二个参数epsilon,是从原始轮廓到近似轮廓的最大距离,是一个准确度参数。# -*- coding:utf-8 -*-
import numpy as np
import cv2
src = cv2.imread('1.jpg')
img = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
epsilon =0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)#这个和上面的True都是表示是闭曲线
#approx得到的仅仅是几个点集,需要将其连接起来
cv2.polylines(src, [approx], True, (0,255,0),2) #这个函数才能画出轮廓,中间的True也是指示是否为闭曲线的
cv2.imshow('1',src)
cv2.waitKey(0)
当epsilon为0.1时:
当epsilon为0.01时:
5.凸包
凸包与轮廓近似相似,但不同,虽然有些情况下它们给出的结果是一样的。函数cv2.convexHull() 可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷。
如图:
红色曲线表示了它的凸包,而凸性缺陷被双箭头标出来了。
函数cv2.convexHull()hull = cv2.convexHull(points[],hull[],clockwise,retirnPoints)
point是我们要传入的轮廓
hull 输出,通常不需要
clockwise 方向标志,如果设置为True,输出的凸包是顺时针方向的,否则为逆时针方向
returnPoints 默认为True。它会返回凸包上点的坐标。如果设置为False,则会返回凸包点对应于原轮廓上的点坐标
实际操作中我们只需要下面的命令就可以了。hull = cv2.convexHull(cnt)
但是如果你想获得凸性缺陷,需要把 returnPoints 设置为 False。现在我把 returnPoints 设置为True 查找凸包# -*- coding:utf-8 -*-
import numpy as np
import cv2
src = cv2.imread('1.jpg')
img = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
hull = cv2.convexHull(cnt,returnPoints=True)
print hull
cv2.polylines(src, [hull], True, (0, 255, 0), 2) #这个函数才能画出轮廓,中间的True也是指示是否为闭曲线的
cv2.imshow('1',src)
cv2.waitKey(0)
6.凸性检测
函数 cv2.isContourConvex() 可以可以用来检测一个曲线是不是凸的。它只能返回True 或 False。k = cv2.isContourConvex(cnt)
7.边界矩形
有两类边界矩形
直边界矩形 一个直矩形,它不会考虑对象是否旋转。所以边界矩形的面积不是最小的。
旋转的边界矩形 这个边界矩形是面积最小的,因为它考虑了对象的旋转。# -*- coding:utf-8 -*-
import numpyas np
import cv2
src = cv2.imread('2.jpg')
img = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
#直边界矩形
x,y,w,h = cv2.boundingRect(cnt)
src = cv2.rectangle(src,(x,y),(x+w,y+h),(0,255,0),2)
#旋转边界矩形
s = cv2.minAreaRect(cnt)
a = cv2.boxPoints(s)
a = np.int0(a)
cv2.polylines(src,[a],True,(0,0,255),3)
cv2.imshow('2',src)
cv2.waitKey(0)
8.最小外接圆
函数 cv2.minEnclosingCircle() 可以帮我们找到一个对象的外切圆。它是所有能够包括对象的圆中面积最小的一个。(x,y),radius = cv2.minEnclosingCircle(cnt)
center= (int(x),int(y))
radius= int(radius)
src= cv2.circle(src,center,radius,(0,255,0),1)