当前位置: 代码网 > it编程>前端脚本>Python > OpenCV-Python实战(2)——图像与视频文件的处理_pythonopencv处理视频(3)

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

2024年07月31日 Python 我要评论
在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。需要完整版PDF学习资源私我。

写在最后

在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。

需要完整版pdf学习资源私我

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

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

编写 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

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

获取相机画面

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

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

播放视频文件

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 字节编码),用于指定视频编解码器,查看获取更多可用编码。应该注意的是:支持的编解码器是平台相关的,如果想使用特定的编解码器,则应该在系统上安装该编解码器。典型的编解码器包括 divx、xvid、x264 和 mjpg。
视频文件格式是一种用于存储数字视频数据的文件格式,典型的视频文件格式包括 avi(*.avi)、mp4(*.mp4)、quicktime(*.mov) 和 windows media video(*.wmv)。
最后,应该考虑到视频文件格式和 fourcc 之间需要进行正确的组合。 在 opencv 中创建视频文件时,必须考虑这些因素:

写入视频文件的流程

上图总结了在 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_graycv2.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:
        break

最后,释放所有内容(包括 cv2.videocapturecv2.videwriter 对象,并销毁创建的窗口):

capture.release()
out_gray.release()
cv2.destroyallwindows()

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

python write_video_file.py video_example.avi

在工作目录下可以看到保存的灰度视频文件。

5. 视频属性详解

在上述示例中,我们已经了解了如何从 cv2.videocapture 对象中获取一些关键属性。接下来,将介绍所有属性并了解它们的工作原理。最后,我们将使用这些属性来加载视频文件并反向输出(首先显示视频的最后一帧,依此类推)。

5.1 获取视频对象的属性

创建 read_video_file_all_properties.py 脚本来显示所有属性。其中一些属性仅在使用相机时才有效(而在视频文件时无效)。
在脚本中,首先创建 decode_fourcc() 函数,它将 capture.get(cv2.cap_prop_fourcc) 返回的 int 类型的值转换为表示编解码器的字符串值,来正确输出编解码器:

def decode\_fourcc(fourcc):
    fourcc_int = int(fourcc)

    print("int value of fourcc: '{}'".format(fourcc_int))

    fourcc_decode = ""
    for i in range(4):
        int_value = fourcc_int >> 8 \* i & 0xff
        print("int\_value: '{}'".format(int_value))
        fourcc_decode += chr(int_value)
    
    return fourcc_decode

下图解释了函数 decode_fourcc 的工作原理:

视频对象的属性

第一步是获取由 capture.get(cv2.cap_prop_fourcc) 返回的值( int 表示的字符串),然后,迭代四次,每次获取八位并将这八位转换为 int 。最后,使用 chr() 函数将这些 int 值转换为 char。也可以只使用一行代码就可以完成此功能:

return "".join([chr((fourcc_int >> 8 * i) & 0xff) for i in range(4)])

下表显示了视频文件的主要属性和解释:

视频属性解释
cap_prop_pos_frames视频文件的当前帧
cap_prop_pos_msec当前帧的时间戳
cap_prop_fps获取 fps
cap_prop_frame_wodth视频帧的宽度
cap_prop_frame_height视频帧的高度
cap_prop_frame_count视频文件的总帧数

使用以下代码,可以获取和打印所有属性:

print("cv\_cap\_prop\_frame\_width:'{}'".format(capture.get(cv2.cap_prop_frame_width)))
print("cv\_cap\_prop\_frame\_height :'{}'".format(capture.get(cv2.cap_prop_frame_height)))
print("cap\_prop\_fps : '{}'".format(capture.get(cv2.cap_prop_fps)))
print("cap\_prop\_pos\_msec :'{}'".format(capture.get(cv2.cap_prop_pos_msec)))
print("cap\_prop\_pos\_frames :'{}'".format(capture.get(cv2.cap_prop_pos_frames)))
print("cap\_prop\_fourcc :'{}'".format(decode_fourcc(capture.get(cv2.cap_prop_fourcc))))
print("cap\_prop\_frame\_count :'{}'".format(capture.get(cv2.cap_prop_frame_count)))
print("cap\_prop\_mode : '{}'".format(capture.get(cv2.cap_prop_mode)))
print("cap\_prop\_brightness :'{}'".format(capture.get(cv2.cap_prop_brightness)))
print("cap\_prop\_contrast :'{}'".format(capture.get(cv2.cap_prop_contrast)))
print("cap\_prop\_saturation :'{}'".format(capture.get(cv2.cap_prop_saturation)))
print("cap\_prop\_hue : '{}'".format(capture.get(cv2.cap_prop_hue)))
print("cap\_prop\_gain : '{}'".format(capture.get(cv2.cap_prop_gain)))
print("cap\_prop\_exposure :'{}'".format(capture.get(cv2.cap_prop_exposure)))
print("cap\_prop\_convert\_rgb :'{}'".format(capture.get(cv2.cap_prop_convert_rgb)))
print("cap\_prop\_rectification :'{}'".format(capture.get(cv2.cap_prop_rectification)))
print("cap\_prop\_iso\_speed :'{}'".format(capture.get(cv2.cap_prop_iso_speed)))
print("cap\_prop\_buffersize :'{}'".format(capture.get(cv2.cap_prop_buffersize)))

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

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

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

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com