OpenCV 图像与视频的基础操作

news2024/11/18 15:44:30

文章目录

    • 引言
    • 创建和显示窗口
    • 如何通过 OpenCV 加载图片问题
    • 加载图片存在的问题
    • 如何通过 openCV 保存图片(保存图片)
    • 如何通过 OpenCV 保存图片
    • 如何利用 OpenCV 从摄像头采集视频(读取视频文件)
    • 如何从多媒体文件中读取视频帧(读取视频文件)
    • 如何将视频数据录制成多媒体文件(视频录制)
    • 代码优化
    • OpenCV 控制鼠标
    • OpenCV 中的 TrackBar 控件
    • 总结

引言

在计算机视觉领域,OpenCV是一款广泛使用的开源库,用于图像处理和计算机视觉任务。当你开始使用OpenCV时,了解如何创建和显示窗口,以及加载和保存图片是至关重要的基础知识。本文将介绍如何使用OpenCV进行这些操作,帮助你更好地掌握图像处理和视觉任务的开发技巧。

创建和显示窗口

创建和显示窗口是图像处理中的重要步骤之一。在OpenCV中,你可以使用一些简单而强大的函数来完成这些操作。让我们来详细了解一下这些函数:

  1. namedWindow() - 创建一个窗口,并指定窗口的名称和类型。
  2. resizeWindow() - 调整窗口的大小,接受窗口名称、宽度和高度作为参数。
  3. imshow() - 在指定的窗口中显示图像,接受窗口名称和要显示的图像作为参数。
  4. waitKey() - 等待键盘输入,接受等待时间(以毫秒为单位)作为参数,0表示无限等待用户的键盘输入。
  5. destroyAllWindows() - 关闭所有窗口。

下面是一个完整的示例代码:

import cv2  
cv2.namedWindow('new', cv2.WINDOW_NORMAL)  
cv2.resizeWindow('new', 640, 480)  
cv2.imshow("new", 0)  
  
key = cv2.waitKey(0)  
if(key == 'q'):  
	exit()  
  
cv2.destroyAllWindows()

在这里插入图片描述

如何通过 OpenCV 加载图片问题

加载图像是使用 OpenCV 进行图像处理的常见操作之一。在下面的示例中,我们将了解如何使用 OpenCV 加载图像:

  1. im == image - 在代码中,im代表图像对象,通常用于存储加载的图像数据。

  2. imread(path, flag) - 这是一个用于读取图像文件的函数。它接受两个参数:path表示图像文件的路径,flag表示读取图像的方式。常见的flag选项包括:

    • cv2.IMREAD_COLOR:加载彩色图像。
    • cv2.IMREAD_GRAYSCALE:以灰度模式加载图像。
    • cv2.IMREAD_UNCHANGED:加载图像,包括 alpha 通道。

在下面的示例代码中,我们将加载名为 sample.jpg 的图像文件并显示出来:

import cv2

cv2.namedWindow('img', cv2.WINDOW_NORMAL)
img = cv2.imread('sample.jpg')
cv2.imshow('img', img)

key = cv2.waitKey(0)
if key == ord('q'):
    exit()

cv2.destroyAllWindows()

在这里插入图片描述

加载图片存在的问题

在原始代码中,存在一些问题需要解决,包括语法检测、跨平台路径访问以及程序退出逻辑。下面是对这些问题进行优化的详细解释和示例代码:

存在的问题:

  1. 语法检测有问题:原始代码中的缩进存在问题,影响代码的可读性和执行。

  2. Windows 下访问图片的路径与 Mac/Linux 不同:在不同的操作系统中,访问文件的路径表示方式可能有所差异。需要注意在不同平台上正确指定图像文件的路径。

  3. 程序退出的逻辑有问题:原始代码中使用key == 'q'来检测用户是否按下 ‘q’ 键退出程序,但实际上waitKey()函数返回的是一个整数值。正确的做法是将键码与 'q' 的 ASCII 码值进行比较。

以下是优化后的代码示例:

import cv2

cv2.namedWindow('img', cv2.WINDOW_NORMAL)
img = cv2.imread('sample.jpg')
cv2.imshow('img', img)

key = cv2.waitKey(0)

if key & 0xFF == ord('q'):
    exit()

cv2.destroyAllWindows()

