【OpenCV图像处理1】图像&视频的加载与显示

一、图像&视频的加载与显示

1、创建和显示窗口

1.1 namedWindow() 创建命名窗口

namedWindow()用法:

cv2.namedWindow(winname, flags)

参数说明:

  • winname:新建窗口的名称,可任意取(字符串类型)。

  • flags:窗口的标识,一般默认为 WINDOW_AUTOSIZE ,还有其他几种参数,具体用法如下表所示:

参数描述
WINDOW_NORMAL显示图像后,允许用户随意调整窗口大小
WINDOW_AUTOSIZE根据图像大小显示窗口,不允许用户调整大小
WINDOW_OPENGL创建窗口的时候会支持OpenGL
WINDOW_FULLSCREEN全屏显示窗口
WINDOW_FREERATIO调整图像尺寸以充满窗口
WINDOW_KEEPRATIO保持图像的比例
WINDOW_GUI_EXPANDED创建的窗口允许添加工具栏和状态栏
WINDOW_GUI_NORMAL创建没有状态栏和工具栏的窗口

以上两种标蓝色的参数是最为常见的。

1.2 resizeWindow() 修改窗口尺寸

resizeWindow()用法:

cv2.resizeWindow(winname, width, height)

参数说明:

  • winname:被修改窗口的名称。
  • width 和 height:窗口的宽和高。

注意:当 namedWindow(winname, flags) 中的 flages 设为 WINDOW_AUTOSIZE 时,将不会对窗口尺寸进行修改。

1.3 imshow() 显示窗口

imshow()用法:

cv2.imshow(winname, mat)

参数说明:

  • winname:窗口名称,它是一个字符串。
  • mat:要展现的对象。

若 mat 设置为0,即不展示任何对象,只是一个黑框。

1.4 waitKey() 等待用户输入

waitKey()用法:

cv2.waitKey(delay)

参数说明:

  • delay:以毫秒为单位,该函数等待任何键盘事件指定的毫秒。如果在这段时间内按下任何键,程序将继续运行。
  • 如果 0 被传递,它将无限期地等待一次敲击键。

当然也可以设置按指定键退出,即使用 if 判断语句:

key = cv2.waitKey(0)
# 按q键退出
if key & 0xFF == ord('q'):
	break

1.5 destroyWindow()、destroyAllWindows销毁窗口

1、destroyWindow()用法:

cv2.destroyWindow(winname)

参数说明:

  • winname:需要销毁的窗口名称。

2、destroyAllWindows用法:

cv2.destroyAllWindows()

参数说明:

  • 无参数

3、两者区别:

destroyAllWindows() 会销毁我们创建的所有窗口

如果要销毁任何特定的窗口,使用函数 destroyWindow() ,并在其中传递确切的窗口名称作为参数。

1.6 代码实现

import cv2

cv2.namedWindow('windows', cv2.WINDOW_NORMAL)  # 创建命名窗口
cv2.resizeWindow('windows', 640, 360)  # 修改窗口尺寸

cv2.imshow('windows', 0)  # 显示窗口
cv2.waitKey(0)  # 等待用户输入
cv2.destroyAllWindows()  # 销毁窗口

2、加载显示图像

2.1 imread() 读取图像

imread()用法:

cv2.imread(filename, flags)

参数说明:

  • filename:要加载的文件名(路径)。
  • flags:读取图像的方式,一般默认为 IMREAD_COLOR ,还有其他几种参数,具体用法如下表所示:
参数描述
IMREAD_UNCHANGED如果设置,则按原样返回加载的图像(带有Alpha通道,否则将被裁剪)。
IMREAD_GRAYSCALE如果设置,请始终将图像转换为单通道灰度图像。
IMREAD_COLOR如果设置,请始终将图像转换为3通道BGR彩色图像。
IMREAD_ANYDEPTH如果设置,则当输入具有相应的深度时返回16位/ 32位图像,否则将其转换为8位。
IMREAD_ANYCOLOR如果设置,将以任何可能的颜色格式读取图像。
IMREAD_LOAD_GDAL如果设置,请使用Gdal驱动程序加载图像。
IMREAD_REDUCED_GRAYSCALE_2如果设置,则始终将图像转换为单通道灰度图像,并且图像尺寸减小1/2。
IMREAD_REDUCED_COLOR_2如果设置,请始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/2。
IMREAD_REDUCED_GRAYSCALE_4如果设置,则始终将图像转换为单通道灰度图像,并且图像尺寸减小1/4。
IMREAD_REDUCED_COLOR_4如果设置,请始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/4。
IMREAD_REDUCED_GRAYSCALE_8如果设置,请始终将图像转换为单通道灰度图像,并且图像尺寸减小1/8。
IMREAD_REDUCED_COLOR_8如果设置,请始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/8。
IMREAD_IGNORE_ORIENTATION如果设置,请不要根据EXIF的方向标志旋转图像。

