检测轮廓API:
- cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
- 返回三个值:img(轮廓本身);contours(每条轮廓对应的属性);hierarchy(层级)
– mode:轮廓的检索模式,有四种:
1.cv2.RETR_EXTERNAL:只检测外轮廓;
2.cv2.RETR_LIST:检测所有的轮廓,并将其保存在一条链表中;
3.cv2.RETR_CCOMP:检测所有的轮廓,并将他们组织为两层:顶层是个部分的外部边界,第二次是空洞的边界;
4.cv2.RETR_TREE:检测所有的轮廓,并重构前台轮廓的整个层次。
- 第四种用得最多。
– method:轮廓逼近方法:
1.cv2.CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列);存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1;
2.cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息;
3.cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。
绘制轮廓API:
- cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]]):绘制轮廓
为了更高的准确率,我们使用二值图像。 - image:在哪个图像上绘制轮廓;contours:检测 *** 作得到的轮廓,是个list;contourIdx:指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./img.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
#注意要对原图使用copy,不然原图也会改变
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv2.imshow('img', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
9.2 轮廓特征
调用对应API得到结果,仅此而已,用到的时候再说吧。
。
。
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./img.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
#开始查看轮廓特征,从列表中取出一个
cnt = contours[0]
#面积
cv2.contourArea(cnt)
#周长,True表示闭合
cv2.areLength(cnt, True)
9.3 轮廓近似
9.3.1 近似图形
- cv2.approxPolyDP(contour, epsilon, isClosed)
轮廓近似
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
#轮廓近似
epsilon = 0.1 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
9.3.2 外接矩形
9.3.2.1 直边界矩形
没有进行旋转,所以该边界矩形的面积不是最小的。
-
cv2.boundingRect(contour)
-
返回4个值:x,y,w,h(x,y为矩形左上角坐标,w,h为矩形宽,高)
-
先靠这个API获取外界举行的信息,再用图像绘制中的cv2.rectangle()绘制外界矩形。
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
9.3.2.2 旋转边角矩形
需要用到角点知识,后面再进行补充。
- cv2.minAreaRect(contour)
- 返回5个值:矩形左上角角点坐标(x, y),矩形的宽和高(w, h)以及旋转角度。
- 绘制该矩形需要矩形的四个角点,可通过函数cv2.boxPoints()获得。
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
s = cv2.minAreaRect(cnt)
a = cv2.boxPoints(s)
a = np.int0(a)
cv2.polylines(img, [a], True, (0, 0, 255), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
9.3.3 最小外接圆
- cv2.minEnclosingCircle(contour)
- 返回中心点(x, y)和圆的半径radius
import cv2
import numpy as np
if __name__ == '__main__':
# 二值图像的转化
img = cv2.imread('./contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
#注意都需要转换成int型
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)