通过以上改进,我们解决了原始代码中存在的语法检测、跨平台路径访问和程序退出逻辑的问题。这样的优化使代码更具可读性和可靠性。

如何通过 openCV 保存图片(保存图片)

如何通过 OpenCV 保存图片

在OpenCV中,可以使用imwrite()函数来保存图片。该函数接受两个参数:要保存的文件名和要保存的图像(以OpenCV中的Mat类型表示)。你可以指定保存的文件名和文件格式(如.jpg、.png等),并将图像数据作为参数传递给imwrite()函数,即可将图像保存到指定的文件中。

  • imwrite(name, img)
    • name,要保存的文件名
    • img,是 Mat 类型
import cv2  
cv2.namedWindow('img', cv2.WINDOW_NORMAL)  
  
img = cv2.imread('sample.jpg')  
cv2.imshow("img", img)  
  
key = cv2.waitKey(0)  
  
if(key & 0xFF == ord('q')):  
	cv2.destroyAllWindows()  
elif(key & 0xFF == ord('s')):  
	cv2.imwrite('sample.png', img) # 改了一下文件格式

改善后的代码:

import cv2  
cv2.namedWindow('img', cv2.WINDOW_NORMAL)  
  
img = cv2.imread('sample.jpg')  
  
while True:  
cv2.imshow("img", img)  
  
key = cv2.waitKey(0)  
  
if(key & 0xFF == ord('q')):  
	break  
elif(key & 0xFF == ord('s')):  
	cv2.imwrite('sample.png', img) # 改了一下文件格式  
else:  
	print(key)  
  
cv2.destroyAllWindows()

如何利用 OpenCV 从摄像头采集视频(读取视频文件)

在许多计算机视觉应用中,从摄像头采集视频是一个常见的任务。OpenCV提供了简单而强大的函数来实现这个目标。下面我们将介绍如何利用OpenCV从摄像头读取视频帧。

  • VideoCapture():用于获取视频设备。它接受一个参数index,表示要使用的视频设备的索引。通常情况下,索引为0表示使用默认的摄像头。
  • cap.read():用于从摄像头读取视频帧。
    • 返回两个值,第一个为状态值,读到帧为 true
    • 第二个值为视频帧
  • cap.release():用于释放VideoCapture对象。在程序结束时,应该调用该函数释放占用的资源。

下面是一个完整的示例代码,展示了如何利用OpenCV从摄像头采集视频并实时显示:

import cv2

# 创建窗口
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)

# 获取视频设备
cap = cv2.VideoCapture(0)

while True:
    # 从摄像头读视频帧
    ret, frame = cap.read()

    # 将视频帧在窗口中显示
    cv2.imshow('video', frame)

    # 等待键盘时间,如果为q,退出
    key = cv2.waitKey(1)    # 设置1ms,最低为1ms
    if(key & 0xFF == ord('q')):
        break

# 释放 VideoCapture
cap.release()
cv2.destroyAllWindows()

如何从多媒体文件中读取视频帧(读取视频文件)

除了从摄像头采集视频帧,OpenCV还提供了读取视频文件中的视频帧的功能。下面我们将介绍如何使用cv2.VideoCapture()函数从多媒体文件中读取视频帧。

  • cv2.VideoCapture() 从视频文件中读取视频帧

下面是一个完整的示例代码,展示了如何从视频文件中读取视频帧并显示:

import cv2

# 创建窗口
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)

# 获取视频设备/从视频文件中读取视频帧
cap = cv2.VideoCapture("sample.mp4")

while True:
    # 从摄像头读视频帧
    ret, frame = cap.read()

    # 将视频帧在窗口中显示
    cv2.imshow('video', frame)

    # 等待键盘时间,如果为q,退出
    key = cv2.waitKey(40)    # 设置1ms,最低为1ms
    if(key & 0xFF == ord('q')):
        break

# 释放 VideoCapture
cap.release()
cv2.destroyAllWindows()

如何将视频数据录制成多媒体文件(视频录制)

OpenCV提供了VideoWriter类,可以将视频数据录制成多媒体文件。

  • VideoWriter
    • 参数一为输出文件
    • 参数二为多媒体文件格式(VideoWriter_fourcc
    • 参数三为帧率
    • 参数四为分辨率大小
  • write
  • release

下面是使用VideoWriter类进行视频录制的示例代码:

import cv2

# 创建 VideoWriter 为写多媒体文件
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
vw = cv2.VideoWriter('./out.mp4', fourcc, 25, (1280, 720))   # 分辨率要按照真实摄像头分辨率填写

# 创建窗口
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)

