#1024 程序员节 大图像中的小目标检测——基于YOLOV8+OnnxRuntime部署+滑动窗口+Zbar的条码检测研究

本文主要是介绍#1024 程序员节 大图像中的小目标检测——基于YOLOV8+OnnxRuntime部署+滑动窗口+Zbar的条码检测研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 1 训练一个YOLOV8的一维码检测模型
  • 2 创建滑动窗口
    • 2.1 模块导入与测试图片展示
    • 2.2 创建滑动窗口检测,窗口大小为(640,640),滑动距离为640。对不足(640,640)的窗口进行填充
  • 3 创建onnxruntime推理引擎
    • 3.1推理测试
    • 3.2获得ONNX模型输入层(输出层)和数据维度
    • 3.3 预处理-构造输入张量 torch_list
  • 4 执行推理预测
  • 5 后处理-置信度过滤、NMS过滤
    • 5.1解析目标检测预测结果
  • 6 opencv 可视化
  • 7 检测完的切片重新放回原图
  • 8 用Zbar识别二维码
    • 8.1条码剪切
    • 8.1 筛选出选合格的条码
  • 总结
  • 相关文章

原创声明:如有转载请注明文章来源。码字不易,如对卿有所帮助,欢迎评论、点赞、收藏。
本文为深度学习的条码检测方案,如需传统算法的条码检测方案请阅读(基于Opencv+Kmeans+Zbar的条码检测与基于锐化+双边高斯滤波+Zbar的条码检测在工业光伏产线上的检测效果研究)

前言

最近项目中用到了条码检测,查阅很多资料,说用Zbar等工具检测的比较多。但是我们会发现,检测是不稳定的,Zbar是解析条码的工具包,运用好它的前提是:能够准确将条码区域提取出来,以及图像质量(分辨率、打光效果等)要把握很好。本文基于YOLOV8+OnnxRuntime部署+滑动窗口+Zbar对于条码检测进行升级,可以有效解决条码检测问题,并且速度也很高。

1 训练一个YOLOV8的一维码检测模型

  • 关于如何训练模型不是本文的重点,可以根据这篇文章简单训练一个模型(YOLOV8目标检测——模型训练)

  • 如果需要本人训练好的模型可以在点击这里下载( 文章顶部文件包:best.pt、best.onnx、 数据集、实验图片)

  • 当然若有训练和环境的相关问题,可以在评论里写明。看到一定回复。

2 创建滑动窗口

2.1 模块导入与测试图片展示

import cv2
import numpy as np
from PIL import Imageimport onnxruntimeimport torch
# 有 GPU 就用 GPU,没有就用 CPU
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')import matplotlib.pyplot as plt
%matplotlib inline
```在这里插入图片描述```python
# 显示图片
image = cv2.imread("D:/yolov8/data/images/Pic_2023_04_18_104022_3.bmp")
plt.imshow(image[:,:,::-1])
image_1 = image.copy()

在这里插入图片描述

2.2 创建滑动窗口检测,窗口大小为(640,640),滑动距离为640。对不足(640,640)的窗口进行填充

win = 0 
image_list = [] # 用来存储滑动窗口
while(win<4000):img_test = image[340:980,win:win+640]if img_test.shape[1]<640:top = 0bottom = 0left = 0right = 640-img_test.shape[1]img_test = cv2.copyMakeBorder(img_test,top,bottom,left,right,cv2.BORDER_CONSTANT,value=[255,255,255])  image_list.append(img_test)win = win + 640

展示窗口切片

for i in range(len(image_list)):plt.subplot(2,4,i+1)plt.imshow(image_list[i][:,:,::-1])
plt.show()

在这里插入图片描述

3 创建onnxruntime推理引擎

