OpenCV-Python实战(2)——图像与视频文件的处理_pythonopencv处理视频(1)

做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。

别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。

我先来介绍一下这些东西怎么用,文末抱走。


(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

(4)200多本电子书

这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。

基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

(5)Python知识点汇总

知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。

在这里插入图片描述

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

cv2.waitKey(0)
cv2.destroyAllWindows()


在这个例子中,必需的参数是 `path_image`,它是我们要加载的图像的路径。利用 `args.path_image` 和 `args["path_image"]` 都可以获取图像的路径(从参数中获取值的两种不同方式),然后将它们用作 `cv2.imread()` 函数的参数。  
 通过在命令行中执行以下命令,运行脚本:



python load_image.py sigonghuiye.jpeg


可以看到运行结果如以下屏幕截图所示:


![在 OpenCV 中读取图像](https://img-blog.csdnimg.cn/35b6825219ec470f83dc4384bdd850fc.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xPVkVteTEzNDYxMQ==,size_16,color_FFFFFF,t_70#pic_center)


#### 2.2 使用 OpenCV 写入图像


以下示例 `write_image.py` 展示了如何使用函数 `cv2.imshow()` 加载图像:



import argparse
import cv2
parser = argparse.ArgumentParser()
parser.add_argument(“path_image”, help=“path to input image to be displayed”)
parser.add_argument(“path_image_output”, help=“path of the processed image to be saved”)
args = parser.parse_args()
image = cv2.imread(args.path_image)
args = vars(parser.parse_args())
cv2.imwrite(args[“path_image_output”], image)
cv2.waitKey(0)
cv2.destroyAllWindows()


上述示例中,执行脚本需要的参数是 `path_image` 和 `path_image_output`,它们分别是我们要加载的图像的路径以及图像要保存的路径。  
 通过在命令行中执行以下命令,运行脚本:



python load_image.py sigonghuiye.jpeg copy_image.jpg


运行结束后就可以在工作目录中,看到保存的 `copy_image.jpg`.


#### 2.3 计算机视觉项目处理流程示例


计算机视觉项目的常见处理流程是加载图像,执行某种处理,最后输出这个处理过的图像。处理后的图像可以保存到磁盘或者进行展示。为了对计算机视觉项目处理流程有一个完整的认识,在下面的示例中,介绍了这三个步骤(加载、处理和保存)。为了简单起见,处理步骤仅将图像转换为灰度图像,接下来编写脚本 `load_processing_save_image.py`:



import argparse
import cv2
parser = argparse.ArgumentParser()
parser.add_argument(“path_image_input”, help=“path to input image to be displayed”)
parser.add_argument(“path_image_output”, help=“path of the processed image to be saved”)
args = vars(parser.parse_args())
image_input = cv2.imread(args[“path_image_input”])
cv2.imshow(“loaded image”, image_input)
gray_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
cv2.imshow(“gray image”, gray_image)
cv2.imwrite(args[“path_image_output”], gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()


上述示例中,执行脚本需要两个必需的参数。第一个是 `path_image_input`,它表示要加载的图像的路径。第二个是 `path_image_output`,它表示要保存的结果图像的路径。处理步骤仅将加载的图像转换为灰度图像:



gray_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)


需要注意的是,`cv2.cvtColor` 函数第二个参数 `cv2.COLOR_BGR2GRAY` 假定加载的图像是 BGR 彩色图像。如果已经加载了 RGB 彩色图像并且想要将其转换为灰度,则应该使用 `cv2.COLOR_RGB2GRAY`。  
 通过在命令行中执行以下命令,运行脚本:



python load_processing_save_image.py sigonghuiye.jpeg gray_image.png


可以看到运行结果如以下屏幕截图所示,同时,在运行结束后就可以在工作目录中,看到保存的灰度图像 `gray_image.jpg`:


![计算机视觉项目处理流程示例](https://img-blog.csdnimg.cn/b8b32ee6278846599a315d1376d02530.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xPVkVteTEzNDYxMQ==,size_16,color_FFFFFF,t_70#pic_center)


### 3. 读取相机画面和视频文件


在某些需要实时计算机视觉项目中,必须捕捉实时相机画面(例如,使用笔记本电脑的摄像头或监控摄像机捕捉画面)。在 OpenCV 中,使用 `cv2.VideoCapture` 作为从不同来源捕获视频的类,例如图像序列、视频文件和相机。


#### 3.1 读取相机画面


编写 `read_camera.py` 用于从连接到计算机的相机读取画面。首先看下完整程序,然后再进行详细解释:



import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(“index_camera”, help=“index of the camera to read from”, type=int)
args = parser.parse_args()

capture = cv2.VideoCapture(args.index_camera)
if capture.isOpened()is False:
print(“Error opening the camera”)
while capture.isOpened():
ret, frame = capture.read()

if ret is True:
    cv2.imshow('Input frame from the camera', frame)
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('Grayscale input camera', gray_frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
else:
    break

capture.release()
cv2.destroyAllWindows()


`cv2.VideoCapture` 所必需的参数是 `index_camera`,它指示要读取的相机的索引。如果有一个摄像头连接到计算机,则它的索引为 `0` ,如果有第二台摄像头,可以通过传递参数值 `1` 来选择它,以此类推;需要注意的是,该参数的类型是 int 。



parser = argparse.ArgumentParser()
parser.add_argument(“index_camera”, help=“index of the camera to read from”, type=int)
args = parser.parse_args()


使用 cv2.VideoCapture 的第一步是创建一个要使用的对象 `capture`:



capture = cv2.VideoCapture(args.index_camera)


如果 `index_camera` 为 0,则相当于调用 `cv2.VideoCapture(0)` 。为了检查连接是否已正确建立,需要使用 `capture.isOpened()` 方法,如果无法建立连接,该方法返回 `False`;如果正确初始化,则此方法返回 `True`。  
 要从相机逐帧捕获画面,需要调用 `capture.read()` 方法,该方法从相机返回帧;同时还将返回一个布尔值,此布尔值指示是否已从 `capture` 对象正确读取帧。



while capture.isOpened():
# 逐帧获取相机画面
ret, frame = capture.read()
if ret is True:
# 显示捕获的帧画面
cv2.imshow(‘Input frame from the camera’, frame)


获取的相机帧画面与 OpenCV 读取的图像具有相同的结构,因此可以像处理图像一样处理它。例如,要将帧画面转换为灰度:



	# 将从相机捕获的帧转换为灰度图像
	gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	# 显示灰度帧图像
    cv2.imshow('Grayscale input camera', gray_frame)

接下来,实现按下 `q` 键退出程序的功能,`ord('q')` 返回 `q` 字符对应的 8 位 ASCII 值,而 `cv2.waitKey()` 与 0xFF 的 按位与 (&) 运算用于仅获取 `cv2.waitKey()` 的最后 8 位。因此,可以对这两个值进行比较,如果相等则退出程序:



    # 按下 q 键可退出程序执行
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

最后,释放所有内容 (cv2.VideoCapture,并销毁创建的窗口):



capture.release()
cv2.destroyAllWindows()


通过在命令行中执行以下命令,运行脚本:



python read_camera.py 0


可以看到运行结果显示了相机获取的实时画面:


![获取相机画面](https://img-blog.csdnimg.cn/53911632f3af4068a6beedb788e3c814.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xPVkVteTEzNDYxMQ==,size_16,color_FFFFFF,t_70#pic_center)


#### 3.2 访问捕获画面对象的属性


可以使用 `capture.get(property_identifier)` 访问 `capture` 对象的某些属性,例如帧宽度、帧高度和每秒帧数 (Frames Per Second, FPS)。如果调用不受支持的属性,则返回值将为 0:



import cv2

capture = cv2.VideoCapture(0)

获取 VideoCapture 的属性 (frame width, frame height and frames per second (fps)):

frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)

打印属性值

print(“CV_CAP_PROP_FRAME_WIDTH: ‘{}’”.format(frame_width))
print(“CV_CAP_PROP_FRAME_HEIGHT : ‘{}’”.format(frame_height))
print(“CAP_PROP_FPS : ‘{}’”.format(fps))

Check if camera opened successfully

if capture.isOpened()is False:
print(“Error opening the camera”)

while capture.isOpened():
ret, frame = capture.read()

if ret is True:
    cv2.imshow('Input frame from the camera', frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
else:
    break

capture.release()
cv2.destroyAllWindows()


执行此脚本将会打印如下属性信息:



CV_CAP_PROP_FRAME_WIDTH: ‘640.0’
CV_CAP_PROP_FRAME_HEIGHT : ‘480.0’
CAP_PROP_FPS : ‘30.0’


#### 3.3 保存相机画面


可以修改前面的示例以在处理流程中添加其他的功能。例如,我们可能想将一些关键的感兴趣帧保存到磁盘中。在以下示例 `read_camera_capture.py` 中 ,将添加此示例功能,当按下键盘上的 `c` 键时,将当前帧保存到磁盘(同时保存 BGR 和灰度帧):



import cv2
import argparse

capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
print(“Error opening the camera”)
frame_index = 0
while capture.isOpened():
ret, frame = capture.read()

if ret is True:
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 保存相机画面
    if cv2.waitKey(20) & 0xFF == ord('c'):
        frame_name = "camera\_frame\_{}.png".format(frame_index)
        gray_frame_name = "grayscale\_camera\_frame\_{}.png".format(frame_index)
        # 将当前帧保存到磁盘(同时保存 BGR 和灰度帧)
        cv2.imwrite(frame_name, frame)
        cv2.imwrite(gray_frame_name, gray_frame)
        frame_index += 1
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
else:
    break

capture.release()
cv2.destroyAllWindows()


当按下 `c` 键时,首先构造两个文件名;然后,将两个图像保存到磁盘;最后,`frame_index` 递增,以便为保存下一帧做好准备。


#### 3.4 读取视频文件


`cv2.VideoCapture` 也可以用于读取视频文件,要读取视频文件,应在创建 `cv2.VideoCapture` 对象时提供视频文件的路径,编写 `read_video_file.py` 脚本:



import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(“video_path”, help=“path to the video file”)
args = parser.parse_args()
capture = cv2.VideoCapture(args.video_path)
if capture.isOpened() is False:
print(“Error opening the video file!”)

while capture.isOpened():
ret, frame = capture.read()
if ret is True:
cv2.imshow(‘Original frame from the video file’, frame)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow(‘Grayscale frame’, gray_frame)
if cv2.waitKey(20) & 0xFF == ord(‘q’):
break
else:
break
capture.release()
cv2.destroyAllWindows()


通过在命令行中执行以下命令,运行脚本:



python read_video_file.py xinlingqilv.mp4


可以看到运行结果开始播放视频文件:


![播放视频文件](https://img-blog.csdnimg.cn/2395e7c69039409999a2eb129e24504c.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xPVkVteTEzNDYxMQ==,size_16,color_FFFFFF,t_70#pic_center)


#### 3.5 读取 IP 摄像机


`cv2.VideoCapture` 也可以从 IP 摄像头读取数据。在 OpenCV 中从 IP 摄像头读取数据与从文件读取数据非常相似。唯一需要修改的是提供给 `cv2.VideoCapture` 构造函数的参数。可以使用本地网络中的 IP 摄像机或尝试连接公共 IP 摄像机。


### 4. 保存视频文件


接下来,首先介绍与视频相关的基本概念(例如,fps、编解码器和视频文件格式等),然后将了解如何使用 `cv2.VideoWriter` 保存视频文件。


#### 4.1 计算帧率(FPS)


`FPS` 是计算机视觉项目中的一个重要指标,该指标表示每秒处理的帧(画面)数,`FPS` 越高越好。但是,算法每秒应处理的帧数将取决于需要解决的特定问题。例如,如果算法需要跟踪和检测在街上行走的人,那么 15 FPS 可能就足够了。但是,如果是检测和跟踪高速公路上快速行驶的汽车,则可能需要 20-25 FPS。  
 因此,计算计算机视觉项目中的 FPS 指标非常重要。编写 `read_camera_fps.py` 以输出 `FPS`:



import cv2
import argparse
import time

capture = cv2.VideoCapture(0)

if capture.isOpened() is False:
print(“Error opening the camera”)

while capture.isOpened():
ret, frame = capture.read()
if ret is True:
processing_start = time.time()
cv2.imshow(“Input frame from the camera”, frame)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow(‘Grayscale input camera’, gray_frame)
if cv2.waitKey(20) & 0xFF == ord(‘q’):
break
processing_end = time.time()
processing_time_frame = processing_end - processing_start
print(“FPS: {}”.format(1.0 / processing_time_frame))
else:
break

capture.release()
cv2.destroyAllWindows()


在上述示例脚本中,首先需要获取处理开始的时间:



processing_start = time.time()


然后,获取所有处理完成后的时间:



processing_end = time.time()


接下来,计算时间差:



processing_time_frame = processing_end - processing_start


最后,计算并打印 FPS:



print(“FPS: {}”.format(1.0 / processing_time_frame))


#### 4.2 写入视频文件的流程


视频编码是一种用于压缩和解压缩数字视频的程序。具体而言,编解码器可用于将未压缩的视频转换为压缩后的视频,或者可用于将压缩的视频转换为未压缩的视频。压缩视频格式通常遵循视频压缩规范或视频编码格式的标准规范。OpenCV 提供了 `FOURCC` (一个 4 字节编码),用于指定视频编解码器,查看[可用编码列表](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)获取更多可用编码。应该注意的是:支持的编解码器是平台相关的,如果想使用特定的编解码器,则应该在系统上安装该编解码器。典型的编解码器包括 DIVX、XVID、X264 和 MJPG。  
 视频文件格式是一种用于存储数字视频数据的文件格式,典型的视频文件格式包括 AVI(\*.avi)、MP4(\*.mp4)、QuickTime(\*.mov) 和 Windows Media Video(\*.wmv)。  
 最后,应该考虑到视频文件格式和 FOURCC 之间需要进行正确的组合。 在 OpenCV 中创建视频文件时,必须考虑这些因素:


![写入视频文件的流程](https://img-blog.csdnimg.cn/707790556f244a72ac2aca508f37c610.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xPVkVteTEzNDYxMQ==,size_16,color_FFFFFF,t_70#pic_center)


上图总结了在 OpenCV 中使用 `cv2.VideoWriter()` 创建视频文件时应考虑的主要因素。在创建的名为 `video_example.avi` 视频中,FOURCC 值为 XVID,视频文件格式为 AVI(\*.avi),同时最后,应设置视频每一帧的 FPS 和尺寸。  
 脚本 `write_video_file.py` 演示如何创建视频文件:



Import required packages

import cv2
import argparse

parser = argparse.ArgumentParser()

parser.add_argument(“output_video_path”, help=“path to the video file to write”)
args = parser.parse_args()

capture = cv2.VideoCapture(0)

frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)

fourcc = cv2.VideoWriter_fourcc(*‘XVID’)

out_gray = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), False)

while capture.isOpened():
ret, frame = capture.read()
if ret:
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out_gray.write(gray_frame)

    cv2.imshow('gray', gray_frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
else:
    break

capture.release()
out_gray.release()
cv2.destroyAllWindows()


在上例中,必需的参数是输出视频文件名(例如 video\_example.avi):



parser = argparse.ArgumentParser()
parser.add_argument(“output_video_path”, help=“path to the video file to write”)
args = parser.parse_args()


从连接到计算机的第一台相机拍摄视频画面。因此,首先创建对象:



capture = cv2.VideoCapture(0)


接下来,从 `capture` 对象中获取一些关键属性(帧宽度、帧高度和 FPS),用于创建视频文件时使用:



frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)


然后,使用四字节编码 `FOURCC` 指定视频编解码器,此处将编解码器定义为 XVID :



fourcc = cv2.VideoWriter_fourcc(‘X’, ‘V’, ‘I’, ‘D’)


也可以使用以下方式指定视频编码器:



fourcc = cv2.VideoWriter_fourcc(*‘XVID’)


然后,使用与输入相机相同的属性创建 `cv2.VideoWriter` 对象 `out_gray`,`cv2.VideoWriter` 的最后一个参数值是 False 表示以灰度方式写入视频。如果我们想创建彩色视频,最后一个参数值为 True :



out_gray = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), False)


使用 `capture.read()` 从 `catpure` 对象获取相机帧,每一帧都被转换成灰度并写入视频文件,如果按下 `q` 键,程序结束:



while capture.isOpened():
ret, frame = capture.read()
if ret:
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out_gray.write(gray_frame)
cv2.imshow(‘gray’, gray_frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
else:

现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。

分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值