【OpenCV学习】初识OpenCV其二

据说,看我文章时 关注、点赞、收藏帅哥美女们 心情都会不自觉的好起来。

前言:
作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
✨个人主页:点我直达,在这里肯定能找到你想要的~
专栏介绍:OpenCV从入门到放弃 ,一个学习OpenCV的专栏~

专栏文章直链:
【OpenCV学习】初识OpenCV人生苦短,我用python

初识OpenCV其二

  • 保存图片
  • 采集摄像头视频
  • 视频录制
  • 鼠标检测
  • trackbar

保存图片

在上一章节,说了读取图片,接下来可以保存图片

from cv2 import cv2
# 默认是按照彩色图片来读取的。
cat = cv2.imread('./cat.jpeg')
cv2.imwrite('./123.png', cat)

imwrite 就是保存图片(写入图片)的意思。

采集摄像头视频

首先我们先要了解视频的本质。
我们常常听到说,电影是24帧的, 游戏30帧玩起来有点卡,流畅的话至少要60帧…
其实这些都是视频,帧率的意思就是,每秒钟播放几张图片。
通常帧率越高,看起来越流畅,但高到了一定程度,人眼就分辨不出来了。
所以视频其实本质上就是由一幅一幅的图片组成的。

import cv2
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('window', 640, 480)
# 如果打开失败,不会报错。
# cap = cv2.VideoCapture(1)
cap = cv2.VideoCapture(0)

这样我们就获取到了一个摄像头对象 cap
接下来我们通过循环 cap.isOpened() 判断摄像头有没有被关闭,达到不断刷新窗口的效果:

import cv2
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('window', 640, 480)
# 如果打开失败,不会报错。
# cap = cv2.VideoCapture(1)
cap = cv2.VideoCapture(0)
# 循环读取谁想投的每一帧。
# while True:
while cap.isOpened():
    # 读一帧数据,返回标记和这一帧数据,True表示读到了数据,False表示没读到数据。
    ret, frame = cap.read()
    # 可以根据ret做个判断。
    if not ret:
        # 没读到数据,直接退出。
        break
    # 显示数据
    cv2.imshow('video', frame)
    key = cv2.waitKey(10)
    if key & 0XFF == ord('q'):
        break
# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()

这样一个过程就是循环读取摄像头的每一帧,读取速度将依据 cv2.waitKey 设置的等待超时时长决定。
当然这边的时间设置还是有点夸张的,10毫秒获取一张图片,相当于是100帧这种速度,我们不需要这么快:

