Python 课程16-OpenCV

前言

OpenCV(Open Source Computer Vision Library)是一个广泛使用的开源计算机视觉库,旨在为实时图像处理提供高效的计算工具。它提供了数百种算法和函数,用于处理图像和视频。OpenCV 在工业、学术研究和个人项目中应用广泛,适用于各种任务,如对象检测、图像增强、计算机视觉中的机器学习等。

在本教程中,我们将详细介绍 OpenCV 的常用功能,包括图像处理、视频处理以及如何结合其他机器学习框架(如 TensorFlow 和 PyTorch)进行应用。


目录

  1. OpenCV 基础

    • 安装 OpenCV
    • 读取与显示图像
    • 保存图像与视频
    • 调整图像尺寸与裁剪
  2. 图像处理

    • 图像颜色空间转换
    • 图像平滑与滤波
    • 边缘检测与轮廓检测
    • 图像几何变换
  3. 对象检测与跟踪

    • 使用 Haar 级联分类器进行人脸检测
    • 使用深度学习模型进行对象检测
    • 视频跟踪与运动检测
  4. 高级功能

    • OpenCV 与机器学习(TensorFlow、PyTorch)
    • 使用 OpenCV 进行相机校准与立体视觉
    • 图像分割与图像形态学操作

1. OpenCV 基础

安装 OpenCV

你可以使用 pip 安装 OpenCV:

pip install opencv-python

 安装带有 contrib 模块 的 OpenCV:

pip install opencv-contrib-python

导入 OpenCV:

import cv2
读取与显示图像

OpenCV 提供了简单的函数来读取和显示图像:

  • 读取图像
# 读取一张图像
image = cv2.imread('image.jpg')

# 打印图像的形状(高度、宽度、通道)
print(image.shape)
  •  显示图像
# 显示图像
cv2.imshow('Image', image)

# 等待按键输入,然后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
保存图像与视频
  • 保存图像
# 保存图像
cv2.imwrite('output.jpg', image)
  •  保存视频
# 定义视频编解码器并创建 VideoWriter 对象
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

# 写入视频帧
out.write(image)  # 假设 image 是一个视频帧
out.release()  # 释放 VideoWriter
调整图像尺寸与裁剪
  • 调整图像尺寸
# 调整图像大小为 300x300
resized_image = cv2.resize(image, (300, 300))
  •  裁剪图像
# 裁剪图像的区域
cropped_image = image[50:200, 100:300]  # 从 (50, 100) 到 (200, 300) 的区域


2. 图像处理

图像颜色空间转换

OpenCV 支持多种颜色空间,如 BGR、RGB、HSV、灰度等。你可以轻松转换图像的颜色空间:

  • BGR 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  •  BGR 转换为 HSV
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

边缘检测与轮廓检测

OpenCV 提供了 Canny 边缘检测轮廓检测 来识别图像中的对象轮廓。

  • Canny 边缘检测
edges = cv2.Canny(image, 100, 200)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
  •  查找轮廓
# 转换为灰度图像并进行二值化
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)

# 查找轮廓
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
cv2.imshow('Contours', image)
cv2.waitKey(0)

图像几何变换

你可以对图像进行几何变换,如旋转、平移、缩放等。

  • 图像旋转
(h, w) = image.shape[:2]
center = (w // 2, h // 2)

# 旋转图像 45 度
matrix = cv2.getRotationMatrix2D(center, 45, 1.0)
rotated_image = cv2.warpAffine(image, matrix, (w, h))
  •  图像平移
# 定义平移矩阵,将图像向右移动 50 像素,向下移动 100 像素
M = np.float32([[1, 0, 50], [0, 1, 100]])
shifted_image = cv2.warpAffine(image, M, (w, h))


3. 对象检测与跟踪

使用 Haar 级联分类器进行人脸检测

OpenCV 提供了 Haar 级联分类器,适用于快速检测人脸或其他对象。

  • 加载预训练的 Haar 分类器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 检测人脸
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5)

# 绘制检测到的人脸
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)

cv2.imshow('Faces', image)
cv2.waitKey(0)

使用深度学习模型进行对象检测

OpenCV 支持加载深度学习模型进行对象检测,如 YOLOSSD 等。

  • 加载 YOLO 模型
# 加载 YOLO 模型的配置和权重
net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')

# 加载对象类别名称
with open('coco.names', 'r') as f:
    classes = f.read().splitlines()

# 读取输入图像并进行预处理
blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)

# 获取 YOLO 输出
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
detections = net.forward(output_layers)

# 解析并显示检测结果
for detection in detections:
    for obj in detection:
        confidence = obj[4]
        if confidence > 0.5:
            # 显示检测到的对象
            print("Detected object with confidence:", confidence)

视频跟踪与运动检测

OpenCV 提供了多种视频跟踪算法,如 CSRTKCF,并可以检测运动。

  • 使用 CSRT 进行视频跟踪
tracker = cv2.TrackerCSRT_create()

# 初始化视频流
cap = cv2.VideoCapture('video.mp4')

