掌握OpenCV Python快速入门指南 – wiki基地


OpenCV Python 快速入门指南:从新手到实践者的进阶之路

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它包含了超过2500种优化算法,可用于处理各种图像和视频相关的任务。从人脸检测、目标跟踪到图像拼接、三维重建,OpenCV 都能提供强大的支持。Python 作为一种简洁、易学且拥有丰富第三方库的语言,与 OpenCV 结合,使得图像处理变得更加高效和便捷。

本指南旨在帮助初学者快速掌握 OpenCV-Python 的基础知识和核心概念,并通过一系列实用的示例,引导你逐步迈入计算机视觉的世界。

1. 安装与配置

在开始之前,我们需要确保正确安装 OpenCV-Python。最简单的方法是使用 pip 包管理器:

bash
pip install opencv-python

如果你需要包含一些额外的贡献模块(例如 SIFT、SURF 等,注意这些算法可能有专利问题),可以使用:

bash
pip install opencv-contrib-python

安装完成后,我们可以在 Python 环境中导入 OpenCV 模块,并验证安装是否成功:

“`python
import cv2
import numpy as np

print(cv2.version)
“`

如果输出了 OpenCV 的版本号,那么恭喜你,环境配置已经完成!

2. 图像基础:读取、显示与保存

图像是 OpenCV 处理的核心对象。在 OpenCV 中,图像被表示为 NumPy 数组,这使得我们可以方便地利用 NumPy 的强大功能进行图像处理。

  • 读取图像:

    使用 cv2.imread() 函数读取图像。该函数接受两个参数:图像文件的路径和读取模式(可选)。

    “`python
    img = cv2.imread(‘image.jpg’) # 默认以彩色模式读取
    gray_img = cv2.imread(‘image.jpg’, cv2.IMREAD_GRAYSCALE) # 以灰度模式读取
    unchanged_img = cv2.imread(‘image.jpg’, cv2.IMREAD_UNCHANGED) # 包含alpha通道

    if img is None:
    print(“Error: 图像未能正确读取”)
    “`
    读取模式包括:

    • cv2.IMREAD_COLOR1: 默认值,加载彩色图像(忽略透明度)。
    • cv2.IMREAD_GRAYSCALE0: 加载灰度图像。
    • cv2.IMREAD_UNCHANGED-1: 加载包含 Alpha 通道的图像(如果有)。
  • 显示图像:

    使用 cv2.imshow() 函数显示图像。该函数接受两个参数:窗口名称和要显示的图像。

    python
    cv2.imshow('Image Window', img)
    cv2.waitKey(0) # 等待按键,参数为等待时间(毫秒),0 表示无限等待
    cv2.destroyAllWindows() # 关闭所有窗口

    cv2.waitKey() 是一个键盘绑定函数。它等待指定的毫秒数以获取键盘输入。如果在这段时间内按下任何键,程序将继续。如果传递 0,它将无限期地等待按键。

  • 保存图像:

    使用 cv2.imwrite() 函数保存图像。该函数接受两个参数:保存的文件名和要保存的图像。

    python
    cv2.imwrite('output.png', img)

3. 图像基本操作:色彩空间转换、几何变换、ROI 操作

  • 色彩空间转换:

    OpenCV 支持多种色彩空间,例如 RGB、BGR、HSV、GRAY 等。使用 cv2.cvtColor() 函数可以在不同色彩空间之间进行转换。

    python
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # BGR 转灰度
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # BGR 转 HSV

    常见的色彩空间转换代码包括:

    • cv2.COLOR_BGR2GRAY: BGR 转灰度
    • cv2.COLOR_BGR2HSV: BGR 转 HSV
    • cv2.COLOR_BGR2RGB: BGR 转 RGB
    • cv2.COLOR_GRAY2BGR: 灰度转 BGR
  • 几何变换:

    OpenCV 提供了多种几何变换,例如缩放、旋转、平移、仿射变换和透视变换。

    • 缩放:

      python
      resized_img = cv2.resize(img, (width, height)) # 指定目标尺寸
      resized_img = cv2.resize(img, None, fx=0.5, fy=0.5) # 使用缩放因子

    • 平移:
      python
      rows, cols = img.shape[:2]
      M = np.float32([[1, 0, 100], [0, 1, 50]]) # 平移矩阵,x方向移动100,y方向移动50
      dst = cv2.warpAffine(img, M, (cols, rows))

    • 旋转:
      python
      rows, cols = img.shape[:2]
      M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1) # 中心点,旋转角度,缩放因子
      dst = cv2.warpAffine(img, M, (cols, rows))

    • 仿射变换:
      需要三个点来定义变换矩阵。
      python
      pts1 = np.float32([[50,50],[200,50],[50,200]])
      pts2 = np.float32([[10,100],[200,50],[100,250]])
      M = cv2.getAffineTransform(pts1,pts2)
      dst = cv2.warpAffine(img,M,(cols,rows))

    • 透视变换
      需要四个点来定义变换矩阵。
      python
      pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
      pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
      M = cv2.getPerspectiveTransform(pts1,pts2)
      dst = cv2.warpPerspective(img,M,(300,300))

  • ROI (Region of Interest) 操作:

    ROI 指图像中感兴趣的区域。通过 NumPy 的切片操作,我们可以轻松地提取和操作 ROI。

    python
    roi = img[100:200, 200:300] # 提取 ROI
    img[0:100, 0:100] = roi # 将 ROI 复制到另一个位置

