用深度学习模型进行条码定位实践【c++和paddle】
利用AI模型进行条码的定位可以解决传统方法在复杂环境下无法定位的问题,大大提高定位的准确性和速度。本文介绍了利用paddle框架进行定位的相关方法,并给出了测试结果。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
条码已渗透到我们生活的各个方面,如支付、物流仓储、零售和工业生产流水线等。扫码读码看似简单“一扫即得”,但在实际场景中却因环境、载体、条码状态等因素的影响而造成困难。如条码布局无序,且摆放角度随机,传统扫码设备难以快速锁定目标;受环境光照影响出现反光、高亮等情形;要定位的条码尺寸小,与周围背景对比度低,很难分辨等。传统条码定位依赖条码的边缘、明暗对比等几何特征,对模糊、遮挡、扭曲的条码适应性差。AI模型凭借对复杂特征的提取与适配能力,即使在强光、阴影等场景下,也能精准捕捉条码区域。例如,针对倾斜、旋转的条码,可通过数据增强训练,实现对任意角度条码的定位。
目前调用AI模型进行实际操作,使用语言比较多的有python和c++。本文将介绍如何在c++项目中paddle框架进行条码的快速定位,并给出相应的示例。
一、paddle是什么?
paddle是由百度开发并开源的深度学习框架,提供了丰富的工具组件和服务平台,适用于图像识别、自然语言处理、语音识别等多个领域;并且提供了预训练模型,可以快速完成模型微调并应用于实际业务场景。
二、使用步骤
1.安装paddle库
在c++项目中利用paddle框架进行推理需要安装paddle Inference推理库。相应的库可以自己从源代码进行编译,也可以下载编译好的release版本。paddle Inference推理库包含了头文件、dll动态库和lib动态库,如下图所示。

2.图像预处理
在代码中需要包含头文件"paddle_inference_api.h"
为了适应模型,需要对图像数据进行预处理和标准化,并转化为NCHW格式,代码如下:
void preprocess(const cv::Mat& img, const int height, const int width, std::vector<float> &input_data)
{
if (img.empty()) {
std::cerr << "图像为空!" << std::endl;
}
// BGR 转 RGB
cv::Mat rgb_img;
cv::cvtColor(img, rgb_img, cv::COLOR_BGR2RGB);
// 归一化
std::vector<float> mean = { 0.485f, 0.456f, 0.406f };
std::vector<float> std = { 0.229f, 0.224f, 0.225f };
cv::Mat normalized_img = normalize(rgb_img, mean, std);
// resize + =>NCHW
cv::Mat preprocess_img = cv::dnn::blobFromImage(
normalized_img, // 原始BGR图像
1.0, // 像素值归一化到0-1
cv::Size(height, width), // 目标尺寸224×224
cv::Scalar(0), // 减去ImageNet均值(RGB顺序,swapRB=true时匹配)
true, // BGR→RGB
false, // 不裁剪
CV_32F // 输出float32类型(适配模型输入)
);
memcpy(input_data.data(), preprocess_img.data, input_data.size() * sizeof(float));
}
其中,归一化的标准和均值需要根据模型具体值修改。这里结合opencv中的cv::Mat作为图像数据的载体,也可以采用其他库。
3.运行推理
推理过程就是将预处理后的图像利用推理器进行推理,并得到推理结果。推理过程可以在GPU上,也可以在CPU上运行。推理过程相关代码如下:
void run(Predictor* predictor,
const std::vector<float>& input,const std::vector<int>& input_shape,
const std::vector<float>& scale_factor,const std::vector<int>& scale_factor_shape,
std::vector<float>* out_data)
{
auto input_names = predictor->GetInputNames();
auto image_handle = predictor->GetInputHandle(input_names[0]);
image_handle->Reshape(input_shape);
image_handle->CopyFromCpu(input.data());
auto scale_factor_handle = predictor->GetInputHandle(input_names[1]);
scale_factor_handle->Reshape(scale_factor_shape);
scale_factor_handle->CopyFromCpu(scale_factor.data());
predictor->Run();
auto output_names = predictor->GetOutputNames();
auto output_t = predictor->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_t->shape();
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
std::multiplies<int>());
out_data->resize(out_num);
output_t->CopyToCpu(out_data->data());
}
三、测试结果
通过对不同环境下的一维码和二维码(包括QR码、DM码)进行测试,无论是低比度还是高反光都可以快速进行定位,如下图所示的各种复杂环境。

总结
本文介绍了利用c++加上paddle深度学习框架进行条码定位的过程,给出了图像预处理和推理的相关代码,并演示了复杂环境下的定位结果。实践表明,利用AI模型进行条码定位进行很高的可靠性,可以解决传统方法对于复杂环境无法定位的结果,大大提高定位的准确性和速度。
有需要完整代码的可以联系以下链接获取。

更多推荐



所有评论(0)