以上三种标蓝色的参数是最为常见的,除了这三个标志,我们可以分别简单地传递整数-1、0或1。

2.2 代码实现

import cv2

cv2.namedWindow('window', cv2.WINDOW_NORMAL)  # 创建命名窗口
cv2.resizeWindow('window', 502, 345)  # 修改窗口尺寸

cat = cv2.imread('../resource/cat.jpg', cv2.IMREAD_GRAYSCALE)  # 读取图片

cv2.imshow('window', cat)  # 显示窗口(图片)
cv2.waitKey(0)  # 等待用户输入
cv2.destroyAllWindows()  # 销毁窗口
  • 如果以 IMREAD_GRAYSCALE0 的方式读取图像,那么将呈现灰色图像:

  • 如果以 IMREAD_COLOR1 的方式读取图像,那么将呈现彩色或原有图像:

  • 如果 imread() 未指定 flag ,那么它默认以彩色的方式来读取图像。

3、保存图像

3.1 imwrite() 保存图像

imwrite()用法:

cv2.imwrite(filename, img)

参数说明:

  • filename:要保存的文件名(路径)。
  • img:要保存的图像。cv2.imwrite('../resource/cat.png', cat) ,这会将图像以PNG格式保存在工作目录中。

3.2 代码实现

在下面的程序中,以灰度加载图像,显示图像,按 q 键直接退出而不保存,或者按 s 键保存图像并退出:

import cv2

cv2.namedWindow('window', cv2.WINDOW_NORMAL)  # 创建命名窗口
cv2.resizeWindow('window', 502, 345)  # 修改窗口尺寸

cat = cv2.imread('../resource/cat.jpg', cv2.IMREAD_GRAYSCALE)  # 读取图片
cv2.imshow('window', cat)  # 显示窗口(图片)
key = cv2.waitKey(0)  # 等待用户输入

if key & 0xFF == ord('q'):  # 按 q 退出
    cv2.destroyAllWindows()
elif key & 0xFF == ord('s'):  # 按 s 保存和退出
    cv2.imwrite('../resource/cat.png', cat)
    cv2.destroyAllWindows()

如果使用的是64位计算机,则必须按如示修改行: key & 0xFF == ord(‘q’)

3.3 ord() 函数

我们想一想:cv2.waitKey() 返回的是什么数据类型?

key = cv2.waitKey(0)
print(type(key))print(type(cv2.waitKey(0)))
<class 'int'>

cv2.waitKey() 返回的是整型,那么我们如果写成 if key & 0xFF == 'q':行不行?

答案当然是不行,因为我们知道 key 是整型,而 ‘q’ 是字符串类型,两者属于不同类型,不能给直接作比较,这就引出了 ord() 函数

ord() 函数的作用是:将字符串转换为ASCII,也就是将字符串类型转换为相对应的整型,然后就可以直接作比较。

3.4 修改 bug

当上述代码运行时发现:我们不仅可以按 q 键退出还可以按其他键退出,这就不满足我们的要求,但我们可以添加一个 while 循环:

import cv2

cv2.namedWindow('window', cv2.WINDOW_NORMAL)  # 创建命名窗口
cv2.resizeWindow('window', 502, 345)  # 修改窗口尺寸

cat = cv2.imread('../resource/cat.jpg', cv2.IMREAD_GRAYSCALE)  # 读取图片

while True:
    cv2.imshow('window', cat)  # 显示窗口(图片)
    key = cv2.waitKey(0)  # 等待用户输入

    if key & 0xFF == ord('q'):  # 按 q 退出
        break
    elif key & 0xFF == ord('s'):  # 按 s 保存和退出
        cv2.imwrite('../resource/cat.png', cat)
    else:
        print(key)  # 打印 key 值

以上代码实现:按 q 键退出,按 s 键保存图像,按 其他 键打印该键的ASCII码。

