Skip to content

OpenCV库及其常用函数

安装 openCV 库和学习 openCV 常用函数

重点学习和实践:灰度图、RGB(BGR)和 HSV 色域、二值化、滤波、膨胀腐蚀等形态学操作、开闭运算操作、边缘检测算法、轮廓检测、最小外接矩形、最小外接多边形、霍夫圆、霍夫直线、直方图、透视变换、PnP 解算等

参考资料压缩包发在群里,函数的具体使用方式不用背,只需要知道大致原理和作用。做某个特定任务的时候需要知道用什么图像处理方法,用的时候现查用法就行,关键在于后续项目实践。

图像基础

颜色空间

  • 灰度图:单通道亮度表示,用于简化计算。cv.cvtColor(...,COLOR_BGR2GRAY)

  • RGB/BGR:OpenCV默认BGR存储顺序,注意转换时的通道顺序问题

    • 通道顺序:RGB 是红色、绿色、蓝色,而 BGR 是蓝色、绿色、红色。
    • 显示差异:在图像处理中,如果不正确处理通道顺序,图像颜色可能会显示异常。例如,在 OpenCV 中读取的图像默认是 BGR 格式,如果直接在期望 RGB 输入的函数中使用,可能导致颜色偏差。
  • HSV:色调(Hue)、饱和度(Saturation)和亮度(Value)。

    • 色调(Hue)

      • 定义:色调表示颜色的种类,例如红色、绿色、蓝色等。

      • 范围:在 OpenCV 中,色调的范围通常是 [0, 180](而不是常见的 [0, 360],因为 OpenCV 将其压缩到 0-180 以适应 8 位表示)。

      • 作用:用于区分不同的颜色。例如,红色的色调值通常在 0 和 10 之间,绿色在 40 和 80 之间,蓝色在 100 和 140 之间。

    • 饱和度(Saturation)

      • 定义:饱和度表示颜色的纯度,即颜色中包含的彩色成分的比例。

      • 范围:在 OpenCV 中,饱和度的范围是 [0, 255]。

      • 作用:饱和度越高,颜色越鲜艳;饱和度越低,颜色越接近灰色。
    • 亮度(Value)

      • 定义:亮度表示颜色的明暗程度。

      • 范围:在 OpenCV 中,亮度的范围是 [0, 255]。

      • 作用:亮度越高,颜色越亮;亮度越低,颜色越暗。

    • 转化:

      # BGR 转 HSV
      hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
      # HSV 转 BGR
      bgr_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)
      