# 选择目标
ret, frame = cap.read()
bbox = cv2.selectROI('Tracking', frame, fromCenter=False)
tracker.init(frame, bbox)

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

    # 更新跟踪器
       success, bbox = tracker.update(frame)

    # 如果跟踪成功,绘制边界框
    if success:
        x, y, w, h = map(int, bbox)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(frame, 'Tracking', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    else:
        cv2.putText(frame, 'Lost', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

    # 显示视频帧
    cv2.imshow('Tracking', frame)

    # 退出条件:按下 "q" 键
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

  •  运动检测(背景减法)

背景减法 是运动检测中常用的技术。OpenCV 提供了 cv2.createBackgroundSubtractorMOG2()cv2.createBackgroundSubtractorKNN() 两种方法来检测运动区域。 

# 创建背景减法器
bg_subtractor = cv2.createBackgroundSubtractorMOG2()

# 打开视频流
cap = cv2.VideoCapture('video.mp4')

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

    # 应用背景减法
    fg_mask = bg_subtractor.apply(frame)

    # 显示前景掩膜
    cv2.imshow('Foreground Mask', fg_mask)

    # 退出条件:按下 "q" 键
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

通过背景减法器,我们可以检测视频中的运动物体,适合用于安防监控或物体跟踪等任务。


4. 高级功能

OpenCV 与机器学习(TensorFlow、PyTorch)

OpenCV 可以与深度学习框架如 TensorFlowPyTorch 结合使用,实现计算机视觉中的高级任务。你可以使用这些框架来构建深度学习模型,然后使用 OpenCV 进行推理和处理图像。

  • 使用 TensorFlow 进行图像分类

假设我们已经训练了一个图像分类模型,可以通过 TensorFlow 加载该模型,并使用 OpenCV 处理输入图像。

import tensorflow as tf
import cv2

# 加载 TensorFlow 模型
model = tf.keras.models.load_model('my_model.h5')

# 读取并预处理图像
image = cv2.imread('image.jpg')
resized_image = cv2.resize(image, (224, 224))  # 假设模型输入尺寸为 224x224
input_image = resized_image / 255.0  # 归一化处理
input_image = input_image.reshape(1, 224, 224, 3)  # 增加批次维度

# 进行预测
predictions = model.predict(input_image)
print('Predictions:', predictions)
  • 使用 PyTorch 进行对象检测

你也可以使用 PyTorch 构建深度学习模型,并将 OpenCV 作为图像预处理和后处理工具。

import torch
import torchvision.transforms as transforms
from PIL import Image

# 加载 PyTorch 模型
model = torch.load('my_model.pth')
model.eval()

# 使用 OpenCV 读取图像并转换为 PIL 图像
image = cv2.imread('image.jpg')
image_pil = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

# 定义图像转换
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 应用转换
input_tensor = transform(image_pil).unsqueeze(0)  # 增加批次维度

# 进行预测
with torch.no_grad():
    predictions = model(input_tensor)
    print('Predictions:', predictions)

使用 OpenCV 进行相机校准与立体视觉

相机校准 是计算机视觉中的一个常见任务,目的是校正相机的光学失真。OpenCV 提供了方便的工具来实现相机校准。

  • 相机校准

假设你有一组棋盘图像,可以通过这些图像进行相机校准。

import numpy as np
import cv2

# 设置棋盘角点的尺寸
chessboard_size = (9, 6)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# 准备世界坐标系的棋盘点
objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2)

# 用于存储对象点和图像点
objpoints = []  # 3D 点
imgpoints = []  # 2D 点

# 读取棋盘图像
images = ['chessboard1.jpg', 'chessboard2.jpg']  # 替换为实际图像路径

for image_path in images:
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 查找棋盘角点
    ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)

    if ret:
        objpoints.append(objp)

        # 提高角点的准确性
        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
        imgpoints.append(corners2)

        # 显示角点
        cv2.drawChessboardCorners(img, chessboard_size, corners2, ret)
        cv2.imshow('Chessboard Corners', img)
        cv2.waitKey(500)

# 进行相机校准
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
print('Camera Matrix:', camera_matrix)
print('Distortion Coefficients:', dist_coeffs)

cv2.destroyAllWindows()

通过相机校准,你可以获得相机的内参(如焦距、主点位置)和畸变系数,从而校正拍摄的图像。

  • 立体视觉与深度图

你还可以使用 OpenCV 实现立体视觉,通过两台相机捕捉的图像计算深度信息。

# 假设你已经捕获了左图和右图
imgL = cv2.imread('left_image.jpg', 0)
imgR = cv2.imread('right_image.jpg', 0)

# 创建 SGBM 立体匹配对象
stereo = cv2.StereoSGBM_create(minDisparity=0, numDisparities=16, blockSize=15)

# 计算视差图
disparity = stereo.compute(imgL, imgR)

# 显示视差图
cv2.imshow('Disparity', disparity)
cv2.waitKey(0)
cv2.destroyAllWindows()

视差图可以反映图像中各个像素的深度信息,常用于 3D 建模和场景重建。

图像分割与图像形态学操作

图像分割 是将图像划分为不同区域或对象的过程。图像形态学操作 可以用于提取对象的形状特征。

  • 分水岭算法进行图像分割
# 转换为灰度图并进行二值化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 应用形态学操作
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2)

# 确定背景区域
sure_bg = cv2.dilate(opening, kernel, iterations=3)

# 寻找前景区域
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)

# 确定未知区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

# 标记连接的组件
ret, markers = cv2.connectedComponents(sure_fg)

# 增加1,确保背景为 1,前景为其他值
markers = markers + 1

# 将未知区域标记为 0
markers[unknown == 255] = 0

# 应用分水岭算法
markers = cv2.watershed(image, markers)

# 将边界标记为红色
image[markers == -1] = [0, 0, 255]

cv2.imshow('Watershed Segmentation', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

结论

通过本详细的 OpenCV 教程,你已经学习了从基本的图像与视频处理到高级的对象检测、分割和形态学操作。你掌握了如何读取、保存和显示图像,并通过颜色空间转换、滤波、边缘检测等图像处理技术对图像进行分析。同时,我们还讨论了如何利用 OpenCV 进行对象跟踪和运动检测,以及如何结合 TensorFlowPyTorch 等深度学习框架进行高级计算机视觉任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值