OpenCV-35 查找轮廓

一、 什么是图像轮廓

图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检测识别中很有用。

  • 用于图形分析
  • 物体的识别和检测

注意点:

  • 为了检测的准确性,需要先对图像进行二值化或Canny操作。
  • 画轮廓时会修改输入的图像,如果之后想继续使用原始图像,应该将原始图像储存到其他变量中。(即画轮廓是在原图上进行修改

二、 查找轮廓

通过使用API --- findContours(img, mode, method[, contours[, hierarchy[, offset]]]])

  • mode 查找轮廓的模式
  • 其中RETR_EXTERNAL = 0,表示只检测外围轮廓

OpenCV-35 查找轮廓_第1张图片

  • RETR_LIST = 1 , 检测的轮廓不建立等级关系,即检测所有轮廓,较为常用。

OpenCV-35 查找轮廓_第2张图片

  •  RETR_CCOMP = 2,每层最多两级,从小到大,从里到外。

OpenCV-35 查找轮廓_第3张图片

  • RETR_TREE = 3, 按照树型存储轮廓,从小到大,从左到右 (最常用)

OpenCV-35 查找轮廓_第4张图片

method :轮廓近似方法,也叫ApproximationMode

  • 其中:CHAIN_APPROX_NONE 保存所有轮廓上的点
  • CHAIN_APPROX_SIMPLE,只保存角点,比如四边形,只保留四边形的4个角,存储信息少,比较常用。

返回值 contours和hierachy是轮廓层级

其中轮廓的类型为元组(旧版本为列表)

层级的类型为np的ndarray形式

示例代码如下:

import cv2
import numpy as np
# 导入图片
img = cv2.imread("black.png")
# 变为单通道的黑白照片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化操作  ---  返回两个值:阈值和结果
ret, new_img = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(new_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 打印轮廓
print(type(contours))
print(type(hierarchy))
print(contours)
print(hierarchy)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下:

OpenCV-35 查找轮廓_第5张图片

三、 绘制轮廓

通过API --- drawContours(image, contours, contourldx[, thickness[,lineTupe[, hierachy[, maxlevel[,offset]]]])

  • image:要绘制的图象
  • conyours: 轮廓点
  • contourldx:要绘制的轮廓的编号。-1表示绘制所有的轮廓
  • color:轮廓的颜色,如(0,0,255)表示红色
  • thickness:线宽,-1表示全部填充

示例代码如下:

import cv2
import numpy as np
# 导入图片
img = cv2.imread("black.png")
# 变为单通道的黑白照片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化操作  ---  返回两个值:阈值和结果
ret, new_img = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(new_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
img_copy = img.copy()
# 直接在img_copy上面操作
cv2.drawContours(img_copy, contours, -1, (0, 0, 255), 2)
cv2.imshow("img", np.hstack((img, img_copy)))
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下:

OpenCV-35 查找轮廓_第6张图片

四、轮廓的面积和周长

轮廓的面积指的是每个轮廓中所有的像素点围成的区域的面积单位为像素

轮廓面积是轮廓重要的统计特征之一,通过轮廓面积的大小可以进一步分析每个轮廓隐含的信息, 例如通过轮廓面积区分物体大小识别不同的物体

在查找到轮廓之后,可能会有很多细小的轮廓,我们可以通过轮廓的面积进行过滤。

计算轮廓面积:contourArea (contour)

计算轮廓周长:arcLength (curve, closed)

  • curve : 轮廓
  • closed:判断是否为闭合的轮廓

示例代码如下:

import cv2
import numpy as np
# 导入图片
img = cv2.imread("black.png")
# 变为单通道的黑白照片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化操作  ---  返回两个值:阈值和结果
ret, new_img = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(new_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
img_copy = img.copy()
# 直接在img_copy上面操作
cv2.drawContours(img_copy, contours, -1, (0, 0, 255), 2)
cv2.imshow("img", np.hstack((img, img_copy)))
# 计算轮廓的周长和面积
Area = cv2.contourArea(contours[0])
perimeter = cv2.arcLength(contours[1], closed=True)
print(Area)
print(perimeter)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下:

OpenCV-35 查找轮廓_第7张图片

其中第一个为面积,第二个为周长。 

你可能感兴趣的:(OpenCV,opencv,人工智能,计算机视觉,numpy,python)