【正点原子K210连载】第三十八章 image码识别实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第三十八章 image码识别实验

在上一章节中,介绍了image模块中图像对比方法给的使用,本章将继续介绍image模块中码识别方法的使用。通过本章的学习,读者将学习到image模块中码识别的使用。
本章分为如下几个小节:
38.1 image模块码识别方法介绍
38.2 硬件设计
38.3 程序设计
38.4 运行验证

38.1 image模块码识别方法介绍
image模块为Image对象提供了find_barcodes()方法,用于识别图像中的条形码,find_barcodes()方法如下所示:
image.find_barcodes(roi)
find_barcodes()方法用于识别图像中的条形码,并会返回一个image.barcode对象列表,由于条形码的特殊性,条形码是一维图像,所以只需在一个方向上有较高的分辨率,而在另一个方向上秩序较低的分辨率。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
find_barcode()方法会返回一个image.barcode对象列表。
find_barcode()方法的使用示例如下所示:
import image

img = image.Image(size=(320, 240))
barcodes = img.find_barcode()
if barcodes:
print(“%s” % (barcodes[0].payload))
image模块为Image对象提供了find_datamatrices()方法,用于识别图像中的DM码,find_datamatrices()方法如下所示:
image.find_datamatrices(roi, effort=200)
find_datamatrices()方法用于识别图像中的DM码,并返回一个image.datamatrix对象列表,该方法要求被识别图像中的DM码需要比较平展。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
effort指的是用于控制查找DM码匹配的时间,默认为200,这应该适用于大部分的使用场景,需要注意的是,当该参数配置为160以下,可能无法进行任何的DM码识别,并且当该参数可配置的最大值为240。
find_datamatrices()方法会返回一个image.datamatrix对象列表。
find_datamatrices()方法的使用示例如下所示:
import image

img = image.Image(size=(320, 240))
datamatrices = img.find_datamatrices()
if datamatrices:
print(“%s” % (datamatrices[0].payload))
image模块为Image对象提供了find_qrcodes()方法,用于识别图像中的二维码,并返回一个image.rqcode对象列表,find_rqcodes()方法如下所示:
image.find_rqcodes(roi)
find_rqcodes()方法用于识别图像中的二维码,并返回一个image.rqcode对象列表,该方法要求被识别图像中的二维码需要比较平展。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
find_rqcodes()方法会返回一个image.rqcode对象列表。
find_rqcodes()方法的使用示例如下所示:
import image

img = image.Image(size=(320, 240))
rqcodes = img.find_rqcodes()
if rqcodes:
print(“%s” % (rqcodes[0].payload))
image模块为Image对象提供了find_apriltags()方法,用于识别图像中的AprilTag码,并返回一个image.apriltag对象列表,find_apriltags()方法如下所示:
image.find_apriltags(roi, families=image.TAG36H11, fx, fy, cx, cy)
find_apriltags()方法用于识别图像中的AprilTag码,与二维码相比,AprilTag码可在更远距离、较差光线和更扭曲的图像环境下被检测并识别,AprilTag码可以应对所有种类的图像失真问题,而二维码不能,但是AprilTag码只能作为数字ID编码的载体。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
families指的是要解码的标签家族的位掩码,可以用逻辑或来同时指定解码多种标签家族,必须是image模块中定义号的标签家族常量,如下表所示:
常量 标签家族
image.TAG16H5 TAG16H5
image.TAG25H7 TAG25H7
image.TAG25H9 TAG25H9
image.TAG36H10 TAG36H10
image.TAG36H11 TAG36H11
image.ARTOOLKIT ARTOOLKIT
表38.1.1 image模块提供的标签家族常量
fx和fy指的是以像素为单位的相机X和Y方向的焦距。
cx和cy指的是图像的中心X和Y坐标,即image.width() // 2和image.height() //2,而不是roi.width() // 2和roi.height() // 2。
find_airiltags()方法会返回一个image.apriltag对象列表。
find_airiltags()方法的使用示例如下所示:

import image

img = image.Image(size=(320, 240))
apriltags = img.find_apriltags(families=image.TAG36H11)
if apriltags:
    print("%d" % (apriltags[0].id))

38.2 硬件设计
38.2.1 例程功能

  1. 获取摄像头输出的图像,并使用image模块对图像进行码识别,并在图像上绘制识别到的内容,然后将图像显示在LCD上。
  2. 当KEY0按键被按下后,切换image模块识别图像中不同种类的码。
    38.2.2 硬件资源
    本章实验内容,主要讲解image模块的使用,无需关注硬件资源。
    38.2.3 原理图
    本章实验内容,主要讲解image模块的使用,无需关注原理图。
    38.3 程序设计
    38.3.1 image模块图像码识别方法介绍
    有关image模块图像码识别方法的介绍,请见第38.1小节《image模块图像码识别方法介绍》。
    38.3.2 程序流程图
    在这里插入图片描述

