OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 43|回复: 0

《DNK210使用指南 -CanMV版 V1.0》第三十八章 image码识别实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4666
金钱
4666
注册时间
2019-5-8
在线时间
1224 小时
发表于 前天 17:59 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-11-20 17:59 编辑

第三十八章 image码识别实验

1)实验平台:正点原子DNK210开发板

2)章节摘自【正点原子】DNK210使用指南 - CanMV版 V1.0


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子K210技术交流企鹅群:605557868

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

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

38.1 image模块码识别方法介绍
image模块为Image对象提供了find_barcodes()方法,用于识别图像中的条形码,find_barcodes()方法如下所示:
  1. image.find_barcodes(roi)
复制代码
find_barcodes()方法用于识别图像中的条形码,并会返回一个image.barcode对象列表,由于条形码的特殊性,条形码是一维图像,所以只需在一个方向上有较高的分辨率,而在另一个方向上秩序较低的分辨率。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
find_barcode()方法会返回一个image.barcode对象列表。
find_barcode()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. barcodes = img.find_barcode()
  4. if barcodes:
  5.     print("%s" % (barcodes[0].payload))
复制代码
image模块为Image对象提供了find_datamatrices()方法,用于识别图像中的DM码,find_datamatrices()方法如下所示:
  1. 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()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. datamatrices = img.find_datamatrices()
  4. if datamatrices:
  5.     print("%s" % (datamatrices[0].payload))
复制代码
image模块为Image对象提供了find_qrcodes()方法,用于识别图像中的二维码,并返回一个image.rqcode对象列表,find_rqcodes()方法如下所示:
  1. image.find_rqcodes(roi)
复制代码
find_rqcodes()方法用于识别图像中的二维码,并返回一个image.rqcode对象列表,该方法要求被识别图像中的二维码需要比较平展。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
find_rqcodes()方法会返回一个image.rqcode对象列表。
find_rqcodes()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. rqcodes = img.find_rqcodes()
  4. if rqcodes:
  5.     print("%s" % (rqcodes[0].payload))
复制代码
image模块为Image对象提供了find_apriltags()方法,用于识别图像中的AprilTag码,并返回一个image.apriltag对象列表,find_apriltags()方法如下所示:
  1. image.find_apriltags(roi, families=image.TAG36H11, fx, fy, cx, cy)
复制代码
find_apriltags()方法用于识别图像中的AprilTag码,与二维码相比,AprilTag码可在更远距离、较差光线和更扭曲的图像环境下被检测并识别,AprilTag码可以应对所有种类的图像失真问题,而二维码不能,但是AprilTag码只能作为数字ID编码的载体。
roi指的是对Image对象感兴趣的区域,若未指定,即为图像矩形。
families指的是要解码的标签家族的位掩码,可以用逻辑或来同时指定解码多种标签家族,必须是image模块中定义号的标签家族常量,如下表所示:
QQ截图20241120175105.png
表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()方法的使用示例如下所示:
  1. import image
  2. img = image.Image(size=(320, 240))
  3. apriltags = img.find_apriltags(families=image.TAG36H11)
  4. if apriltags:
  5.     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 程序流程图                              
