你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

成功在 stm32 上用 Zbar 库识别二维码!

[复制链接]
国际哥不是国际歌 发布时间:2019-6-29 11:07
       目前能在网上找到的二维码资料,都是编码居多,也就是从一串字符串生成二维码(常用算法如 QRCode),而解码识别方面的参考教程比较少。二维码解码库有 Quirc、Zbar 等,更多的开发者是用在安卓、OpenCV 和 Python 等高级环境上,对于 MCU 级别的使用,并且基本是经过封装后的实现,灵活性较差。于是便想着自己从头使用 Zbar 库的接口,实现图片中的二维码检测及识别。
测试环境
  • 开发板:STM32F429I Disco
  • CPU:Arm® 32-bit Cortex®-M4 180 MHz
  • 内存:2Mbytes Flash, 256KMbytes RAM, 64-Mbit 外部 SDRAM
  • 软件:RT-Thread 操作系统
实现过程
        这里说明一下,Zbar 库要求输入的是灰度图像数据(也就是黑白照),每个像素用一个字节表示灰度,从 0x00 全白到 0xff 全黑,有了图像数据,再传入图像的宽高便能解码了。
通过 Zbar 库识别二维码,大致可以分为下面 3 个过程:
  • 创建配置 image_scanner、zbar_image 对象,并设置图像信息
  • 扫描图像并识别
  • 提取解码结果
        我写了一个函数,能够直接读取 bmp 8 位灰度图片(因为 bmp 文件包含了图像数据便于处理),并打印输出其中的二维码识别结果:

  1. #include <rtthread.h>
  2. #include <rtdevice.h>

  3. #include "zbar.h"

  4. #define BITMAP_IMG_OFFSET               0x0A
  5. #define BITMAP_IMG_WIDTH_OFFSET         0x12
  6. #define BITMAP_IMG_HEIGHT_OFFSET        0x16
  7. #define BITMAP_IMG_FILE_SIZE_OFFSET     0x02

  8. zbar_image_scanner_t *rt_scanner = NULL;

  9. void qr_bitmap_decoder(const rt_uint8_t *img_buffer)
  10. {
  11.     /* create a reader */
  12.     rt_scanner = zbar_image_scanner_create();

  13.     /* configure the reader */
  14.     zbar_image_scanner_set_config(rt_scanner, 0, ZBAR_CFG_ENABLE, 1);

  15.     /* obtain image data */
  16.     void *raw = (void *)img_buffer;

  17.     int img_width = *(int *)(&img_buffer[BITMAP_IMG_WIDTH_OFFSET]);
  18.     int img_height = *(int *)(&img_buffer[BITMAP_IMG_HEIGHT_OFFSET]);
  19.     int img_offset = *(int *)(&img_buffer[BITMAP_IMG_OFFSET]);
  20.     int file_size = *(int *)(&img_buffer[BITMAP_IMG_FILE_SIZE_OFFSET]);

  21.     rt_kprintf("img_info: width=%d, height=%d, file_size=%d\n", img_width, img_height, file_size);

  22.     /* wrap image data */
  23.     zbar_image_t *image = zbar_image_create();
  24.     zbar_image_set_format(image, *(int*)"Y800");
  25.     zbar_image_set_size(image, img_width, img_height);
  26.     zbar_image_set_data(image, (void *)(&img_buffer[img_offset]), img_width * img_height, zbar_image_free_data);

  27.     /* scan the image for barcodes */
  28.     int n = zbar_scan_image(rt_scanner, image);

  29.     /* extract results */
  30.     const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
  31.     for(; symbol; symbol = zbar_symbol_next(symbol)) {
  32.         /* do something useful with results */
  33.         zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
  34.         const char *data = zbar_symbol_get_data(symbol);
  35.         rt_kprintf("decoded %s symbol "%s"\n",
  36.                zbar_get_symbol_name(typ), data);
  37.     }

  38.     /* clean up */
  39.     zbar_image_destroy(image);
  40.     zbar_image_scanner_destroy(rt_scanner);
  41. }
复制代码



运行结果
        来看下实测的识别效果,RT-Thread 提供了 finsh Shell,可以很方便地使用命令行的方式运行写好的测试例程:
样本1(图片尺寸 256*256,纯二维码):
样本2(图片尺寸 480*360,摄像头拍摄):
1 收藏 3 评论6 发布时间:2019-6-29 11:07

举报

6个回答
lwg8458 回答时间:2019-6-29 11:24:25
强!!!!!
STMWoodData 回答时间:2019-6-29 11:27:37
提示: 作者被禁止或删除 内容自动屏蔽
andey 回答时间:2019-6-29 14:09:52
提示: 作者被禁止或删除 内容自动屏蔽
TLLED 回答时间:2019-6-30 07:44:26
厉害
搞个大新闻 回答时间:2019-6-30 15:14:00
赞一个,谢谢分享
yipan 回答时间:2020-9-24 22:19:18
大神您好,能否帮忙把您用来做测试的灰度图发到我的邮箱 ypan@senecasense.com
我移植zbar到arm上,找不到啥问题但就是扫不到码zbar_scan_image始终返回0

谢谢

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版