图38.3.2.1 image图像码识别实验流程图
38.3.3 main.py代码
main.py中的脚本代码如下所示:

from board import board_info
from fpioa_manager import fm
from maix import GPIO
import time
import lcd
import sensor
import image
import math
import gc

lcd.init()
sensor.reset()
sensor.set_framesize(sensor.QVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.set_hmirror(False)

type = 0
type_dict = {
    0: "Normal",
    1: "Barcode",
    2: "Data Matrices",
    3: "QRCode",
    4: "AprilTag"
}

fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)

def key_irq_handler(key):
    global key0
    global type
    time.sleep_ms(20)
    if key is key0 and key.value() == 0:
        type = type + 1
        if type == len(type_dict):
            type = 0
key0.irq(key_irq_handler, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT, 7)

while True:
    img = sensor.snapshot()
    if type == 0:
        pass
    elif type == 1:
        # 条形码识别
        roi = (img.width() // 2 - 120, img.height() // 2 - 80, 240, 160)
        gray = img.copy(roi).to_grayscale()
        img.draw_rectangle(roi, color=(0, 255, 0))
        barcodes = gray.find_barcodes((0, 0, gray.width(), gray.height()))
        if barcodes:
            img.draw_string(10, 30, barcodes[0].payload(), color=(255, 0, 0), scale=1.6)
    elif type == 2:
        # DM码识别
        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
        gray = img.copy(roi).to_grayscale()
        img.draw_rectangle(roi, color=(0, 255, 0))
        datamatrices = gray.find_datamatrices((0, 0, gray.width(), gray.height()))
        if datamatrices:
            img.draw_string(10, 30, datamatrices[0].payload(), color=(255, 0, 0), scale=1.6)
    elif type == 3:
        # 二维码识别
        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
        gray = img.copy(roi).to_grayscale()
        img.draw_rectangle(roi, color=(0, 255, 0))
        qrcodes = gray.find_qrcodes((0, 0, gray.width(), gray.height()))
        if qrcodes:
            img.draw_string(10, 30, qrcodes[0].payload(), color=(255, 0, 0), scale=1.6)
    elif type == 4:
        # AprilTag识别
        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
        gray = img.copy(roi).to_grayscale()
        img.draw_rectangle(roi, color=(0, 255, 0))
        apriltags = gray.find_apriltags((0, 0, gray.width(), gray.height()), families=image.TAG36H11)
        if apriltags:
            def shot_degrees(axis, y, rotation):
                degrees = (180 * rotation) / math.pi
                img.draw_string(10, y, "{:s}:{:.0f}".format(axis, degrees), color=(255, 0, 0), scale=1.6)
            img.draw_string(10, 30, "ID:{:d}".format(apriltags[0].id()), color=(255, 0, 0), scale=1.6)
            shot_degrees("X", 50, apriltags[0].x_rotation())
            shot_degrees("Y", 70, apriltags[0].y_rotation())
            shot_degrees("Z", 90, apriltags[0].z_rotation())
    else:
        type = 0
    img.draw_string(10, 10, type_dict[type], color=(255, 0, 0), scale=1.6)
    lcd.display(img)
    gc.collect()

可以看到一开始是先初始化了LCD、摄像头和中断按键,并且按下中断按键可以切换不同的码识别方法类识别图像中不同种类的码。
接着在一个循环中不断地获取摄像头输出的图像,因为获取到的图像就是Image对象,因此可以直接调用image模块为Image对象提供的各种方法,然后就是对图像中的码进行检测和识别,并在LCD上绘制识别到码的信息,最后在LCD显示图像。
38.4 运行验证
将DNK210开发板连接CanMV IDE,点击CanMV IDE上的“开始(运行脚本)”按钮后,便能看到LCD上显示了摄像头输出的图像,并能看一个绿色的识别框,但将对应的码移入识别框后,能够看到LCD的左上角显示了识别到的结果,按下KEY0按键还能够切换识别码的种类,以识别不同种类的码,如下图所示:
在这里插入图片描述

图38.4.1 条形码识别
在这里插入图片描述

图38.4.2 DM码识别
在这里插入图片描述

图38.4.3 二维码识别
在这里插入图片描述

图38.4.4 AprilTag码识别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值