• OpenCV:01图片&视频的加载显示


    学习目标:

    • 了解OpenCV的运行机制
    • 可以使用OpenCV处理一些图像常见问题
    • 学会物体识别,文字识别等问题的处理思路

    图像与视频的加载显示

    导入OpenCV的包cv2

    # 导入opencv的包
    import cv2
    
    • 1
    • 2

    窗口操作

    cv2.imshow('window',0) # imshow(winname, mat):'mat’表示展示的内容,0表示什么都不展示

    # 创建窗口
    #cv2.namedWindow('window',cv2.WINDOW_AUTOSIZE)
    cv2.namedWindow('window',cv2.WINDOW_NORMAL)
    
    # 更改窗口大小—>在窗口属性为‘WINDOW_AUTOSIZE’自动设置时无效果
    cv2.resizeWindow('window',800,600) # resizeWindow(winname, width, height)
    
    # 展示名字为window的窗口
    cv2.imshow('window',0) # imshow(winname, mat):'mat'表示展示的内容,0表示什么都不展示
    
    # 等待按键
    #cv2.waitKey(0) # waitKey会返回按下按键的ASCII值(8位)
                  # 值为‘0’表示接受任意按键,如果给其他的整数,表示等待按键的时间(单位:毫秒ms)
                # 比如waitKey(5000)如果5000ms后没有按键,则窗口无响应
            # 可以用waitKey来销毁窗口,不用每次都重启python
    key = cv2.waitKey(0)
    if key == ord('q'): # 如果按下键盘上的'q'
        print("准备销毁窗口")
        cv2.destroyAllWindows() # 销毁窗口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    计算按键的ASCII

    # 怎么计算按键'x'的ASCII码
    # ord()是python中计算ASCII值的函数
    ord('q')
    
    • 1
    • 2
    • 3

    读取图片

    cv2.imread('./cat.jpeg') # ./是直接调用day1目录下的文件
    
    • 1

    用其他插件来读取(以matplotlib为例)

    先将图片存入我们的文件夹下,命名为cat.jpeg
    在这里插入图片描述

    import matplotlib.pyplot as plt
    # 默认按照彩色图片来读取
    cat = cv2.imread('./cat.jpeg') # ./是直接调用day1目录下的文件
    
    # 调出cat的值
    cat
    
    
    # 利用matplotlib来显示图像
    plt.imshow(cat)
    
    # 我们会发现matplotlib显示的图片和真实的图片颜色不一样,发生了变化
        # 因为opencv读进来的通道不是默认的RGB(红绿蓝)通道,而是BGR(蓝绿红)
        # 因此opencv读进来的图片不要用别的方式去展示(如matplotlib),而是用opencv自带的方式去展示
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:单独调用imshow()时可以不用创建窗口,opencv会自动生成
    在这里插入图片描述


    OpenCV自带的方式去展示图片

    cv2.imshow('cat',cat)
    key = cv2.waitKey(0)
    if key == ord('q'): # 如果按下键盘上的'q'
        print("准备销毁窗口")
        cv2.destroyAllWindows() # 销毁窗口
        
    # 执行时会弹出窗口,显示图片     按‘q’则退出窗口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    函数的封装

    如果我们需要频繁地显示图片,那么我们可以把显示图片的方法封装成一个函数方便我们显示图片

    把这个函数放在一个文件里,需要使用的话就直接导入文件即可

    将函数保存为.py文件(命名为utils.py),放在我们的文件夹中

    # 如果我们需要频繁地显示图片,那么我们可以把显示图片的方法封装成一个函数方便我们显示图片
        # 把这个函数放在一个文件里,需要使用的话就直接导入文件即可
    def cv_show(name,img):
        import cv2
        cv2.imshow(name,img)
        
        # 关闭窗口
        key = cv2.waitKey(0)
        if key  == ord('q') or key == ord('Q'):
            cv2.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    想要调用函数时,我们导入文件即可

    # 从外部py文件中导入工具类,即可直接使用
    from utils import cv_show
    
    • 1
    • 2

    注意:导入后必须先执行文件!

    # 导入后必须先执行文件
    %run utils.py
    
    # 如果出现报错IndentationError:unindent does not match any outer indentation level
        # 那就是Tab和空格混用的缩进问题:本应该用Tab缩进,可能打成了空格缩进
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用函数

    cv_show('cat',cat)
    
    • 1

    保存图片

    imwrite(path,img):使用imwrite保存图片

    import cv2
    
    # 创建一个窗口
    cv2.namedWindow('img',cv2.WINDOW_NORMAL)
    cv2.resizeWindow('img',640,480)
    
    # 读一个图片
    img = cv2.imread('./cat.jpeg') # 打开当前目录下的图像文件
    
    while True:# 进入循环,使得cv2不停地展示img图片
        cv2.imshow('img',img)
        key = cv2.waitKey(0) # 接受任意字符——>写0
        
        if key == ord('q'): # 按下按键'q'——> quit
            break
        elif key == ord('s'): # 按下按键's'——> save
            cv2.imwrite('./123.png',img) # 会把cv2.imshow('img',img)的图片保存到当前文件下下,命名为123.png
        else:
            print(key)
    
    # 关闭窗口
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述


    读取摄像头与视频数据

    打开摄像头

    • 视频是由图片组成的,视频的每一帧就是一幅图片,一般是30帧,表示1s显示30张图片
    • cv2.VideoCapture()可以捕获摄像头,用数字来表示不同的设备,比如0,1
    • 如果是视频文件,可以直接指定路径即可
    import cv2
    # VideoCapture()可以捕获摄像头:如果是视频文件,则直接在参数中写入路径即可;如果是电脑上的摄像头,则可以根据摄像头编号进行索引,通过这个简单的数字去指定调用的摄像头
    
    
    # 打开视频文件 #
    #vc = cv2.VideoCapture()  
    
    # 打开摄像头 #
    cv2.namedWindow('video',cv2.WINDOW_NORMAL)
    cv2.resizeWindow('video',640,480)
    
    # 如果打开失败或者没读到数据,会闪退,但并不会报错
    #cap = cv2.VideoCapture(1)
    
    cap = cv2.VideoCapture(0) # 该函数会返回一个对象,我们用cap来接受(0是笔记本自带的摄像头)
    
    # 循环读取摄像头的每一帧
    while True:
        # 读一帧数据(一帧=视频里的一幅图) 
        flag,frame = cap.read() # 返回“标记”和“这一帧数据(图片)”:True表示读取成功,False表示读取失败
        
        # 可以根据flag做判断
        if not flag:
            print("没读到数据!退出......")
            break
            
        # 显示数据
        else:
            cv2.imshow('video',frame)
            
        key = cv2.waitKey(1) # 此处不可以写0!因为0会允许任何输入并且一直在等待输入,如果这样写就只能看到一帧数据,并且一直在等待
                             # 此处写1,每隔1ms检测一次输入
        if key == ord('q'):
            break
            
    # 别忘了释放资源!
    cap.release()
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    打开视频

    打开视频的操作和打开摄像头是一样的:只需要修改cap = cv2.VideoCapture(0)cap = cv2.VideoCapture(‘./1.mp4’) # 括号内为路径即可

    放出的视频会有加速的效果:是因为我们的代码中key = cv2.waitKey(1)每隔1ms就执行下一张图片

    那么我们为了完整播放这个视频,提出了一个问题:假如一个视频是30帧,那么每张图之间要间隔多少毫秒呢

    # 1帧 = 1s内显示1张图片,每张图片用时t = 1/1(s) = 1000/1(ms)
    # 30帧 = 1s内显示30张图片,每张图片用时t = 1/30(s) = 1000/30(ms)
    
    key = cv2.waitKey(1000 // 30)	# 括号内必须是整数!"//"两个斜线表示除后向下取整
    
    • 1
    • 2
    • 3
    • 4

    视频录制

    opencv打开一个视频或一个摄像头,我们把捕获到的每一帧存储在一个视频中

    • VideoWrite:参数一为输出文件,参数二为多媒体文件格式,参数三为帧率,参数四为分辨率
    • write:编码并写入缓存
    • release:缓存内容写入磁盘,并释放资源
    import cv2
    cap = cv2.VideoCapture(0) # 把摄像头捕获的内容存入cap中
    
    # 创建对象 (fourcc表示视频的一种格式)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v') # *mp4v表示“解包操作”——> 等同于解成'm','p','4','v'
    
    # 创建对象
    vw = cv2.VideoWriter('output.mp4',fourcc,30,(640,480)) # ('保存的文件名',指定存储的格式,帧率,摄像头的分辨率(一定要正确否则报错!))
    
    # 判断摄像头是否打开
    while cap.isOpened() :
        ret,frame = cap.read()
        if not ret: # 如果没有打开
            print('can not recive frame ,Exiting...')
            break
            
        else : # 如果成功打开——> 写每一帧数据
            vw.write(frame) # 把 这一帧数据 写到Videowriter中
            cv2.imshow('frame',frame) # 展示 这一帧数据 到窗口
            
        if cv2.waitKey(1) == ord('q') or cv2.waitKey(1) == ord('Q'):
            break
    
    # 别忘了release
    cap.release()
            
    # 释放Videowriter
    vw.release() # write是先写到缓存中,再由release写入到磁盘中 
    
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    控制鼠标

    OpenCV允许我们对窗口上的鼠标动作做出响应

    • setMouseCallback(winname,callback,userdata)winname是窗口的名字,callback是回调函数,userdata是给回调函数的参数
    • callback(event,x,y,flags,userdata):回调函数必须包含这5个参数:event是事件(鼠标移动,按下左键、右键…);xy是鼠标的坐标点;flags主要用于组合键;userdata就是上面的setMouseCallbackuserdata
      在这里插入图片描述

    在这里插入图片描述

    # opencv控制鼠标
    import cv2
    import numpy as np
    
    # 定义鼠标的回调函数(函数名可以随便取,但是参数必须是五个!)
    def mouse_callback(event,x,y,flags,userdata): # event:鼠标事件;xy:鼠标坐标;flags:鼠标的组合操作;userdata:传给用户的数据
        print(event,x,y,flags,userdata)
        
        # 增加功能:按下鼠标右键退出
        if event == 2:
            cv2.destroyAllWindows() # 窗口会闪一下 然后继续出现,其实我们是运行成功了,只不过下方是个死循环,会一直存在
        
    # 创建窗口
    cv2.namedWindow('mouse',cv2.WINDOW_NORMAL)
    cv2.resizeWindow('mouse',640,360) # 宽度(列)和高度(行)
    
    cat = cv2.imread('./cat.jpeg')
    
    
    # 设置鼠标的回调函数
    cv2.setMouseCallback('mouse',mouse_callback,'123') # '123'为用户数据,会传到上方的参数userdata中
        # 在我们生成的mouse的窗口上,做任何鼠标的操作,它都会去执行我们定义的mouse_callback()函数
    
    # 生成一个全黑的图片(先行后列——> 要和上面反过来)
    img = np.zeros((360,640,3),np.uint8) # np.zeros()生成全是0的图片  np.uint8表示0-255 u表示无符号
    
    # 循环展示图片
    while True:
    #     cv2.imshow('mouse',img) # 展示刚才生成的全黑图片
        cv2.imshow('mouse',cat) # 展示猫
        key = cv2.waitKey(1)
        
        if key == ord('q') or key == ord('Q'):
            break
            
    cv2.destroyAllWindows()
        
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    TrackBar控件

    TrackBar是一个可拖动的控件,可以用于控制RGB

    现在我们创建一个调整RGB的TrackBar,用调整的值来生成一张图片,通过拖到TrackBar来随时改变这个图片的颜色

    • cv2.createTrackbar(trackbarName, windowName, value, count, onChange)创建trackbar控件:valuetrackbar的默认值(开始时游标的位置),coutbar的最大值和最小值(是两个值),onChange为回调函数,每次修改这个值就会跳入该函数
    • cv2.getTrackbarPos(trackbarName, windowName):获取当前TrackBar的值
    # trackbar的使用
    import cv2
    import numpy as np
    
    # 创建窗口
    cv2.namedWindow('trackbar',cv2.WINDOW_NORMAL)
    cv2.resizeWindow('trackbar',640,480)
    
    # 定义回调函数 ——> 我们用这个函数来打印当前的值
    def callback(value):
        print(value)
        
    # 创建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] # opencv里的图片颜色通道就是BGR 
        
        # 展示图片
        cv2.imshow('trackbar',img)
        
        # 退出
        key = cv2.waitKey(1)
        if key == ord('q') or key == ord('Q'):
            break
            
    # 释放空间
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    结果:
    在这里插入图片描述

  • 相关阅读:
    Vue发布自定义组件库
    千里马常有而伯乐不常有啊
    网站后台删除文章时,如何把内容中的图片也一并删除?
    VUE 组件传值 $emit之 $event和arguments
    web组态(BY组态)接入流程
    广工电工与电子技术实验报告-8路彩灯循环控制电路
    小程序代码管理
    JavaEE进阶 - Spring Boot 配置文件 - 细节狂魔
    融云IM(即时通讯服务)
    Spring整合Mybatis和Junit小案例(9)
  • 原文地址:https://blog.csdn.net/m0_59466249/article/details/125452030