硬汉嵌入式论坛

 找回密码
 立即注册
查看: 181|回复: 1
收起左侧

[客户分享] STM32F407/STM32H743二维码识别(附源码)

[复制链接]

10

主题

34

回帖

64

积分

初级会员

积分
64
发表于 2025-5-27 16:21:19 | 显示全部楼层 |阅读模式
分享一个识别二维码可在单片机上运行的库---zbar
内存消耗比较多,建议外扩ram使用
大致步骤:
1.使用摄像头获取一帧RGB图像,不是拍照,就是RGB数据流
2.将RGB图像转为8位灰度图像
3.调用zbar库,直接拿结果
我在H7上实测,zbar解码240x240的二维码,需要约80KB的内存,加上RGB图像240x240x2=112.5KB,大致需要接近200KB了
-------------------------------------------------------------------------------------
下图是在STM32H743@480MHz - 240x240下得到的时间消耗
从RGB图像转灰度图像,约4ms
zbar库解析不到二维码时,约32ms
zbar库解析出二维码时,约44ms

IMG_6408 00_00_00-00_00_30.gif
-------------------------------------------------------------------------------------
下图是在STM32F407@168MHz - 240x240下得到的时间消耗
从RGB图像转灰度图像,约13ms
zbar库解析不到二维码时,约260ms
zbar库解析出二维码时,约370ms
(无法上传图片了.....)
-------------------------------------------------------------------------------------
zbar源码
qrcode-源码.zip (279.7 KB, 下载次数: 2)
-------------------------------------------------------------------------------------
灰度转换
[C] 纯文本查看 复制代码
/*
************************************************************
*        函数名称:        IA_Image_Gray_Light
*
*        函数功能:        灰度处理
*
*        入口参数:        rgb565:源数据
*                                size:源数据项数
*                                gray:灰度缓存
*
*        返回参数:        0-成功                1-失败
*
*        说明:                亮度法
*                                公式:Gray = 0.299*R + 0.587*G + 0.116*B
*                                使用整数运算代替浮点:系数放大256倍(0.299 → 77)
************************************************************
*/
uint8_t IA_Image_Gray_Light(uint16_t *rgb565, uint32_t size, uint8_t *gray)
{

        if((rgb565 == (void *)0) || (size == 0) || (gray == (void *)0))                                        return 1;

        for(uint8_t r = 0, g = 0, b = 0; size--; rgb565++, gray++)
        {
                r = (*rgb565 >> 11) & 0x1F;
                g = (*rgb565 >> 5)  & 0x3F;
                b = *rgb565 & 0x1F;

                *gray = (r * 77 + g * 150 + b * 29) >> 8;
        }

        return 0;

}

/*
************************************************************
*        函数名称:        IA_Image_Gray_Light_Table
*
*        函数功能:        灰度处理
*
*        入口参数:        rgb565:源数据
*                                size:源数据项数
*                                gray:灰度缓存
*
*        返回参数:        0-成功                1-失败
*
*        说明:                亮度法
*                                公式:Gray = 0.299*R + 0.587*G + 0.116*B
*                                使用整数运算代替浮点:系数放大256倍(0.299 → 77)
************************************************************
*/
uint8_t IA_Image_Gray_Light_Table(uint16_t *rgb565, uint32_t size, uint8_t *gray)
{

#if(IA_RGB_2_GRAY_TABLE == 1)
        if((rgb565 == (void *)0) || (size == 0) || (gray == (void *)0))                                        return 1;

        if(rgb_2_gray_table == (void *)0)
        {
                rgb_2_gray_table = HM_Malloc(HM_TYPE_EXTRAM_1, 65536);
                if(rgb_2_gray_table == (void *)0)                                                                                        return 1;

                for(uint32_t i = 0; i < 65536; i++)
                {
                        uint8_t r = (i >> 11) & 0x1F;
                        uint8_t g = (i >> 5)  & 0x3F;
                        uint8_t b = i & 0x1F;

                        rgb_2_gray_table[i] = (r * 77 + g * 150 + b * 29) >> 8;
                }
        }

        for(; size--;)
        {
                *gray++ = rgb_2_gray_table[*rgb565++];
        }

        return 0;
#else
        return 1;
#endif

}

-------------------------------------------------------------------------------------
修改zbar_config.c里边的函数即可,就是动态内存,内存操作之类的,然后解码流程我也封装好放在zbar_config.c里边了,网上下载的移植好的源码没有zbar_decode函数
解码流程
[C] 纯文本查看 复制代码
unsigned char zbar_decode(unsigned short width, unsigned short heigh, unsigned char *gray, unsigned short *type, char *result)
{

        unsigned char ret = 1;

        zbar_image_scanner_t *scanner = NULL;
        scanner = zbar_image_scanner_create();
        zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1);

        zbar_image_t *image = zbar_image_create();
        zbar_image_set_format(image, *(int*)"Y800");
        zbar_image_set_size(image, width, heigh);
        zbar_image_set_data(image, gray, width * heigh, zbar_image_free_data);

        if(zbar_scan_image(scanner, image) != 0)
        {
                const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
                for(; symbol; symbol = zbar_symbol_next(symbol))
                {
                        zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);

                        const char *data = zbar_symbol_get_data(symbol);

                        if(type != NULL)                *type = typ;
                        if(result != NULL)
                        {
                                unsigned short len = strlen(data);

                                memcpy(result, data, len);

                                result[len] = 0;
                        }

                        ret = 0;
                }
        }

        zbar_image_destroy(image);
        zbar_image_scanner_destroy(scanner);

        return ret;

}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 2025-5-28 11:00:56 | 显示全部楼层
谢谢分享
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-10 04:49 , Processed in 0.338688 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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