图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检测识别中很有用。
注意点:
通过使用API --- findContours(img, mode, method[, contours[, hierarchy[, offset]]]])
method :轮廓近似方法,也叫ApproximationMode
返回值 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()
输出结果如下:
通过API --- drawContours(image, contours, contourldx[, thickness[,lineTupe[, hierachy[, maxlevel[,offset]]]])
示例代码如下:
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()
输出结果如下:
轮廓的面积指的是每个轮廓中所有的像素点围成的区域的面积,单位为像素。
轮廓面积是轮廓重要的统计特征之一,通过轮廓面积的大小可以进一步分析每个轮廓隐含的信息, 例如通过轮廓面积区分物体大小识别不同的物体。
在查找到轮廓之后,可能会有很多细小的轮廓,我们可以通过轮廓的面积进行过滤。
计算轮廓面积:contourArea (contour)
计算轮廓周长:arcLength (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()
输出结果如下:
其中第一个为面积,第二个为周长。