程序员

Opencv之轮廓特征

2020-02-08  本文已影响0人  码农啊涛

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)


上一篇下一篇

猜你喜欢

热点阅读