# 获取视频设备/从视频文件中读取视频帧
cap = cv2.VideoCapture(0)

while True:
    # 从摄像头读视频帧
    ret, frame = cap.read()

    # 将视频帧在窗口中显示
    cv2.imshow('video', frame)

    # 写数据到多媒体文件
    vw.write(frame)

    # 等待键盘时间,如果为q,退出
    key = cv2.waitKey(1)    # 设置1ms,最低为1ms
    if(key & 0xFF == ord('q')):
        break

# 释放 VideoCapture
cap.release()

# 释放VideoWriter
vw.release()

cv2.destroyAllWindows()

代码优化

在下面的代码中,我们对代码进行了优化以解决一些问题:

  • 显示窗口为什么变大了?
  • 使用 isOpened() 判断摄像头是否已打开
  • 采集数据时要判断数据是否获取到了
import cv2

# 创建 VideoWriter 为写多媒体文件
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
vw = cv2.VideoWriter('./out.mp4', fourcc, 25, (1280, 720))   # 分辨率要按照真实摄像头分辨率填写

# 创建窗口
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)

# 获取视频设备/从视频文件中读取视频帧
cap = cv2.VideoCapture(0)

while cap.isOpened():   # ⭐判断摄像头是否打开
    # 从摄像头读视频帧
    ret, frame = cap.read()

    if ret == True: # ⭐判断是否获取到数据
        # 将视频帧在窗口中显示
        cv2.imshow('video', frame)
        cv2.resizeWindow('video', 640, 480) # ⭐窗口变大了

        # 写数据到多媒体文件
        vw.write(frame)

        # 等待键盘时间,如果为q,退出
        key = cv2.waitKey(1)    # 设置1ms,最低为1ms
        if(key & 0xFF == ord('q')):
            break
    else:
        break

# 释放 VideoCapture
cap.release()

# 释放VideoWriter
vw.release()

cv2.destroyAllWindows()

OpenCV 控制鼠标

下面将了解如何使用 OpenCV 控制鼠标。具体来说,我们将了解如何设置鼠标回调函数,以便在鼠标事件发生时执行特定的操作。

设置鼠标回调函数

  • setMouseCallback(winname, callback, userdata)
  • callback(event, x, y, flags, userdata)
    • event:鼠标移动,按下左键
    • x,y:鼠标左键
    • flags:鼠标键及组合键

下面是一个完整的示例代码,演示了如何设置鼠标回调函数并在窗口中显示鼠标事件的信息:

import cv2
import numpy as np


# 鼠标回调函数
def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)

# mouse_callback(1, 100, 100, 16, "666")

# 创建窗口
cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 640, 360)

# 设置鼠标回调
cv2.setMouseCallback('mouse', mouse_callback, "123")

# 显示窗口和背景
img = np.zeros((360, 640, 3), np.uint8) # 全黑图片
while True:
    cv2.imshow('mouse', img)
    key = cv2.waitKey(1)
    if key & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

OpenCV 中的 TrackBar 控件

TrackBar 是 OpenCV 提供的一个图形用户界面控件,用于在窗口中创建滑动条,通过滑动条可以动态调整某个参数的值。下面将介绍如何在 OpenCV 中使用 TrackBar 控件。

在这里插入图片描述

  • createTrackbar
    • trackbarname,winname
    • value:trackbar 当前值
    • count:最小值为0,最大值为 count
    • callback,userdata
  • getTrackbarPos
    • 输入参数:trackbarname
    • 输入参数:winname
    • 输出:当前值

在下面代码中,我们将创建了一个名为 ‘trackbar’ 的窗口,并在其中创建了三个 TrackBar,分别用于控制红、绿、蓝三个通道的值。每个 TrackBar 的取值范围为 0~255。我们还创建了一个背景图片,其颜色将根据 TrackBar 的值进行实时更新。

import cv2
import numpy as np


def callback():
    pass

# 创建窗口
cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)

# 创建 trackbar
cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)

# 创建一个背景图片
img = np.zeros((480, 640, 3), np.uint8) # 黑色背景