4、视频采集

4.1 VideoCapture() 获取视频设备

VideoCapture() 用法:

cap = cv2.VideoCapture(0)

参数说明:

  • 设备索引
    • 0 表示打开笔记本的内置摄像头,1 则打开外置摄像头。
  • 视频文件
    • 视频文件所在的路径。(以下会提及)

4.2 cap.read() 读取视频帧

cap.read()用法

ret, frame = cap.read()

返回值说明:

  • ret:返回布尔值(True / False ),代表是否读取到图像。
  • frame:表示截取的一帧图像。

4.3 cap.release() 释放捕获

cap.release()用法

cap.release()

4.4 代码实现

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)
    if key & 0xFF == ord('q'):
        break

cap.release()  # 释放VideoCapture
cv2.destroyAllWindows()  # 销毁窗口

5、读取视频文件

5.1 VideoCapture() 读取视频

VideoCapture() 用法:

cap = cv2.VideoCapture('../resource/fire.mp4')

参数说明:

  • 视频文件所在的路径。

5.2 VideoCapture() 小结

参数为设备索引时:获取视频设备;参数为视频文件时:从视频文件中读取视频帧。

5.3 代码实现

import cv2

cv2.namedWindow('video', cv2.WINDOW_NORMAL)  # 创建窗口
cv2.resizeWindow('video', 640, 360)  # 修改窗口尺寸

cap = cv2.VideoCapture('../resource/fire.mp4')  # 从视频文件读取视频帧

while True:
    # 从摄像头读视频帧
    ret, frame = cap.read()
    # 将视频帧在窗口显示
    cv2.imshow('video', frame)
    # 等待键盘事件,如果为q,退出
    key = cv2.waitKey(1000 // 30)
    if key & 0xFF == ord('q'):
        break

cap.release()  # 释放VideoCapture
cv2.destroyAllWindows()  # 销毁窗口

6、录制并保存视频

6.1 VideoWriter_fourcc() 多媒体格式

VideoWriter_fourcc()用法:

fourcc = cv2.VideoWriter_fourcc(c1, c2, c3, c4)

参数说明:

  • Fedora 中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG会生成大尺寸的视频。X264会生成非常小的尺寸的视频)
  • Windows 中:DIVX(.avi 尚待测试和添加)
  • OSX 中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

cv2.VideoWriter_fourcc() 的参数可以写成 ('M','J','P','G') 或者 (*'MJPG') 传递。

6.2 视频录制 VideoWriter()

VideoWriter()用法:

vw = cv2.VideoWriter('../resource/out.avi', fourcc, 25, (640, 480))

参数说明:

  • 输出文件
  • 多媒体文件格式 VideoWriter_fourcc()
  • 帧率
  • 分辨率大小
  • 颜色标志(默认为True ),编码器期望颜色帧,否则它与灰度帧一起工作。

6.3 写数据 vw.write

vw.write用法:

vw.write(frame)

参数说明:

  • ret, frame = cap.read() 将读取到的视频帧,再通过 vw.write(frame) 将数据写入多媒体文件。

6.4 释放资源 vw.release

vw.release用法:

vw.release()

完成工作后释放所有内容(释放VideoCapture、释放VideoWriter、销毁窗口)。

6.5 代码实现

import cv2

# 创建VideoWriter为写多媒体文件
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
vw = cv2.VideoWriter('../resource/out.avi', fourcc, 25, (640, 480))

cv2.namedWindow('video', cv2.WINDOW_NORMAL)  # 创建窗口
cv2.resizeWindow('video', 640, 360)  # 修改窗口尺寸

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