4. 图像处理:滤波、阈值处理、形态学操作、边缘检测

  • 滤波 (Smoothing/Blurring):

    滤波用于去除图像中的噪声或模糊图像。常见的滤波器包括:

    • 均值滤波: cv2.blur()cv2.boxFilter()
    • 高斯滤波: cv2.GaussianBlur() (对高斯噪声效果好)
    • 中值滤波: cv2.medianBlur() (对椒盐噪声效果好)
    • 双边滤波: cv2.bilateralFilter() (在保持边缘清晰的同时去除噪声)

    python
    blur = cv2.blur(img, (5, 5)) # 5x5 均值滤波
    gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0) # 5x5 高斯滤波,标准差为0
    median_blur = cv2.medianBlur(img, 5) # 5x5 中值滤波
    bilateral_blur = cv2.bilateralFilter(img,9,75,75)

  • 阈值处理:

    阈值处理用于将图像分割成不同的区域。常见的阈值处理方法包括:

    • 简单阈值: cv2.threshold()
    • 自适应阈值: cv2.adaptiveThreshold()
    • Otsu’s 二值化: cv2.threshold() (与 cv2.THRESH_OTSU 结合使用)
      python
      ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) #简单阈值
      adaptive_thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) #自适应阈值
      ret2,otsu_thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #Otsu阈值
  • 形态学操作:

    形态学操作基于图像的形状进行处理。常见的形态学操作包括:

    • 腐蚀: cv2.erode()
    • 膨胀: cv2.dilate()
    • 开运算: cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) (先腐蚀后膨胀,去除小物体)
    • 闭运算: cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) (先膨胀后腐蚀,填充小孔洞)
    • 形态学梯度: cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)(膨胀图减去腐蚀图)
    • 顶帽: cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) (原图减去开运算图)
    • 黑帽: cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)(闭运算图减去原图)

    “`python
    kernel = np.ones((5, 5), np.uint8) # 定义结构元素
    erosion = cv2.erode(img, kernel, iterations=1)
    dilation = cv2.dilate(img, kernel, iterations=1)
    opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

    “`

  • 边缘检测:

    边缘检测用于识别图像中的边缘。常见的边缘检测算子包括:

    • Sobel 算子: cv2.Sobel()
    • Scharr 算子: cv2.Scharr()
    • Laplacian 算子: cv2.Laplacian()
    • Canny 边缘检测: cv2.Canny() (推荐,多阶段算法)

    python
    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5) # x 方向 Sobel
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5) # y 方向 Sobel
    laplacian = cv2.Laplacian(gray, cv2.CV_64F)
    canny = cv2.Canny(gray, 100, 200) # Canny 边缘检测,100 和 200 是阈值

5. 图像特征:角点检测、特征描述

  • Harris 角点检测:

    python
    gray = np.float32(gray)
    dst = cv2.cornerHarris(gray, 2, 3, 0.04) # 检测角点
    dst = cv2.dilate(dst, None) # 膨胀角点标记
    img[dst > 0.01 * dst.max()] = [0, 0, 255] # 标记角点

  • Shi-Tomasi 角点检测:

    python
    corners = cv2.goodFeaturesToTrack(gray, 25, 0.01, 10) # 检测角点
    corners = np.int0(corners)
    for i in corners:
    x, y = i.ravel()
    cv2.circle(img, (x, y), 3, 255, -1) # 绘制角点

  • SIFT (Scale-Invariant Feature Transform) 特征 (可能需要 opencv-contrib-python)
    python
    sift = cv2.SIFT_create()
    keypoints, descriptors = sift.detectAndCompute(gray,None)
    img=cv2.drawKeypoints(gray,keypoints,img)

  • SURF (Speeded-Up Robust Features) 特征 (可能需要 opencv-contrib-python)
    python
    surf = cv2.SURF_create(400) # 400为Hessian阈值
    keypoints, descriptors = surf.detectAndCompute(gray,None)
    img=cv2.drawKeypoints(gray,keypoints,img)

    注意,SIFT和SURF算法受到专利保护。在某些版本的OpenCV中,你可能需要安装opencv-contrib-python,并且可能需要特别注意这些算法的使用许可。

  • FAST (Features from Accelerated Segment Test) 特征
    python
    fast = cv2.FastFeatureDetector_create()
    keypoints = fast.detect(gray,None)
    img2 = cv2.drawKeypoints(img, keypoints, None, color=(255,0,0))

  • BRIEF (Binary Robust Independent Elementary Features) 特征描述
    BRIEF本身不是特征点检测算法,它是一种特征描述符。通常与FAST、SIFT或SURF等检测器一起使用。

  • ORB (Oriented FAST and Rotated BRIEF) 特征
    python
    orb = cv2.ORB_create()
    keypoints, descriptors = orb.detectAndCompute(gray,None)
    img=cv2.drawKeypoints(gray,keypoints,img)

    ORB是一种对SIFT和SURF的有效替代方案,它在计算上更快,并且在许多情况下具有相似的性能。

