findContours
发现轮廓drawContours
绘制轮廓处理的图像,轮廓列表,继承关系 = cv.findContours(图像,轮廓检索模式,检索的方法)
# hierarchy[i][3],分别表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号
RETR_EXTERNAL | 只检测最外层轮廓 |
---|---|
RETR_LIST | 提取所有轮廓,并放置在list中,检测的轮廓不建立等级关系 |
RETR_CCOMP | 提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界 |
RETR_TREE | 提取所有轮廓并重新建立网状轮廓结构 |
CHAIN_APPROX_NONE | 获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1 |
---|---|
CHAIN_APPROX_SIMPLE | 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息 |
CHAIN_APPROX_TC89_L1 | Teh-Chinl链逼近算法 |
CHAIN_APPROX_TC89_KCOS | Teh-Chinl链逼近算法 |
cv.drawContours(图像,轮廓列表,轮廓索引-1则绘制所有,轮廓颜色,轮廓的宽度)
cv.drawContours(图像,轮廓列表,轮廓索引-1则绘制所有,轮廓颜色,轮廓的宽度)
实现步骤:
示例代码
import cv2 as cv
def read_rgb_img(img_name):
rgb_img = cv.imread(img_name, cv.IMREAD_COLOR)
cv.imshow("rgb img", rgb_img)
return rgb_img
def convert_rgb2gray(img):
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow("gray img", gray_img)
return gray_img
def convert_gray2binary(img):
binary_img = cv.adaptiveThreshold(img,
255,
cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY, 5, 2)
# _,binary_img = cv.threshold(img,50,255,cv.THRESH_BINARY_INV)
cv.imshow("binary img", binary_img)
return binary_img
def getContours(img):
_, contours, hierarchy = cv.findContours(img, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print(contours, hierarchy)
return contours
def draw_contours(img, contours):
index = -1 # 所有的轮廓
thickness = 2 # 轮廓的宽度
color = (255, 125, 125) # 轮廓的颜色
cv.drawContours(img, contours, index, color, thickness)
cv.imshow('draw contours', img)
if __name__ == '__main__':
img_name = "img/shape0.jpg"
rgb_img = read_rgb_img(img_name)
gray_img = convert_rgb2gray(rgb_img)
binary_imgage = convert_gray2binary(gray_img)
contours = getContours(binary_imgage)
draw_contours(rgb_img, contours)
cv.waitKey(0)
cv.destroyAllWindows()
实现步骤:
示例代码
import cv2 as cv
import numpy as np
def read_rgb_img(img_name):
rgb_img = cv.imread(img_name, cv.IMREAD_COLOR)
cv.imshow("rgb img", rgb_img)
return rgb_img
def convert_rgb2gray(img):
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 采用高斯滤波去掉噪点
gray_img = cv.GaussianBlur(gray_img, (5, 5), 0)
cv.imshow("gray img", gray_img)
return gray_img
def convert_gray2binary(img):
binary_img = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 5, 2)
cv.imshow("binary img", binary_img)
return binary_img
def filter_tenis(img, lower_color, upper_color):
hsv_img = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 查找颜色
mask_img = cv.inRange(hsv_img, lower_color, upper_color)
cv.imshow("mask img", mask_img)
return mask_img
def getContours(img):
# 这里只需要传入俩个参数即可 高斯模糊
contours, hierarchy = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
print(contours, hierarchy)
return contours
def process_tenis_contours(rgb_img, contours):
black_img = np.zeros([rgb_img.shape[0], rgb_img.shape[1], 3], np.uint8)
for c in contours:
# 计算面积
area = cv.contourArea(c)
# 该函数计算曲线长度或闭合轮廓周长。
perimeter = cv.arcLength(c, True)
# 获取最小的外切圆
((x, y), radius) = cv.minEnclosingCircle(c)
# 绘制轮廓
cv.drawContours(rgb_img, [c], -1, (150, 250, 150), 2)
cv.drawContours(black_img, [c], -1, (150, 250, 150), 2)
# 获取轮廓中心点
# cx,cy = get_contour_center(c)
# print(cx,cy)
x = int(x)
y = int(y)
cv.circle(rgb_img, (x, y), int(radius), (0, 0, 255), 2)
cv.circle(black_img, (x, y), int(radius), (0, 0, 255), 2)
print("Area:{},primeter:{}".format(area, perimeter))
print("number of contours:{}".format(len(contours)))
cv.imshow("rgb img contours", rgb_img)
cv.imshow("black img contours", black_img)
if __name__ == '__main__':
img_name = "img/tenis1.jpg"
# 定义范围
lower_color = (30, 120, 130)
upper_color = (60, 255, 255)
rgb_img = read_rgb_img(img_name)
binary_imgage = filter_tenis(rgb_img, lower_color, upper_color)
contours = getContours(binary_imgage)
process_tenis_contours(rgb_img, contours)
cv.waitKey(0)
cv.destroyAllWindows()