while True:
    # 从摄像头读视频帧
    ret, frame = cap.read()
    # 将视频帧在窗口显示
    cv2.imshow('video', frame)
    
    # 写数据到多媒体文件
    vw.write(frame)

    # 等待键盘事件,如果为q,退出
    key = cv2.waitKey(1000 // 30)
    if key & 0xFF == ord('q'):
        break

cap.release()  # 释放VideoCapture
vw.release()  # 释放VideoWriter
cv2.destroyAllWindows()  # 销毁窗口

6.6 代码优化

1、使用 isOpened() 判断摄像头是否已打开?

while cap.isOpened():

判断摄像头是否为打开状态

2、采集数据时要判断数据是否获取到了?

if ret == True:
	...
else:
	break

3、优化后代码

import cv2

# 创建VideoWriter为写多媒体文件
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
vw = cv2.VideoWriter('../resource/out.avi', fourcc, 25, (640, 480))

cv2.namedWindow('video', cv2.WINDOW_NORMAL)  # 创建窗口
cv2.resizeWindow('video', 640, 360)  # 修改窗口尺寸

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

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

    if ret == True:
        # 将视频帧在窗口显示
        cv2.imshow('video', frame)
        # 写数据到多媒体文件
        vw.write(frame)

        # 等待键盘事件,如果为q,退出
        key = cv2.waitKey(1000 // 30)
        if key & 0xFF == ord('q'):
            break
    else:
        break

cap.release()  # 释放VideoCapture
vw.release()  # 释放VideoWriter
cv2.destroyAllWindows()  # 销毁窗口

7、鼠标控制

7.1 设置鼠标回调 setMouseCallback()

setMouseCallback()用法:

cv2.setMouseCallback(winname, callback, userdata)

参数说明:

  • winname:窗口名称
  • callback:鼠标事件的回调函数
  • userdata:传递给回调函数的可选参数(默认为None)

7.2 回调函数 callback()

callback()用法:

callback(event, x, y, flags, userdata)

参数说明:

  • event:鼠标事件(鼠标移动、左键、右键…)

  • x, y:鼠标所在坐标点

  • flags:鼠标键及组合键

  • userdata:传递给回调函数的可选参数(默认为None)

event类型如下表所示:

event描述
EVENT_MOUSEMOVE0鼠标移动
EVENT_LBUTTONDOWN1按下鼠标左键
EVENT_RBUTTONDOWN2按下鼠标右键
EVENT_MBUTTONDOWN3按下鼠标中键
EVENT_LBUTTONUP4左键释放
EVENT_RBUTTONUP5右键释放
EVENT_MBUTTONUP6中键释放
EVENT_LBUTTONDBLCLK7左键双击
EVENT_RBUTTONDBLCLK8右键双击
EVENT_MBUTTONDBLCLK9中键双击
EVENT_MOUSEWHEEL10鼠标滚轮上下移动
EVENT_MOUSEHWHEEL11鼠标滚轮左右移动

flags类型如下表所示:

flags描述
EVENT_FLAG_LBUTTON1按下左键
EVENT_FLAG_RBUTTON2按下右键
EVENT_FLAG_MBUTTON4按下中键
EVENT_FLAG_CRTLKEY8按下CTRL键
EVENT_FLAG_SHIFTKEY16按下SHIFT键
EVENT_FLAG_ALTKEY32按下ALT键

7.3 设置背景 np.zeros()

np.zeros()用法:

img = np.zeros(shape, dtype)

参数说明:

  • shape:创建新数组的形状(维度),与显示窗口相反。
  • dtype:数据类型

7.4 代码实现

import cv2
import numpy as np

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

# 创建、修改窗口
cv2.namedWindow('mouse_callback', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse_callback', 640, 360)

# 设置鼠标回调
cv2.setMouseCallback('mouse_callback', callback, 'userdata')
# 显示窗口和背景
img = np.zeros((360, 640, 3), np.uint8)

while True:
    cv2.imshow('mouse_callback', img)
    key = cv2.waitKey(0)
    if key & 0xFF == ord('q'):
        break

# 销毁窗口
cv2.destroyAllWindows()

8、TrackBar控件

8.1 创建TrackBar控件 createTrackbar()

createTrackbar()用法:

cv2.createTrackbar(trackbarName, windowName, value, count, onChange)

参数说明:

  • trackbarName:轨迹条名
  • windowName:窗口名
  • value:滑块初始位置
  • count:滑块达到最大位置的值(最小值为0,最大值为count)
  • onChange:默认值为0,指回调函数
  • userdate:默认值为0,用户传递给回调函数的数据值

8.2 获取当前TrackBar值 getTrackbarPos()

getTrackbarPos()用法:

cv2.getTrackbarPos(trackbarName, windowName)

参数说明:

  • trackbarName:轨迹条名
  • windowName:窗口名

8.3 代码实现

import cv2
import numpy as np

# 定义回调函数
def callback(value):
    print(value)

# 创建窗口
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)

# 设置纯黑色背景图片(640 * 480)
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]

    # 显示
    cv2.imshow('TrackBar', img)

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

cv2.destroyAllWindows()

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_leoatliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值