while True:

    # 获取当前 trackbar 的值
    r = cv2.getTrackbarPos('R', 'trackbar')
    g = cv2.getTrackbarPos('G', 'trackbar')
    b = cv2.getTrackbarPos('B', 'trackbar')

    # 改变背景图片颜色
    img[:] = [b, g, r]  # img[:] 表示所有像素
    cv2.imshow('trackbar', img)

    key = cv2.waitKey(10)
    if key & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

总结

这篇博客简单介绍了 OpenCV 的OpenCV 图像与视频的基础操作,包括窗口创建、图像加载和保存、摄像头视频采集以及多媒体文件录制等内容。同时,还提供了代码优化技巧以及鼠标交互和 TrackBar 控件的应用。通过阅读这篇博客,读者可以全面了解 OpenCV 的功能和用法,掌握图像处理的基本技能。

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

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

相关文章

52、基于51单片机脉搏心率报警LCD 1602显示系统设计(程序+原理图+PCB图+Proteus仿真+参考论文+开题报告+任务书+外文文献+元器件清单等)

摘 要 脉搏心率测量仪在我们的日常生活中已经得到了非常广泛的应用,通过观测脉搏信号,可以对人体的健康进行检查,通常被用于保健中心和医院。为了提高脉搏测量仪的简便性和精确度,本课题设计了一种基于51单片机的脉搏测量仪。系统以51单片机…

C++设计模式 - 创建型模式之工厂模式

文章目录 C设计模式 - 创建型模式之工厂模式接口和针对接口编程 1. 简单工厂模式适用场合UML代码示例 2. 工厂方法模式适用场合UML代码示例 3. 抽象工厂模式适用场合UML代码示例 总结 C设计模式 - 创建型模式之工厂模式 工厂模式属于创建型模式,大致可以分为三类&a…

【Linux】信号量(基于环形队列的生产消费模型)

文章目录 POSIX信号量一、什么是信号量二、信号量接口1.初始化信号量2.销毁信号量3.申请信号量(等待信号量)4.释放信号量(发布信号量) 基于环形队列的生产消费模型一、结构介绍二、理论讲解三、代码实现 总结 POSIX信号量 POSIX信…

C语言之操作符详解

本章重点 1. 各种操作符的介绍 2. 表达式求值 给大家提到一些操作符,下面我们来给大家详细介绍 首先看算术操作符,其他几个都没什么可讲的我们来重点看一下/(除法) 整数除法(除号的两端都是整数) 浮点…

【漏洞复现】Apache RocketMQ 命令注入漏洞(CVE-2023-33246)

文章目录 前言声明一、漏洞描述二、漏洞危害三、影响版本四、环境搭建五、漏洞复现六、修复建议 前言 RocketMQ 是阿里巴巴在2012年开发的分布式消息中间件,专为万亿级超大规模的消息处理而设计,具有高吞吐量、低延迟、海量堆积、顺序收发等特点。同时它…

Shell脚本查询进程并kill进程(集群版)

记录:454 场景:使用Shell脚本查询进程并kill进程。使用Shell脚本远程执行脚本查询进程并kill进程。 版本:CentOS Linux release 7.9.2009。 1.使用Shell脚本查询进程并kill进程 1.1脚本 脚本名称:zk-kill_pid.sh 脚本内容&a…

从ROS1到ROS2无人机编程实战指南

亲爱的读者们,我今天非常荣幸地向大家推荐一本本人的全新力作——《从ROS1到ROS2无人机编程实战指南》。这本书站在初学者的角度,从入门到进阶,再到实战,循序渐进,是学习ROS1和ROS2的最佳选择。如今已在全国范围内上市…

Java spring boot 全解Camunda 7,从 0 到 1 构建工作流平台——第一节:各个开源框架对比

目录 1. Camunda 介绍2. Camunda 选型说明2.1 osworkflow2.2 jbpm2.3 ActivitiActiviti介绍各个版本的优缺点 2.4 flowable2.5 camundacamunda介绍主流版本介绍 2.6 n8n.io2.7 为什么选 camunda ? camunda7.x 还是 camunda 8.x ?为什么选 camunda?camun…

碳排放预测模型 | Python实现基于机器学习回归分析的碳排放预测模型——数据可视化和探索

文章目录 效果一览文章概述研究内容环境准备源码设计学习总结参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于机器回归分析的碳排放预测模型——数据可视化和探索 目标是测试所选特征对分析的重要性,检测异常值的存在并准备数据以供进一步分析。 </

