### 图像轮廓 (轮廓不同于边缘,连接在一起的才叫轮廓)
#### cv2.findContours(img, mode, method)
#### mode: 轮廓检索模式
- RETR_EXTERNAL: 只检索最外面的轮廓
- RETR_LIST: 检索所有的轮廓,并将其保存在一条链表当中
- RETR_CCOMP: 检索所有的轮廓,并将他们组织为俩层:顶层是各部分的外部边界,第二层是空洞的边界
- RETR_TREE: 检索所有的轮廓,并重构嵌套轮廓的整个层次
#### method:轮廓逼近方法
- CHAIN_APPROX_NONE: 以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
- CHAIN_APPROX_SIMPLE: 压缩水平的、垂直的和斜的部分,也就是:函数只保留他们的终点部分
### 为了更高的准确率,使用二值图像
import cv2
img = cv2.imread(‘1.jpg‘) # 读数据
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换灰度图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 图像阈值 二值处理(0, 255)
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
cv_show(thresh, ‘thresh‘)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 检测函数
### 绘制轮廓
# 传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意传入的模型需要copy,因为函数实在原图像上进行轮廓绘制的
cv_show(img, ‘img‘)
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2) # (图片, 轮廓信息, 画第几个轮廓,(B,G,R), 线条宽度)
cv_show(res, ‘res‘)
### 轮廓特征
len(contours) # 轮廓个数
cnt = contours[10]
cv2.contourArea(cnt) # 轮廓面积
cv2.arcLength(cnt, True) # 轮廓周长, True表示闭合
### 轮廓近似
import cv2
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
img = cv2.imread(‘3.jpg‘) # 读数据
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换灰度图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 图像阈值 二值处理(0, 255)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 检测函数
print(len(contours))
cnt = contours[66]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2) # (图片, 轮廓信息, 画第几个轮廓,(B,G,R), 线条宽度)
cv_show(res, ‘res‘)
epsilon = 0.05 * 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)
cv_show(res, ‘res‘)
### 外接矩形
img = cv2.imread(‘3.jpg‘) # 读数据
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换灰度图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 图像阈值 二值处理(0, 255)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 检测函数
print(len(contours))
cnt = contours[66]
x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv_show(img, ‘img‘)
area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extend = float(area) / rect_area
print(‘轮廓面积与边界矩形面积之比为:‘, extend)
### 外接圆
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0, 255, 0), 2)
cv_show(img, ‘img‘)