OpenCV 从基础到进阶系列之二 ->轮廓检测,模板匹配,图像平滑(滤波),形态学操作

OpenCV 核心功能详解教程(Python版)从基础到进阶第二章


OpenCV是计算机视觉领域的“瑞士军刀”,支持图像/视频处理、特征提取、目标检测等核心功能。
本教程以基础篇 和 进阶篇 2部分对OpenCV 功能进行详解,结合 Python 代码、参数说明及原理讲解,带你系统掌握OpenCV的核心技能


内容摘要

轮廓检测,模板匹配,图像平滑(滤波),形态学操作


  1. 轮廓检测
    用途:提取图像中连通区域的轮廓,用于形状分析。
    核心函数:
    cv2.findContours(image, mode, method):
    mode 如 cv2.RETR_TREE
    method 如 cv2.CHAIN_APPROX_SIMPLE

    检索模式(mode):

    方法名称用途参数说明原理
    cv2.RETR_EXTERNAL只检测最外层轮廓适用于提取简单物体的外轮廓(如一个独立物体仅返回没有父轮廓的轮廓(层级结构中的顶层)
    cv2.RETR_LIST检测所有轮廓,不建立层级关系适用于无需分析轮廓父子关系的场景所有轮廓存储在列表中,无层级嵌套关系
    cv2.RETR_CCOMP检测所有轮廓,并将轮廓组织为两级结构(外层和内孔)适用于需要区分物体和外孔的场景(如带孔的零件)所有轮廓分为两级:顶层是外部轮廓,第二层是内孔轮廓
    cv2.RETR_TREE检测所有轮廓,并建立完整的层级树结构适用于需要分析轮廓嵌套关系的场景(如嵌套的几何图形)生成完整的父子层级关系树

    近似方法(method):

    方法名称用途参数说明原理
    cv2.CHAIN_APPROX_NONE存储轮廓所有点的坐标保留完整轮廓细节,适用于需要精确坐标的场景轮廓点以连续坐标形式存储(内存占用较大)
    cv2.CHAIN_APPROX_SIMPLE压缩水平、垂直和对角线段,仅保留端点减少轮廓点数量,适用于矩形、多边形等规则形状删除冗余点,仅保留线段转折点(内存优化)
    cv2.CHAIN_APPROX_TC89_L1使用 Teh-Chin 链逼近算法(L1 范数)适用于复杂曲线的高效逼近基于链式近似算法,平衡精度与效率
    cv2.CHAIN_APPROX_TC89_KCOS使用 Teh-Chin 链逼近算法(K-COS 范数)同上,但使用不同范数计算同上,但逼近方式略有不同

    实际应用场景举例

    名称应用场景
    RETR_EXTERNALOCR 文字轮廓检测(仅需外框)
    RETR_CCOMP工业零件孔洞检测(区分物体和孔)
    RETR_TREE医学图像中嵌套器官分析
    CHAIN_APPROX_SIMPLE矩形/多边形物体识别(减少计算量)

    示例代码:

    import cv2
    import numpy as np
    
    # 1. 读取图像并二值化
    img = cv2.imread('shapes.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    
    # 2. 轮廓检测(使用RETR_TREE和CHAIN_APPROX_SIMPLE)
    contours, hierarchy = cv2.findContours(
        binary, 
        mode=cv2.RETR_TREE,         # 检索模式:层级树结构
        method=cv2.CHAIN_APPROX_SIMPLE  # 近似方法:压缩冗余点
    )
    
    # 3. 绘制轮廓
    cv2.drawContours(img, contours, -1, (0, 0, 255), 2)
    cv2.imshow('Contours', img)
    cv2.waitKey(0)
    

在这里插入图片描述

  1. 模板匹配
    用途:在图像中查找模板位置,用于目标定位。
    核心函数:
    cv2.matchTemplate(image, templ, method):
    method 如 cv2.TM_CCOEFF_NORMED。

    方法名称函数名称数学原理适用场景
    平方差匹配法cv2.TM_SQDIFF计算模板与图像区域的平方差,值越小匹配度越高。适用于模板与图像区域的亮度差异较大的场景,匹配结果越接近0越好
    归一化平方差匹配法cv2.TM_SQDIFF_NORMED对平方差进行归一化处理,值范围 [0, 1]。对光照变化鲁棒,适合模板和图像亮度不一致的情况
    相关匹配法cv2.TM_CCORR计算模板与图像区域的互相关,值越大匹配度越高对亮度敏感,若图像亮度整体偏高可能导致误匹配。
    归一化相关匹配法cv2.TM_CCORR_NORMED归一化互相关,值范围 [0, 1]减少亮度变化的影响,适合光照不均匀但图案相似的情况
    相关系数匹配法cv2.TM_CCOEFF基于模板和图像的均值计算相关性,值越大匹配度越高。对模板和图像的亮度变化不敏感,适合复杂背景下的匹配
    归一化相关系数匹配法cv2.TM_CCOEFF_NORMED归一化相关系数,值范围 [-1, 1],1表示完全匹配。最常用方法,对光照、对比度变化鲁棒,适合大多数场景。

    示例代码:

    import cv2
    import numpy as np
    
    # 读取图像和模板
    img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    template = cv2.imread('template.jpg', cv2.IMREAD_GRAYSCALE)
    h, w = template.shape
    
    # 执行模板匹配(以归一化相关系数法为例)
    result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
    
    # 获取最佳匹配位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    top_left = max_loc  # TM_CCOEFF_NORMED取最大值位置
    bottom_right = (top_left[0] + w, top_left[1] + h)
    
    # 绘制矩形框
    cv2.rectangle(img, top_left, bottom_right, 255, 2)
    cv2.imshow('Match Result', img)
    cv2.waitKey(0)
    

    在这里插入图片描述

  2. 图像平滑(滤波)
    用途:去除噪声,提升图像质量。

    方法名称函数名称核心参数数学原理优点缺点适用场景
    均值滤波cv2.blur() 或 cv2.boxFilter()ksize: 滤波核大小(如 (5,5))normalize: 是否归一化(仅 boxFilter)邻域内像素值的算术平均计算简单、速度快边缘模糊,噪声抑制能力弱快速去除轻微噪声,对计算资源要求低
    高斯滤波cv2.GaussianBlur()ksize: 高斯核大小(正奇数,如 (5,5))sigmaX: X方向标准差(0表示自动计算)邻域内像素的高斯加权平均,权重随距离中心点增加而衰减。保留边缘较好,抗高斯噪声强计算量较大图像预处理(如边缘检测前)、高斯噪声去除
    中值滤波cv2.medianBlur()ksize: 滤波核大小(正奇数,如 5)邻域内像素值排序后取中值。有效去除椒盐噪声,保护边缘对大面积连续噪声效果差椒盐噪声、脉冲噪声去除(如老旧照片修复)
    双边滤波cv2.bilateralFilter()d: 邻域直径sigmaColor: 颜色空间标准差sigmaSpace: 坐标空间标准差结合空间邻近度和像素值相似性的加权平均,保留边缘的同时平滑保持边缘清晰,去噪效果好计算速度极慢高精度图像去噪(如人像美化)、边缘敏感场景
    方框滤波cv2.boxFilter()ksize: 核大小normalize: 归一化开关(默认True,同均值滤波)邻域内像素值的和(可归一化为均值滤波)灵活性高(可控制是否归一化)非归一化时易导致数值溢出特殊需求(如积分图计算)、快速均值滤波替代

    示例代码

    import cv2
    import numpy as np
    
    img = cv2.imread('noisy_image.jpg')
    
    # 1. 均值滤波
    blur = cv2.blur(img, (5,5))
    
    # 2. 高斯滤波
    gaussian = cv2.GaussianBlur(img, (5,5), sigmaX=0)
    
    # 3. 中值滤波
    median = cv2.medianBlur(img, 5)
    
    # 4. 双边滤波
    bilateral = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
    
    # 5. 方框滤波(未归一化)
    box_filter = cv2.boxFilter(img, -1, (5,5), normalize=False)
    
    # 显示结果(示例)
    cv2.imshow('Original', img)
    cv2.imshow('Mean Blur', blur)
    cv2.imshow('Gaussian Blur', gaussian)
    cv2.imshow('Median Blur', median)
    cv2.imshow('Bilateral Filter', bilateral)
    cv2.waitKey(0)
    

    在这里插入图片描述

  3. 形态学操作
    用途:处理二值图像,用于去噪、连接区域。

    方法名称函数名称参数说明原理/作用适用场景
    腐蚀 (Erosion)cv2.erode(src, kernel, iterations=1)- kernel: 结构元素(如矩形、椭圆)- iterations: 操作次数用结构元素扫描图像,取邻域内最小值,消除小物体或细化边缘去除噪声、分离粘连物体
    膨胀 (Dilation)cv2.dilate(src, kernel, iterations=1)- kernel: 结构元素- iterations: 操作次数取邻域内最大值,扩大亮区域,连接断裂部分填充孔洞、连接相邻区域
    开运算 (Opening)cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)- kernel: 结构元素先腐蚀后膨胀,消除小噪声并保留原形状。去除亮背景中的暗噪声(如斑点)
    闭运算 (Closing)cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)- kernel: 结构元素先膨胀后腐蚀,填充孔洞并保留原形状填充暗区域中的亮孔洞(如指纹断裂
    形态学梯度 (Morphological Gradient)cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)- kernel: 结构元素膨胀图与腐蚀图的差值,提取物体边缘边缘检测、轮廓增强。
    顶帽 (Top Hat)cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)- kernel: 结构元素原图与开运算的差值,突出比原图更亮的微小区域。检测亮背景中的暗细节(如文本增强)
    黑帽 (Black Hat)cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)- kernel: 结构元素闭运算与原图的差值,突出比原图更暗的微小区域。检测暗背景中的亮细节(如医学图像中的微小病灶)

    参数补充说明
    结构元素 (kernel):
    可通过 cv2.getStructuringElement(shape, size) 创建,shape 可选:
    cv2.MORPH_RECT(矩形)
    cv2.MORPH_ELLIPSE(椭圆)
    cv2.MORPH_CROSS(十字形)
    示例:kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    边界处理:
    默认使用 cv2.BORDER_CONSTANT 填充边界,可通过 borderType 参数修改。

    示例代码:

    import cv2
    import numpy as np
    
    # 读取图像并二值化
    img = cv2.imread('input.png', cv2.IMREAD_GRAYSCALE)
    _, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
    
    # 创建矩形结构元素
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    
    # 腐蚀
    eroded = cv2.erode(binary, kernel, iterations=1)
    
    # 开运算
    opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
    
    # 形态学梯度
    gradient = cv2.morphologyEx(binary, cv2.MORPH_GRADIENT, kernel)
    
    # 显示结果
    cv2.imshow('Original', binary)
    cv2.imshow('Erosion', eroded)
    cv2.imshow('Opening', opening)
    cv2.imshow('Gradient', gradient)
    cv2.waitKey(0)
    

    在这里插入图片描述


总结

本文介绍了轮廓检测,模板匹配,图像平滑(滤波),形态学操作,建议大家结合实际情况选择适合的函数多练习比较.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HC1025

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值