打印
[其他ST产品]

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

[复制链接]
606|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
第三十八章 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模块提供的标签家族常量
fxfy指的是以像素为单位的相机XY方向的焦距。
cxcy指的是图像的中心XY坐标,即image.width() // 2和image.height() //2,而不是roi.width() // 2roi.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码识别

使用特权

评论回复
沙发
AloneKaven| | 2024-8-26 10:25 | 只看该作者
AprilTag码是用在什么地方的啊?

使用特权

评论回复
板凳
AloneKaven| | 2024-8-26 10:26 | 只看该作者
DM码好像生活中也没见过

使用特权

评论回复
地板
xionghaoyun| | 2024-8-26 13:55 | 只看该作者
学习一下

使用特权

评论回复
5
正点原子官方|  楼主 | 2024-8-26 17:13 | 只看该作者
AloneKaven 发表于 2024-8-26 10:25
AprilTag码是用在什么地方的啊?

多用在于机器视觉和机器人导航等领域吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

91

主题

92

帖子

1

粉丝