opencv学习(轮廓检测)

发布于:2025-07-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

1.相关概念

2.核心函数

3.常见的几种操作处理


1.相关概念

轮廓是图像中连续的、有相同颜色 / 灰度值的像素点组成的曲线,代表物体的边界。

与边缘的区别:边缘是离散的像素突变点,轮廓是连续的闭合曲线,更强调 “连接性”。

轮廓检测的前提必须输入二值图像(黑白图像)

2.核心函数

cv2.findContours():用于从二值图像中提取轮廓,返回轮廓列表和层级信息

# OpenCV 4.x/2.x 版本
contours, hierarchy = cv2.findContours(binary_img, mode, method)

# OpenCV 3.x 版本(多一个返回值,通常用_忽略)
_, contours, hierarchy = cv2.findContours(binary_img, mode, method)

参数:: 

  • mode(轮廓检索模式):决定轮廓的层级关系(父子关系)

    • cv2.RETR_EXTERNAL:只保留最外层轮廓(常用,减少干扰)。

    • cv2.RETR_TREE:保留所有轮廓并构建完整层级树(适合分析嵌套轮廓,如 “同心圆”)。

    • cv2.RETR_LIST:保留所有轮廓,但不构建层级(简单场景用)。

  • method(轮廓逼近方法):决定轮廓点的存储方式

    • cv2.CHAIN_APPROX_NONE:存储所有轮廓点(精确但占内存)。

    • v2.CHAIN_APPROX_SIMPLE:压缩冗余点(如矩形只保留 4 个角点,节省内存,常用)。

3.常见的几种操作处理

 绘制轮廓,轮廓特征,边界矩形,外接圆,轮廓近似

import cv2
import matplotlib.pyplot as plt
import numpy as np

#为了更高的准确率,采用二值图像

img=cv2.imread('stru2.jpg')
def cv_show(name,imag):
    cv2.imshow(name,imag)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
cv_show('stru',img)

gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
res,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  #二值处理
cv_show('thresh',thresh)


#轮廓特征(求轮廓的面积和周长)

con=contours[1]#[1]表示轮廓列表的第一个
area=cv2.contourArea(con)#求面积
arc=cv2.arcLength(con,True)#求周长,True表示轮廓是闭合的
print(area,'      ',arc)



#边界矩形

x,y,w,h=cv2.boundingRect(con)#cv2.boundingRect() 是 OpenCV 中用于计算轮廓最小外接矩形(边界矩形)的函数
#x:矩形左上角的 x 坐标,y:矩形左上角的 y 坐标,w:矩形的宽度,h:矩形的高度
imag=cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
#cv2.rectangle() 是 OpenCV 中用于在图像上绘制矩形的函数,常与 cv2.boundingRect() 配合使用,
#(x,y)是矩形的左上角坐标,(x+w,y+h)是矩形的右下角坐标
cv_show('imag',imag)


#外接圆
'''
v2.minEnclosingCircle()是计算轮廓 con 的最小外接圆(能完全包围轮廓的最小圆形)
其中,(x1,y1)是圆心坐标,是浮点数类型,r是半径也是浮点数类型

'''
(x1,y1),r=cv2.minEnclosingCircle(con)
center=(int(x1),int(y1))
r=int(r)
imag1=cv2.circle(draw_img,center,r,(0,255,0),2)#cv2.circle()是OpenCV中用于在图像上绘制圆形的函数,可用于标记目标中心、绘制轮廓外接圆等场景
cv_show('imag1',imag1)



#轮廓近似

con1=contours[2]
arc1=cv2.arcLength(con1,True)
epsilon=0.1*arc1#精度(0.1)越小,近似结果越接近原始轮廓;精度越大,轮廓越简化。
approx=cv2.approxPolyDP(con1,epsilon,True)
draw_img1=img.copy()
res1=cv2.drawContours(draw_img1,[approx],-1,(0,0,255),2)
cv_show('res1',res1)



#用for循环遍历所有的轮廓并进行轮廓近似

draw_img2 = img.copy()
for i,contour in enumerate(contours):
    '''
i:接收当前轮廓的索引(从 0 开始的整数),用于标识当前处理的是第几个轮廓。
contour:接收 contours 列表中的每个轮廓元素(即单个轮廓的坐标数据)。不这样用:contour=contours[i]
enumerate() 是 Python 内置函数,用于将一个可迭代对象(这里是 contours 轮廓列表)转换为一个枚举对象。
    '''
    arc2=cv2.arcLength(contour,True)
    epsilon2=0.2*arc
    approx2=cv2.approxPolyDP(contour,epsilon2,True)
    cv2.drawContours(draw_img2,[approx2],-1,(0,0,255),2)
cv_show('draw_all',draw_img2)




网站公告

今日签到

点亮在社区的每一天
去签到