import cv2
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('window', 640, 480)
# 如果打开失败,不会报错。
# cap = cv2.VideoCapture(1)
# 打开视频,输入视频的地址
cap = cv2.VideoCapture('./1.mp4')
# 循环读取谁想投的每一帧。
# while True:
while cap.isOpened():
    # 读一帧数据,返回标记和这一帧数据,True表示读到了数据,False表示没读到数据。
    ret, frame = cap.read()
    # 可以根据ret做个判断。
    if not ret:
        # 没读到数据,直接退出。
        break
    # 显示数据
    cv2.imshow('video', frame)
    # 假如一个视频是30帧,那么每张图之间要间隔多少毫秒。
    # 只能是整数
    key = cv2.waitKey(1000 // 30)
    if key & 0XFF == ord('q'):
        break
# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()

现在换上 1000 // 30 就表明我们现在的帧率差不多是30帧了。

视频录制

在上面打开摄像头的基础上,可以将视频录制下来~

from cv2 import cv2
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.resizeWindow('frame', 640, 480)
cap = cv2.VideoCapture(0)
# *mp4就是解包操作,等同于  'm', 'p', '4', 'v'
# fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# avi格式的视频
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# 创建videowriter
# vw = cv2.VideoWriter('output.mp4', fourcc, 30, (640, 480))
vw = cv2.VideoWriter('output.avi', fourcc, 30, (640, 480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    # 写每一帧数据
    vw.write(frame)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1000 // 30) == ord('q'):
        break
# 别忘了release
cap.release()
vw.release()
cv2.destroyAllWindows()

关于 *“字符串” 这个解包操作,就是将字符串分成多个字符,由一个参数变成多个参数的过程,这里举几个小栗子,sep='|' 的意思是将多个接收参数当中用 | 分隔开来:

【OpenCV学习】初识OpenCV其二_第1张图片

很明显解包的作用就显现出来了。
这是博主使用摄像头录制的视频(转换成了GIF文件,露脸是不可能的~):
【OpenCV学习】初识OpenCV其二_第2张图片

鼠标检测

作为图像处理套件,怎么能少了对窗口的控制呢?
他既能等待键盘输入,又能检测鼠标状态:

from cv2 import cv2
import numpy as np


# 函数名可以随便取,但是参数必须是5个
# event表示鼠标事件,x,y是鼠标的坐标
# flags鼠标的组合按键.
def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)
    if event == 2:
        cv2.destroyAllWindows()


# 创建窗口
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 == ord('q'):
        break
cv2.destroyAllWindows()

这里通过 numpy 生成全黑背景,然后鼠标的每一次移动,都会传递五个参数到 mouse_callback 这个回调函数上。
其中 x,y 是鼠标的窗口坐标,userdata 为用户数据,方便回调函数知道这是哪里产生的回调。
然后 event 是鼠标事件,flags 是鼠标的组合按键,总结如下:

  • 鼠标事件
    • EVENT_MOUSEMOVE 0 鼠标移动
    • EVENT_LBUTTONDOWN 1 按下鼠标左键
    • EVENT_RBUTTONDOWN 2 按下鼠标右键
    • EVENT_MBUTTONDOWN 3 按下鼠标中键
    • EVENT_LBUTTONUP 4 左键释放
    • EVENT_RBUTTONUP 5 右键释放
    • EVENT_MBUTTONUP 6 中键释放
    • EVENT_LBUTTONDBLCLK 7 左键双击
    • EVENT_RBUTTONDBLCLK 8 右键双击
    • EVENT_MOUSEWHEEL 10 鼠标滚轮上下滚动
    • EVENT_MOUSEHWHEEL 11 鼠标左右滚动
  • 鼠标的组合按键
    • EVENT_FLAG_LBUTTON 1 按下左键
    • EVENT_FLAG_RBUTTON 2 按下右键
    • EVENT_FLAG_MBUTTON 4 按下中键
    • EVENT_FLAG_CTRLKEY 8 按下ctrl键
    • EVENT_FLAG_SHIFTKEY 16 按下shift键
    • EVENT_FLAG_ALTKEY 32 按下alt键

也不是都要记住,在有提示的编辑器中,比如 PyCharm 中就能通过如下方法获取:

【OpenCV学习】初识OpenCV其二_第3张图片
【OpenCV学习】初识OpenCV其二_第4张图片

trackbar

这个组件的意思就是滑动条,这里演示一段 “调色板” 的代码:

from cv2 import cv2
import numpy as np
# 创建窗口
cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar', 640, 480)


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


# 创建3个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]
    cv2.imshow('trackbar', img)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
cv2.destroyAllWindows()

运行后效果如下:

【OpenCV学习】初识OpenCV其二_第5张图片

当然我还没学到像 tkinter 模块那样能自由调整组件位置,我也不知道他能不能调节位置,但我知道他能调色。
原理就是循环,每次循环都会获得 R、G、B 颜色的值,然后对三维数组的所有最内层数组赋值为 [b, g, r] 要注意这里的顺序不是 R、G、B ,不然你调红就会变蓝,你调蓝就会变红(不要问我为什么这么有经验…)。

你可能感兴趣的:(OpenCV从入门到放弃,opencv,计算机视觉,学习)