6. 特征匹配

特征匹配是计算机视觉中的一个重要任务,它用于在不同图像中找到相似的特征点。

  • Brute-Force 匹配
    “`python
    # 使用ORB特征作为例子
    orb = cv2.ORB_create()
    kp1, des1 = orb.detectAndCompute(img1,None)
    kp2, des2 = orb.detectAndCompute(img2,None)

    创建BFMatcher对象

    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    匹配描述符.

    matches = bf.match(des1,des2)

    根据距离排序

    matches = sorted(matches, key = lambda x:x.distance)

    绘制前N个匹配项

    img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10],None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

“`

  • FLANN 匹配
    “`python
    # 使用ORB特征作为例子
    orb = cv2.ORB_create()
    kp1, des1 = orb.detectAndCompute(img1,None)
    kp2, des2 = orb.detectAndCompute(img2,None)

    FLANN 参数

    FLANN_INDEX_LSH = 6
    index_params= dict(algorithm = FLANN_INDEX_LSH,
    table_number = 6, # 12
    key_size = 12, # 20
    multi_probe_level = 1) #2
    search_params = dict(checks=50) # or pass empty dictionary

    flann = cv2.FlannBasedMatcher(index_params,search_params)

    matches = flann.knnMatch(des1,des2,k=2)

    根据Lowe’s ratio test进行筛选

    good = []
    for m,n in matches:
    if m.distance < 0.7*n.distance:
    good.append(m)

    img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,flags=2)
    “`

7. 视频处理基础

OpenCV 不仅可以处理静态图像,还可以处理视频。视频本质上是一系列连续的图像帧。

  • 读取视频:

    使用 cv2.VideoCapture() 函数读取视频。该函数接受一个参数:视频文件的路径或摄像头索引。

    “`python
    cap = cv2.VideoCapture(‘video.mp4’) # 读取视频文件

    cap = cv2.VideoCapture(0) # 打开默认摄像头 (0 表示第一个摄像头)

    if not cap.isOpened():
    print(“Error: 视频/摄像头未能正确打开”)

    while cap.isOpened():
    ret, frame = cap.read() # 读取一帧
    if not ret:
    break # 如果读取失败(例如到达视频结尾),则退出循环

    # 在这里对每一帧进行处理 (例如,转换为灰度)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow('Frame', gray)  # 显示帧
    
    if cv2.waitKey(25) & 0xFF == ord('q'):  # 按 'q' 键退出
        break
    

    cap.release() # 释放资源
    cv2.destroyAllWindows()
    “`

  • 写入视频:
    使用 cv2.VideoWriter()写入视频。
    “`python
    fourcc = cv2.VideoWriter_fourcc(‘XVID’) #或者‘MJPG’, *’MP4V’等,具体取决于你需要的编码
    out = cv2.VideoWriter(‘output.avi’, fourcc, 20.0, (640, 480)) #文件名,编码器,帧率,分辨率

    while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
    break

    # 在这里对每一帧进行处理...
    out.write(frame)
    
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    

    cap.release()
    out.release() # 释放VideoWriter
    cv2.destroyAllWindows()

    “`

8. 总结与进阶

本指南介绍了 OpenCV-Python 的基础知识和核心概念,包括图像的读取、显示、保存、色彩空间转换、几何变换、滤波、阈值处理、形态学操作、边缘检测、特征提取与匹配以及视频处理。通过这些基础知识的学习,你已经具备了使用 OpenCV-Python 进行图像和视频处理的基本能力。

要进一步提高你的技能,建议你:

  • 深入学习 OpenCV 的文档: OpenCV 官方文档提供了详细的 API 参考和教程。
  • 实践项目: 尝试完成一些实际项目,例如人脸识别、目标跟踪、图像拼接等。
  • 学习更高级的计算机视觉技术: 例如目标检测 (YOLO, SSD)、图像分割 (Mask R-CNN)、深度学习与 OpenCV 的结合等。
  • 阅读相关的论文和博客: 了解计算机视觉领域的最新进展。
  • 参与开源社区: 例如在 Stack Overflow 上回答问题,或者为 OpenCV 项目贡献代码。

计算机视觉是一个充满挑战和机遇的领域。希望本指南能够帮助你入门,并激发你对计算机视觉的兴趣。不断学习和实践,你将在这个领域取得更大的成就!

希望这篇文章对你有所帮助! OpenCV 的功能非常强大,这只是一个入门指南。 随着你不断深入学习和实践,你会发现更多有趣的应用和可能性。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部