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'):breakcap.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'):breakcap.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 等深度学习框架进行高级计算机视觉任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1538199.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vue scoped解析

不加scoped 加上scoped 从上面的图可以看出,给style加上scoped之后,会给这个模块的所有元素都加上一个自定义属性data-v-xxxx,这个xxxx就是这个文件的相对路径加上文件名生成的hash值,这样就能保证自定义属性独一无二 给所有元…

【C语言进阶】动态内存与柔性数组:C语言开发者必须知道的陷阱与技巧

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C语言 “ 登神长阶 ” 🤡往期回顾🤡:C语言动态内存管理 🌹🌹期待您的关注 🌹🌹 ❀C语言动态内存管理 &…

数据结构入门学习(全是干货)——树(中)

数据结构入门学习(全是干货)——树(中) 1 二叉搜索树(Binary Search Tree,简称 BST) 1.1 二叉搜索树及查找 二叉搜索树(Binary Search Tree, BST) 是一种特殊的二叉树…

【Delphi】实现接收系统拖动文件

在 Delphi 中,可以通过以下步骤来实现将文件夹中的文件拖动到 Form 上,并在拖动时显示文件类型的光标。我们可以利用 VCL 中的 Drag and Drop 机制来处理拖动操作,以及自定义光标显示。 以下是详细的步骤和代码示例: 实现步骤&a…

力扣之181.超过经理收入的员工

文章目录 1. 181.超过经理收入的员工1.1 题干1.2 准备数据1.3 题解1.4 结果截图 1. 181.超过经理收入的员工 1.1 题干 表:Employee -------------------- | Column Name | Type | -------------------- | id | int | | name | varchar | | salary | int | | mana…

在设计开发中,如何提高网站的用户体验?

在网站设计开发中,提高用户体验是至关重要的。良好的用户体验不仅能提升用户的满意度和忠诚度,还能增加转化率和用户留存率。以下是一些有效的方法和策略: 优化页面加载速度 减少HTTP请求:合并CSS和JavaScript文件以减少HTTP请求…

『 Linux 』HTTP(一)

文章目录 域名URLURLEncode和URLDecodeHTTP的请求HTTP的响应请求与响应的获取简单的Web服务器 域名 任何客户端在需要访问一个服务端时都需要一个IP和端口号,而当一个浏览器去访问一个网页时通常更多使用的是域名而不是IP:port的方式, www.baidu.com这是百度的域名; 实际上当浏…

MySQL高阶1777-每家商店的产品价格

题目 找出每种产品在各个商店中的价格。 可以以 任何顺序 输出结果。 准备数据 create database csdn; use csdn;Create table If Not Exists Products (product_id int, store ENUM(store1, store2, store3), price int); Truncate table Products; insert into Products …

音视频入门基础:AAC专题(8)——FFmpeg源码中计算AAC裸流AVStream的time_base的实现

一、引言 本文讲解FFmpeg源码对AAC裸流行解复用(解封装)时,其AVStream的time_base是怎样被计算出来的。 二、FFmpeg源码中计算AAC裸流AVStream的time_base的实现 FFmpeg对AAC裸流进行解复用(解封装)时,其…

通过FUXA在ARMxy边缘计算网关上实现生产优化

在当今工业4.0时代,智能制造的需求日益增长,企业迫切需要通过数字化转型来提高生产效率、降低成本并增强市场竞争力。ARMxy系列的BL340工业级ARM控制器,凭借其强大的处理能力和灵活的配置选项,成为实现生产优化的重要基础。 一、…

io多路复用:epoll水平触发(LT)和边沿触发(ET)的区别和优缺点

在进行ET模式的正式分析之前,我们来举个例子简单地了解下ET和LT: 假设我们通过fork函数创建了父子两个进程,并通过匿名管道来通信,在子进程中,我们一次向管道写入10个字符数据,为"aaaa\nbbbb\n";每隔5s写入…

SmartX 分布式存储产品全新升级,支持文件存储能力与纠删码机制

近日,SmartX 正式发布了 SMTX ZBS 5.6 版本,通过引入对文件存储的支持能力,可作为企业统一存储平台,为大规模虚拟化、私有云、容器等环境提供高可靠、高可用、高性能、易扩展的企业级分布式块存储和分布式文件存储服务。该版本还引…

2024 年至今回顾:The Sandbox 创作者的历程及下一步展望

2024 年上半年是 The Sandbox 令人振奋的旅程!从激动人心的里程碑、丰厚的奖励到创新的功能,我们见证了来自充满活力的社区的惊人创造力。 作为平台的生命线,我们致力于帮助创作者发光发热。让我们深入了解过去六个月中最激动人心的时刻和更…

OpenHarmony(鸿蒙南向开发)——标准系统方案之瑞芯微RK3566移植案例(下)

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ OpenHarmony(鸿蒙南向开发)——轻量系统STM32F407芯片移植案…

MySQL聚合统计和内置函数

【数据库】MySQL聚合统计 王笃笃-CSDN博客https://blog.csdn.net/wangduduniubi?typeblog显示平均工资低于2000的部门和它的平均工资 mysql> select deptno,avg(sal) deptavg from emp group by deptno; --------------------- | deptno | deptavg | --------------…

基于树表的查找

二叉排序树 相关概念 存储结构 查找 具体实现 算法分析 插入 创建 删除 无孩子 有一个孩子 有左右孩子 示例 平衡二叉树 概念 示例 插入调整 类型 由插入结点在失衡结点的位置来定:插入结点C为失衡结点A的左子树的左孩子,因此为LL型。 原则 即选择中…

10.第二阶段x86游戏实战2-反编译自己的程序加深堆栈的理解

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

[C++进阶[六]]list的相关接口模拟实现

1.前言 本章重点 在list模拟实现的过程中&#xff0c;主要是感受list的迭代器的相关实现&#xff0c;这是本节的重点和难点。 2.list接口的大致框架 list是一个双向循环链表&#xff0c;所以在实现list之前&#xff0c;要先构建一个节点类 template <class T> struct L…

Java 中 List 常用类和数据结构详解及案例示范

1. 引言 在 Java 开发中&#xff0c;List 是最常用的数据结构接口之一&#xff0c;它用于存储有序的元素集合&#xff0c;并允许通过索引进行随机访问。电商系统中&#xff0c;如购物车、订单列表和商品目录等功能都依赖 List 进行数据管理。选择适当的 List 实现类能够显著提…