Netty实战(十二)

预置的ChannelHandler和编解码器&#xff08;二&#xff09;HTTPS、WebSocket的添加使用和大型数据写入以及几种常见的序列化 一、基于Netty的HTTPS程序1.2 使用HTTPS2.3 WebSocket 二、空闲连接和超时三、 解码基于分隔符的协议和基于长度的协议3.1 基于分割符的协议3.2 基于长…

策 略 模 式「指 鼠 为 鸭」

前言 大家好&#xff0c;我是 god23bin&#xff0c;今天我们来介绍下设计模式中的一个重要的设计模式——策略模式。 当涉及到某个行为或算法有多个变体时&#xff0c;策略模式是一种常见的设计模式。它允许在运行时选择使用不同的策略&#xff0c;而无需修改现有代码。 现在…

OneFormer:规则通用图像分割的一个Transformer

文章目录 OneFormer: One Transformer to Rule Universal Image Segmentation摘要本文方法实验结果 OneFormer: One Transformer to Rule Universal Image Segmentation 摘要 通用图像分割并不是一个新概念。过去统一图像分割的尝试包括场景解析、全景分割&#xff0c;以及最…

【工具】SecureCR-8.5下载、安装激活和使用教程(包含常用设置)

目录 一、安装包下载 二、安装教程 三、激活操作 四、使用教程 五、常用设置 一、安装包下载 SecureCRT8.5安装包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1yy677I99ln_3evoHc5dMXg 提取码&#xff1a;9tyj 二、安装教程 1. 解压、双击进行安装 2. 安装进…

【LeetCode】136. 只出现一次的数 python

目录 题目描述 第一次刷题 第二次刷题 异或运算的规则 题目描述 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;…

[LeetCode周赛复盘] 第 106 场双周赛20230611

[LeetCode周赛复盘] 第 106 场双周赛20230611 一、本周周赛总结6461. 判断一个数是否迷人1. 题目描述2. 思路分析3. 代码实现 6425. 找到最长的半重复子字符串1. 题目描述2. 思路分析3. 代码实现 6426. 移动机器人1. 题目描述2. 思路分析3. 代码实现 6463. 找到矩阵中的好子集…

DHCP是什么?它有什么作用?其工作模式?工作原理?

目录 一、DHCP是什么&#xff1f;二、DHCP的作用&#xff1f;1. 在没有DHCP服务的网络中2. 在有DHCP服务的网络中 三、DHCP的工作模式简介四、DHCP的工作原理五、参考资料 一、DHCP是什么&#xff1f; DHCP是动态主机配置协议&#xff08;Dynamic Host Configuration Protocol…

Vue 封装ajax请求[接口]函数

在Vue项目开发当中&#xff0c;当有了后端提供的数据接口之后呢&#xff0c;就需要来为接口定义接口的请求函数&#xff0c;那么在去定义接口函数之前可以先来封装一个ajax请求函数&#xff1b;可能有的初学者在之前的一些篇目当中看到这个vue发起数据请求的不是使用axios的吗&…

3.MySQL表的增删改查(基础)

文章目录 ☕️1. CRUD☕️&#x1f375;2. 新增&#xff08;Create&#xff09;&#x1f375;&#x1f37c;2.1 单行数据 全列插入&#x1f37c;&#x1f37a;2.2 多行数据 指定列插入&#x1f37a;&#x1f378;2.3关于时间的插入格式(homework数据表)&#xff1a;&#x1f…

串口RS232、RS485最本质区别

由下图可看出不管是RS232还是RS485&#xff0c;其本质都是串口通信&#xff0c;只不过是串口通信电平上的变种而已。所以&#xff0c;我们首先从串口通信讲起。 1、串口通信 任何一种通信都要有物理接口和通信协议。串口通信物理接口如下图&#xff1a; 串口通信协议首先要约…

RBAC权限管理,Shiro实践

概念介绍 RBAC是指基于角色的访问控制&#xff08;Role-Based Access Control&#xff09;&#xff0c;它是一种广泛应用于计算机安全领域的访问控制机制。RBAC通过将用户分配到不同的角色&#xff0c;来控制用户对系统中资源的访问权限。 在RBAC中&#xff0c;每个角色都被…