图像预处理

  • 二值化:全局阈值(cv.threshold())与自适应阈值(cv.adaptiveThreshold()

    • ret, dst = cv2.threshold(src, thresh, maxval, type)

      • src :表示输入图像,通常是灰度图像(单通道图像)。它是进行阈值处理的对象,例如一张包含各种灰度值的图片。
      • thresh :指设定的阈值。这是一个数值,用于与图像中的像素值进行比较,从而决定像素值在阈值处理后的变化。例如,设置阈值为 127,那么图像中像素值大于或等于 127 的像素会被处理成一种情况,小于 127 的像素会被处理成另一种情况。
      • maxval :表示最大值。当像素值满足一定条件(根据阈值类型决定)时,该像素会被设置为这个最大值。例如,在二值化阈值处理(cv2.THRESH_BINARY 类型)中,如果像素值大于阈值,则会被设置为这个最大值,否则会被设置为 0。
      • type :表示阈值类型,决定了像素值如何根据阈值进行调整,常见的类型有:

      • cv2.THRESH_BINARY :二值化阈值处理。如果像素值大于阈值(thresh),则将其设置为最大值(maxval),否则设置为 0。

      • cv2.THRESH_BINARY_INV :反二值化阈值处理。与二值化相反,如果像素值大于阈值,则设置为 0,否则设置为最大值。
      • cv2.THRESH_TRUNC :截断阈值处理。如果像素值大于阈值,则将其设置为阈值,否则保持原值不变。例如,像素值范围在 [0,255],阈值为 100,处理后像素值大于 100 的部分都会变成 100,小于等于 100 的部分不变。
      • cv2.THRESH_TOZERO :置零阈值处理。如果像素值大于阈值,则保持原值,否则设置为 0。
      • cv2.THRESH_TOZERO_INV :反置零阈值处理。如果像素值大于阈值,则设置为 0,否则保持原值。

      • ret :返回的阈值。在简单阈值处理中,它与输入的阈值(thresh)相同;但在自适应阈值处理等复杂场景下,可能会根据算法重新计算阈值并返回。

      • dst :表示输出的阈值处理后的图像。这个图像的像素值是根据设定的阈值和阈值类型进行处理后得到的结果,与输入图像具有相同的大小和类型。
  • 滤波

    • 均值滤波:用邻域内像素的平均值替代原像素点,使图像模糊,减少噪声,但易丢失细节。

    • 方框滤波:与均值滤波类似,不过不进行归一化,计算简单,效果也使图像模糊。

    • 方框滤波+归一化:对图像求和后进行归一化处理,使像素值整体保持稳定。

    • 高斯滤波:利用高斯核对图像加权平均,模糊图像的同时较好地保留边缘信息。

    • 中值滤波:用邻域内像素的中值替代原像素点,对椒盐噪声有很好的去除效果。

    # 均值滤波
    # 简单的平均卷积操作
    blur = cv2.blur(img, (3, 3))
    
    # 方框滤波
    # 基本和均值一样,可以选择归一化
    box = cv2.boxFilter(img,-1,(3,3), normalize=True)  
    box = cv2.boxFilter(img,-1,(3,3), normalize=False) # 容易越界
    
    # 高斯滤波
    # 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
    aussian = cv2.GaussianBlur(img, (5, 5), 1)  
    
    # 中值滤波
    # 相当于用中值代替
    median = cv2.medianBlur(img, 5)  # 中值滤波
    

形态学操作

  • 腐蚀:通过结构元素处理二值图像,腐蚀消除噪点

  • 原理

    腐蚀操作使用一个称为“核”(kernel)的结构元素在图像上滑动,对每个像素点进行处理。核是一个小的矩阵,通常填充为 1。腐蚀操作的规则如下:

    1. 核的中心:核的中心对准图像中的一个像素点。
    2. 逐元素比较:将核中的每个元素与对应的图像像素进行逐元素比较。
    3. 取最小值:如果核中的所有元素对应的图像像素值都大于或等于某个值,则该中心像素的值保持不变;否则,该中心像素的值被设置为核中最小的值(通常是 0)。
  • 腐蚀操作主要用于

    • 去除噪声:减少图像中的小白色噪声。

    • 分离对象:将粘连在一起的前景对象分开。

    • 细化边界:细化前景对象的边界。

  • 代码参数讲解

    import cv2
    import numpy as np
    
    # 创建一个 3x3 的核,元素全为 1
    kernel = np.ones((3, 3), np.uint8)
    
    # 对图像进行腐蚀操作,迭代次数为 1
    erosion = cv2.erode(img, kernel, iterations=1)
    

    kernel = np.ones((3, 3), np.uint8)

    • np.ones((3, 3), np.uint8):创建一个 3×3 的矩阵,所有元素初始化为 1。

    • 作用:定义一个结构元素(核),用于在腐蚀操作中与图像进行逐元素比较。

    • 例子

    kernel = [
      [1, 1, 1],
      [1, 1, 1],
      [1, 1, 1]
    ]
    

    cv2.erode(img, kernel, iterations=1)

    • img:输入图像,通常是二值化图像(黑白图像)。
    • kernel:结构元素(核),用于定义腐蚀操作的形状和大小。
    • iterations:腐蚀操作的迭代次数。默认值为 1,表示只进行一次腐蚀操作。增加迭代次数会多次应用腐蚀操作,进一步细化图像。
  • 膨胀:通过结构元素处理二值图像,膨胀填充空洞

  • 原理

    膨胀操作是一种用于扩大图像中前景对象(白色区域)的形态学处理技术。它通过使用一个称为“核”(kernel)的结构元素来实现,核在图像上滑动,处理每个像素点。膨胀操作的规则如下:

    1. 核的中心对准像素:将核的中心对准图像中的一个像素点。
    2. 逐元素比较:将核中的每个元素与对应的图像像素进行逐元素比较。
    3. 取最大值:如果核中至少有一个元素对应的图像像素值大于或等于某个值,则该中心像素的值被设置为核中的最大值(通常是 255)。
  • 膨胀操作主要用于

    • 填充空洞:填充前景对象中的小黑点或空洞。
    • 连接对象:将断开的前景对象连接在一起。
    • 扩大边界:扩大前景对象的边界。
  • 代码参数详解

    import cv2
    import numpy as np
    
    # 创建一个 3x3 的核,元素全为 1
    kernel = np.ones((3, 3), np.uint8)
    
    # 对图像进行膨胀操作,迭代次数为 1
    dige_dilate = cv2.dilate(dige_erosion, kernel, iterations=1)
    

    kernel = np.ones((3, 3), np.uint8)

    • 创建一个 3×3 的矩阵,所有元素初始化为 1。
    • 这个矩阵定义了膨胀操作的形状和大小,用于在图像上滑动并处理像素。

    cv2.dilate(dige_erosion, kernel, iterations=1)

    • dige_erosion:输入图像,通常是经过腐蚀操作后的图像。可以是任何二值化图像(黑白图像)。
    • kernel:结构元素(核),用于定义膨胀操作的形状和大小。
    • iterations:膨胀操作的迭代次数。默认值为 1,表示只进行一次膨胀操作。增加迭代次数会多次应用膨胀操作,进一步扩大图像中的白色区域。
  • 开闭运算:开运算(先腐蚀后膨胀)去孤立噪点,闭运算(先膨胀后腐蚀)补闭合区域

# 开:先腐蚀,再膨胀
img = cv2.imread('dige.png')

kernel = np.ones((5,5),np.uint8) 
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 闭:先膨胀,再腐蚀
img = cv2.imread('dige.png')

kernel = np.ones((5,5),np.uint8) 
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

边缘检测与轮廓分析

边缘检测

——Canny算法(双阈值检测+非极大抑制),关注梯度计算与参数调节

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。

轮廓处理

  • cv.findContours()获取轮廓层级结构
  • 最小外接矩形(cv.minAreaRect())与旋转角度检测
  • 多边形逼近(cv.approxPolyDP())用于形状简化

5. 特征检测

  • 霍夫变换
  • 直线检测(累计空间投票机制,调节rho/theta精度)
  • 圆检测(三维参数空间,注意梯度计算优化)
  • 直方图:颜色分布统计(cv.calcHist()),直方图均衡化(cv.equalizeHist()

6. 图像变换

  • 透视变换:通过4点映射实现文档校正等应用(cv.getPerspectiveTransform()
  • PnP解算:结合3D点云与2D图像求解相机位姿(cv.solvePnP()

7. 实践路径

  1. 基础实验:实现证件照背景替换(颜色空间+轮廓处理)
  2. 中级项目:文档扫描仪(边缘检测+透视校正)
  3. 进阶应用:AR物体定位(特征匹配+PnP解算)

8. 高效学习方法

  • API查询技巧:善用help(cv2.function)查看参数说明
  • 调试要点
  • 形态学操作时注意结构元素尺寸选择
  • 轮廓分析前确保二值图像质量
  • 透视变换后添加插值处理(INTER_LINEAR
  • 资源推荐
  • 官方文档的模块化结构(core/imgproc/highgui等)
  • OpenCV-Python Tutorials实战案例