image002.png
图38.3.2.1image图像码识别实验流程图
38.3.3 main.py代码
main.py中的脚本代码如下所示:
  1. from board import board_info
  2. from fpioa_manager import fm
  3. from maix import GPIO
  4. import time
  5. import lcd
  6. import sensor
  7. import image
  8. import math
  9. import gc
  10. lcd.init()
  11. sensor.reset()
  12. sensor.set_framesize(sensor.QVGA)
  13. sensor.set_pixformat(sensor.RGB565)
  14. sensor.set_hmirror(False)
  15. type = 0
  16. type_dict = {
  17.     0: "Normal",
  18.     1: "Barcode",
  19.     2: "DataMatrices",
  20.     3: "QRCode",
  21.     4: "AprilTag"
  22. }
  23. fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
  24. key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)
  25. def key_irq_handler(key):
  26.     global key0
  27.     global type
  28.    time.sleep_ms(20)
  29.     if key is key0 and key.value() == 0:
  30.        type = type + 1
  31.        if type == len(type_dict):
  32.            type = 0
  33. key0.irq(key_irq_handler, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT, 7)
  34. while True:
  35.     img= sensor.snapshot()
  36.     if type == 0:
  37.        pass
  38.     elif type == 1:
  39.        # 条形码识别
  40.        roi = (img.width() // 2 - 120, img.height() // 2 - 80, 240, 160)
  41.        gray = img.copy(roi).to_grayscale()
  42.        img.draw_rectangle(roi, color=(0, 255, 0))
  43.        barcodes = gray.find_barcodes((0, 0, gray.width(), gray.height()))
  44.        if barcodes:
  45.            img.draw_string(10, 30, barcodes[0].payload(), color=(255, 0, 0), scale=1.6)
  46.     elif type == 2:
  47.        # DM码识别
  48.        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
  49.        gray = img.copy(roi).to_grayscale()
  50.        img.draw_rectangle(roi, color=(0, 255, 0))
  51.        datamatrices = gray.find_datamatrices((0, 0, gray.width(), gray.height()))
  52.        if datamatrices:
  53.            img.draw_string(10, 30, datamatrices[0].payload(), color=(255, 0, 0), scale=1.6)
  54.     elif type == 3:
  55.        # 二维码识别
  56.        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
  57.        gray = img.copy(roi).to_grayscale()
  58.        img.draw_rectangle(roi, color=(0, 255, 0))
  59.        qrcodes = gray.find_qrcodes((0, 0, gray.width(), gray.height()))
  60.        if qrcodes:
  61.            img.draw_string(10, 30, qrcodes[0].payload(), color=(255, 0, 0), scale=1.6)
  62.     elif type == 4:
  63.        # AprilTag识别
  64.        roi = (img.width() // 2 - 100, img.height() // 2 - 100, 200, 200)
  65.        gray = img.copy(roi).to_grayscale()
  66.        img.draw_rectangle(roi, color=(0, 255, 0))
  67.        apriltags = gray.find_apriltags((0, 0, gray.width(), gray.height()), families=image.TAG36H11)
  68.        if apriltags:
  69.            def shot_degrees(axis, y, rotation):
  70.                 degrees = (180 * rotation) / math.pi
  71.                 img.draw_string(10, y, "{:s}:{:.0f}".format(axis, degrees), color=(255, 0, 0), scale=1.6)
  72.            img.draw_string(10, 30, "ID:{:d}".format(apriltags[0].id()), color=(255, 0, 0), scale=1.6)
  73.            shot_degrees("X", 50, apriltags[0].x_rotation())
  74.            shot_degrees("Y", 70, apriltags[0].y_rotation())
  75.            shot_degrees("Z", 90, apriltags[0].z_rotation())
  76.     else:
  77.        type = 0
  78.     img.draw_string(10, 10, type_dict[type], color=(255, 0, 0), scale=1.6)
  79.     lcd.display(img)
  80.     gc.collect()
复制代码
可以看到一开始是先初始化了LCD、摄像头和中断按键,并且按下中断按键可以切换不同的码识别方法类识别图像中不同种类的码。
接着在一个循环中不断地获取摄像头输出的图像,因为获取到的图像就是Image对象,因此可以直接调用image模块为Image对象提供的各种方法,然后就是对图像中的码进行检测和识别,并在LCD上绘制识别到码的信息,最后在LCD显示图像。
38.4 运行验证
将DNK210开发板连接CanMV IDE,点击CanMV IDE上的“开始(运行脚本)”按钮后,便能看到LCD上显示了摄像头输出的图像,并能看一个绿色的识别框,但将对应的码移入识别框后,能够看到LCD的左上角显示了识别到的结果,按下KEY0按键还能够切换识别码的种类,以识别不同种类的码,如下图所示:     
image003.png
图38.4.1 条形码识别     
image005.png
图38.4.2 DM码识别     
image007.png
图38.4.3 二维码识别     
image009.png

图38.4.4 AprilTag码识别

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 00:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表