第二十六章 摄像头图像捕获实验 本章将介绍CanMV下摄像头的使用,能通过摄像头实时地采集摄像头捕获到的图像数据,从而进行进一步的处理。通过本章的学习,读者将学习到通过CanMV驱动摄像头实时捕获图像数据。 本章分为如下几个小节: 26.1 sensor模块介绍 26.2 硬件设计 26.3 程序设计 26.4 运行验证 26.1 sensor模块介绍 sensor模块是CanMV内置的模块,sensor模块用于驱动摄像头,能够对摄像头进行配置并进行图像数据的捕获,从而实现一些拍摄任务。 sensor模块提供了reset()函数,用于重置并初始化摄像头,reset()函数如下所示: sensor.reset(freq=24000000, set_regs=True, choice=0, dual_buff=False) reset()函数用于重置并初始化摄像头,该函数能够自动识别接入的且被支持的摄像头类型,并根据不同的摄像头进行不同的重置并初始化操作. freq指的是摄像头像素时钟的频率,若该参数为空,则使用默认的24MHz。 set_regs指的是否让程序在初始化摄像头的过程中配置摄像头的寄存器,若开发者希望使用另外的寄存器配置方式初始化摄像头,可以将该参数配置为False,然后使用相应的寄存器配置函数自行配置摄像头的寄存器,该参数默认为True。 choice指的是接入的摄像头的类型,可选的参数如下表所示: 表26.1.1 choice可选参数描述 dual_buff指的是是否使能摄像头的双缓冲模式,当为True时,将使能双缓冲模式,此时sensor模块会为摄像头的帧缓冲分配两个大小均为帧大小的缓冲区,因此会更加占用内存,但好处是摄像头的捕获帧率在某些情况下可能会有所提升,当为False时,将禁用双缓冲模式,此时sensor模块将只会为摄像头的帧缓冲分配一个大小为帧大小的缓冲区,因此会更加地节省内存。 reset()函数的使用示例如下所示: import sensor sensor.reset() sensor模块提供了set_framesize()函数,用于配置摄像头输出的帧大小,set_framesize()函数如下所示: sensor.set_framesize(framesize, set_regs=True) set_framesize()函数用于配置摄像头输出的帧大小,也就是输出图像的像素分辨率,由于Kendryte K210的DVP最大支持的帧大小为640*480,因此摄像头输出的帧大小不应该超出这个值。 framesize指的是要配置的帧大小,可选的参数如下所示: 表26.1.2 framesize可选参数 set_regs指的是是否让程序在配置摄像头驱动程序时,根据所配置的帧大小配置摄像头的寄存器,若开发者希望自行配置摄像头的寄存器,可以将该参数配置为False,该参数默认为True。 set_framesize()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor模块提供了set_pixformat()函数,用于配置摄像头输出图像的像素格式,set_pixformat()函数如下所示: sensor.set_pixformat(format, set_regs) set_pixformat()函数用于配置摄像头输出图像的像素格式,由于DNK210开发板上的LCD屏幕使用的是RGB565的像素格式,因此推荐配置摄像头输出图像的像素格式也是RGB565. format指的是要配置的图像像素格式,可选的参数如下所示: 表26.1.3 format可选参数 set_regs指的是是否让程序在配置摄像头驱动程序时,根据所配置的像素格式配置摄像头的寄存器,若开发者希望自行配置摄像头的寄存器,可以将该参数配置为False,该参数默认为True。 set_pixformat()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor模块提供了snapshot()函数,用于获取摄像头捕获到的图像数据,snapshot()函数如下所示: sensor.snapshot(update_jb=True) snapshot()函数用于获取摄像头捕获到的图像数据,并返回一个Image对象。 update_jb指的是是否将捕获到的图像数据上传到CanMV IDE软件,当为True时,snapshot()函数捕获到的图像数据会被进行JPEG编码压缩后上传到CanMV IDE软件,这么一来便能在CanMV IDE软件的“帧缓冲区”窗口中看到snapshot()函数捕获到的图像数据,当为False时,snpshot()函数捕获到的图像数据不会被上传到CanMV IDE软件,这样的好处是,当与CanMV IDE软件连接时不用进行JPEG编码压缩以及图像数据上传的任务,从而降低CPU的使用率。 snapshot()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) img = sensor.snapshot() sensor模块提供了set_hmirror()函数,用于使能摄像头输出图像的水平镜像操作,set_hmirror()函数如下所示: sensor.set_hmirror(enable) set_hmirror()函数用于使能摄像头输出图像的水平镜像操作。 enable指的是是否使能摄像头输出图像的水平镜像功能,当为True时,使能摄像头输出图像的水平镜像功能,当为False时,禁止摄像头输出图像的水平镜像功能。 set_hmirror()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) img = sensor.snapshot() sensor模块提供了set_vflip()函数,用于使能摄像头输出图像的垂直翻转操作,set_vflip()函数如下所示: sensor.set_vflip(enable) set_vflip()函数用于使能摄像头输出图像的垂直翻转操作。 enable指的是是否使能摄像头输出图像的垂直翻转功能,当为True时,使能摄像头输出图像的垂直翻转功能,当为False时,禁止摄像头输出图像的垂直翻转功能。 set_vflip()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_vflip(False) img = sensor.snapshot() sensor模块提供了set_jb_quality()函数,用于配置上传到CanMV IDE软件的JPEG图像的质量,set_jb_quality()函数如下所示: sensor.set_jb_quality(quality=35) set_jb_quality()函数用于配置上传到CanMV IDE软件的JPEG图像的质量,因为上传到CanMV IDE软件的图像会被先压缩成JPEG格式在进行上传,JPEG压缩时可以配置JPEG压缩的质量,这个质量越高压缩的程度越小,画面越精细,但压缩出来的JPEG图像体积也越大,反之如果JPEG压缩时配置的JPEG压缩质量越低,则压缩的程度越大,画面越粗糙,但压缩出来的JPEG图像体积也越小。 quality指的时JPEG图像压缩式的质量,范围为[0, 100]。 set_jb_quality()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_jb_quality(35) img = sensor.snapshot() sensor模块提供了set_contrast()函数,用于配置摄像头输出图像的对比度,set_contrast()函数如下所示: sensor.set_contrast(contrast) set_contrast()函数用于配置摄像头输出图像的对比度。 contrast指的是对比度的值,范围为[-2, 2] set_contrast()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_contrast(0) img = sensor.snapshot() sensor模块提供了set_brightness()函数,用于配置摄像头输出图像的亮度,set_brightness()函数如下所示: sensor.set_brightness(brightness) set_brightness()函数用于配置摄像头输出图像的亮度。 brightness指的是亮度的值,范围为[-2, 2] set_brightness()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_brightness(0) img = sensor.snapshot() sensor模块提供了set_saturation()函数,用于配置摄像头输出图像的饱和度,set_saturation()函数如下所示: sensor.set_saturation(saturation) set_saturation()函数用于配置摄像头输出图像的饱和度。 saturation指的是饱和度的值,范围为[-2, 2] set_saturation()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_saturation(0) img = sensor.snapshot() sensor模块提供了set_auto_gain()函数,用于配置摄像头自动增益,set_auto_gain()函数如下所示: sensor.set_auto_gain(enable, gain_db, gain_db_ceiling) set_auto_gain()函数用于配置摄像头的自动增益以及自动增益的上限值等。 enable指的是是否使能摄像头的自动增益,当为True时,使能摄像头的自动增益,当为False时,则不是能摄像头的自动增益。 gain_db指的是当不是能摄像头的自动增益时,设定的固定增益值,单位为dB,需要注意的时,当需要使用颜色追踪功能的时候,建议关闭摄像头的自动增益。 gain_db_ceiling指的是使能摄像头自动增益时,自动增益的上限值。 set_auto_gain()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_auto_gain(True, gain_db=0, gain_db_ceiling=16.0) img = sensor.snapshot() sensor模块提供了set_auto_whitebal()函数,用于配置摄像头的自动白平衡,set_auto_whitebal()函数如下所示: sensor.set_auto_whitebal(enable) set_auto_whitebal()函数用于配置摄像头的自动白平衡。 enable指的是是否使能摄像头的自动白平衡功能,当为True时,则使能摄像头的自动白平衡功能,当为False时,则不使能摄像头的自动白平衡功能。 set_auto_whitebal()函数的使用示例如下所示: import sensor sensor.reset() sensor.set_framesize(sensor.QVGA) sensor.set_pixformat(sensor.RGB565) sensor.set_hmirror(False) sensor.set_auto_whitebal(True) img = sensor.snapshot() sensor模块提供了__write_reg()函数,用于写入摄像头的寄存器,__write_reg()函数如下所示: sensor.__write_reg(address, value) sensor.__write_reg()函数用于使用SCCB接口写入摄像头的寄存器。 address指的是摄像头的寄存器地址。 value指的是待写入摄像头寄存器的值。 __write_reg()函数的使用示例如下所示: import sensor sensor.reset() sensor.__write_reg(0xFF, 0x01) sensor模块提供了__read_reg()函数,用于读取摄像头的寄存器,__read_reg()函数如下所示: sensor.__read_reg(address) sensor.__read_reg()函数用于使用SCCB接口读取摄像头的寄存器,并返回读取到的值。 address指的是摄像头的寄存器地址。 __read_reg()函数的使用示例如下所示: import sensor sensor.reset() pid = sensor.__read_reg(0x0A) << 8 pid |= sensor.__read_reg(0x0B) print("Sensor's product ID: 0x%04X" %(pid)) 26.2 硬件设计 26.2.1 例程功能 1. 使用sensor模块初始化板载的摄像头,并配置摄像头的输出帧大小以及输出格式等进行配置,最后获取摄像头采集到的图像数据,并在LCD以及CanMV IDE软件的“帧缓冲区”窗口进行显示。 26.2.2 硬件资源 1. 摄像头 SCCB_SDA - IO40 SCCB_SCL - IO41 DVP_RESET - IO42 DVP_VSYNC - IO43 DVP_PWDN - IO44 DVP_HREF - IO45 DVP_XCLK - IO46 DVP_PCLK - IO47 D0~D7 - DVP_D0~DVP_D7 2. LCD LCD_RD - IO34 LCD_BL - IO35 LCD_CS - IO36 LCD_RST - IO37 LCD_RS - IO38 LCD_WR - IO39 LCD_D0~LCD_D7 - SPI0_D0~SPI0_D7 26.2.3 原理图 本章实验内容,需要使用到板载的摄像头接口,在正点原子DNK210开发板上有两处摄像头接口分别为位于正点原子DNK210开发板底板上的ATK-MC2640摄像头模块接口,该接口用于连接正点原子的ATK-MC2640模块,另一个摄像头接口位于正点原子CNK210F核心板,该接口同于直接连接OV2640等摄像头模组,但需要特别注意的是,这两个摄像头接口不能同时使用,否则可能导致硬件损坏。 正点原子DNK210开发板上的ATK-MC2640摄像头模块接口的连接原理图,如下图所示:
图26.2.3.1 ATK-MC2640摄像头模块接口原理图 正点原子CNK210F核心板上的OV2640等摄像头模组接口的连接原理图,如下图所示:
图26.2.3.2 OV2640等摄像头模组接口原理图 26.3 程序设计 26.3.1 sensor模块 有关sensor模块的介绍,请见第26.1小节《sensor模块介绍》。 26.3.2 程序流程图
图26.3.2.1 摄像头图像捕获实验流程图 26.3.3 main.py代码 main.py中的脚本代码如下所示: import lcd import sensor # 初始化LCD lcd.init() # 初始化摄像头 sensor.reset() # 设置摄像头输出帧大小 sensor.set_framesize(sensor.QVGA) # 设置摄像头输出格式 sensor.set_pixformat(sensor.RGB565) # 设置摄像头水平镜像 sensor.set_hmirror(False) while True: # 获取摄像头输出图像 img = sensor.snapshot() # 显示摄像头输出图像至LCD lcd.display(img) 可以看到首先对LCD和摄像头进行了初始化。 接着是配置摄像头输出的帧大小以及输出格式。 然后是针对摄像头的摆放方向配置摄像头进行水平镜像,水平镜像后后续才能在LCD和CanMV IDE软件的“帧缓冲区”窗口中看到“较为正常”的图像画面。 最后就是在一个循环中不断地获取摄像头输出的图像数据,然后将图像在LCD显示屏上进行显示。 26.4 运行验证 将DNK210开发板连接CanMV IDE后,点击CanMV IDE上的“开始(运行脚本)”按钮后,可以看到LCD上实时地显示这摄像头采集到的画面,如下图所示:
图26.4.1 LCD显示摄像头采集图像 此时,若使能了CanMV IDE软件的“帧缓冲区”窗口功能,则同时能在CanMV IDE软件的“帧缓冲区”窗口看到摄像头采集的图像画面,如下图所示:
图26.4.2 CanMV IDE软件“帧缓冲区”窗口显示摄像头采集图像
|