ort_session = onnxruntime.InferenceSession('E:/ultralytics/runs/detect/train4/weights/best.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])

3.1推理测试

x = torch.randn(1, 3, 640, 640).numpy()
ort_inputs = {'images': x}
ort_output = ort_session.run(['output0'], ort_inputs)[0]
ort_output

输出了结果,说明onnxruntime引擎没有问题。
在这里插入图片描述

3.2获得ONNX模型输入层(输出层)和数据维度

在这里插入图片描述
在这里插入图片描述

3.3 预处理-构造输入张量 torch_list

这里是标准的yolov8输入图像的预处理模式

# 有 GPU 就用 GPU,没有就用 CPU
torch_list = []
for i in range(len(image_list)):
# 预处理-归一化image = image_list[i][:,:,::-1]image = image / 255# 预处理-构造输入 Tensorimage = np.expand_dims(image, axis=0) # 加 batch 维度image = image.transpose((0, 3, 1, 2)) # N, C, H, Wimage = np.ascontiguousarray(image)   # 将内存不连续存储的数组,转换为内存连续存储的数组,使得内存访问速度更快image = torch.from_numpy(image).to(device).float() # 转 Pytorch Tensor# input_tensor = input_tensor.half() # 是否开启半精度,即 uint8 转 fp16,默认转 fp32 torch_list.append(image)

可以查看一下相关数据
在这里插入图片描述

4 执行推理预测

当你在对切片处理的时候,还需要用字典去标记切片的,即:{切片:目标检测结果}。这个字典是贯穿始终的,能够保证最后把检测之后的切片,贴到原图的时候,知道那个预测结果是哪个窗口预测得来的。

preds_dict = {}for i in range(len(torch_list)):# ONNX Runtime 推理预测ort_output = ort_session.run(output_name, {input_name[0]: torch_list[i].cpu().numpy()})[0]# 转 Tensorpreds = torch.Tensor(ort_output)preds_dict[str(i)] = preds

在这里插入图片描述

5 后处理-置信度过滤、NMS过滤

from ultralytics.utils import ops
for i in range(len(preds_dict)):pred = ops.non_max_suppression(preds_dict[str(i)], conf_thres=0.7, iou_thres=0.7, nc=1)preds_dict[str(i)] = pred[0]

经过非极大值抑制,条码基本都被标记出来了。
在这里插入图片描述

5.1解析目标检测预测结果

pred_det = []
num_bboxs = {} # 画框框的记录,需要标记好每个切片的目标检测数量
for i in range(len(preds_dict)):det = preds_dict[str(i)][:,0:6].cpu().numpy()preds_dict[str(i)] = detnum_bboxs[str(i)] = len(det)

这里的类别会变成0,本文中0代表条码
在这里插入图片描述

6 opencv 可视化

# 框(rectangle)可视化配置
bbox_color = (150, 0, 0)             # 框的 BGR 颜色
bbox_thickness = 6                   # 框的线宽# 框类别文字
bbox_labelstr = {'font_size':2,         # 字体大小'font_thickness':3,   # 字体粗细'offset_x':0,          # X 方向,文字偏移距离,向右为正'offset_y':-10,        # Y 方向,文字偏移距离,向下为正
}
for i in range(len(preds_dict)):# 遍历每个框for j in range(len(preds_dict[str(i)])):# 获取该框坐标bboxes_xyxy = preds_dict[str(i)][:, :4].astype('uint32')bbox_xyxy = bboxes_xyxy[j] # 获取框的预测类别(对于关键点检测,只有一个类别)bbox_label = 'code'# 画框image_list[i] = cv2.rectangle(image_list[i], (bbox_xyxy[0], bbox_xyxy[1]), (bbox_xyxy[2], bbox_xyxy[3]), bbox_color, bbox_thickness)# 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细image_list[i] = cv2.putText(image_list[i], bbox_label, (bbox_xyxy[0]+bbox_labelstr['offset_x'], bbox_xyxy[1]+bbox_labelstr['offset_y']), cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], bbox_color, bbox_labelstr['font_thickness'])
for i in range(len(image_list)):plt.subplot(2,4,i+1)plt.imshow(image_list[i][:,:,::-1])
plt.show()

运行结果如下:
在这里插入图片描述

7 检测完的切片重新放回原图

wide = 0for i in range(len(image_list)):  wide += 640if wide < 4000:image_1[340:980,i*640:640*(i+1)] = image_list[i]else:image_1[340:980,3840:4000] = image_list[i][:,0:160]
plt.imshow(image_1[:,:,::-1])

在这里插入图片描述

8 用Zbar识别二维码

8.1条码剪切

codes = []
for i in range(len(preds_dict)): # 遍历每个框for j in range(len(preds_dict[str(i)])):# 获取该框坐标bboxes_xyxy = preds_dict[str(i)][:, :4].astype('uint32') # 目标检测预测结果:左上角X、左上角Y、右下角X、右下角Y、置信度、类别IDbbox_xyxy = bboxes_xyxy[j] code = image_list[i][bbox_xyxy[1]:bbox_xyxy[3],bbox_xyxy[0]:bbox_xyxy[2]]codes.append(code)
# 展示一下提取到的条码图片
for i in range(len(codes)):plt.subplot(4,5,i+1)plt.imshow(codes[i],cmap="gray")
plt.show()

此时我们会发现条码中是有一个条码被标注上两个框的。15个目标,但涵盖了16个检测框。
在这里插入图片描述

8.1 筛选出选合格的条码

条码的宽度如果小于条码的一半,则剔除该条码

for code in codes:if code.shape[1]<20:  # 去除宽度小于20的条码codes.remove(code)
```python
# 展示一下提取到的条码图片
for i in range(len(codes)):plt.subplot(4,5,i+1)plt.imshow(codes[i],cmap="gray")
plt.show()

在这里插入图片描述

from pyzbar import pyzbar
res_1=[]
for i in range(len(codes)):res = pyzbar.decode(codes[i])res_1.append(res)
res_1

在这里插入图片描述
但是我们会发现,最后检测出的15个目标,只有14个条码。那是因为在滑动窗口中是需要去调节滑动窗口的大小以及滑动的距离。总得来说,将滑动距离从640变为320会是比较好的选择,最后对于检测出的条码再做一下处理即可。

总结

市面上有很多条码、二维码检测的算法,最让人印象深刻的就是腾讯微信扫码——基于SSD和超分算法的二维码检测方式。本文深受启发,将SSD的提取网络换成YOLOV8,将二维码的提取换成一维码。总的来说,试一次不错的体验。
本人是一名计算机视觉应用工程师,喜欢将算法应用于实际当中,这是自己的乐趣,如有什么需要讨论,欢迎评论区留言。
如您百忙之中还看到了这里,那是缘分。想来您和我一样对深度学习的应用深有兴趣,还请您帮忙点个赞,以便于更多的你我这样的人发现本文章,谢谢。

相关文章

基于Opencv+Kmeans+Zbar的条码检测与基于锐化+双边高斯滤波+Zbar的条码检测在工业光伏产线上的检测效果研究

这篇关于#1024 程序员节 大图像中的小目标检测——基于YOLOV8+OnnxRuntime部署+滑动窗口+Zbar的条码检测研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/263185

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

Solr部署如何启动

Solr部署如何启动 Posted on 一月 10, 2013 in:  Solr入门 | 评论关闭 我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 1、准备环境 建立一个solr目录,把solr压缩包example目录下的内容复制