×

开源硬件自动售货机

消耗积分:3 | 格式:zip | 大小:0.06 MB | 2022-11-02

KANA

分享资料个

描述

为什么选择自动售货机?

自动售货机为用户提供各种产品,如零食、饮料、比萨饼、纸杯蛋糕、苏打水等。机器的界面包括一个数字键盘,用户可以在其中选择所需的产品、输入产品 ID 并进行购买。在covid-19爆发期间,最常被触摸的按钮板或控制台被污染,因此我们无法为自动售货机使用数字键盘界面。这就是为什么最好选择可以取代我们常规数字键盘控制台的手势控制系统。

这个怎么运作?

深度学习模型是使用一些非常常见的手势数据集构建的,例如 Palm、Okay、Peace、Fist 和 L。富含这些手势的 Kaggle 数据集可用于训练和测试模型 | 资源

pYYBAGNh68mAG4caAABM4r2FeYA054.png
5 个手势的日期集
 

与其从头开始构建顺序模型,不如使用预训练模型,这就是我使用 VGG-16 神经网络的原因。除了能够对照片中的物体进行分类之外,模型权重是免费提供的,可以在我们自己的模型和应用程序中加载和使用。这是一个沉重的模型,但预测准确性非常令人满意。我的训练模型可以在这里找到它是使用带有TensorFlow后端的Keras API生成的。

里面发生了什么

我们在基本模型布局中看到的,它有大约 4 层 -> 输入层、输出层,在两个隐藏层之间。

  • 信息被输入输入层,输入层将其传输到隐藏层
  • 两层之间的互连为每个输入随机分配权重(权重是与输入相乘的数值参数,主要将输入转换为输出
  • 在将权重与它们单独相乘后添加到每个输入的偏差(偏差只是为调整输出而添加的数字参数)
  • 加权和被转移到激活函数
  • 激活函数确定应该触发哪些节点进行特征提取
  • 该模型将应用程序功能应用于输出层以传递输出
  • 调整权重,并反向传播输出以最小化错误

对于 VGG16 ,它不过是 16 层的堆栈。在这些层上,完成了不同的操作,例如:卷积、relu、最大池化等。来源可找到有关 VGG-16 架构及其实现方式的更多信息。

poYBAGNh69CAcVU6AACM2ZYYMkQ218.png
VGG-16 架构
 

在继续前进之前

由于我们将使用 Raspberry-pi Zero W,我们需要拥有精简版的 Tensor Flow 才能将TinyML集成到我们的项目中。这样,后端处理将尽可能顺利地运行。这就是为什么需要TF_lite 模型的原因我的 TensorFlow lite 模型可以在这里找到。要了解更多关于 TensorFlow lite 模型从 TensorFlow 模型的转换,我们可以去这里

我使用Jupyter Notebook来构建代码并生成模型。因此,数据集必须存储在本地。我如何构建、训练、调整和测试我的模型,我使用的数据集也可以在这里找到。试图使笔记本尽可能简单,用有用的注释表示代码:)。

图像处理任务的四个阶段概述

首先,相机开始捕捉被分解成帧的视频。OpenCv 有助于每次迭代获取一帧并执行以下操作:

  • 获取帧时,应用使用 OpenCv 双边滤波器功能的平滑滤波器。应用平滑滤波器去除帧中的高空间频率噪声。
将前景与背景分开以仅获取手势
  • 使用 OpenCv background_model_mog2 函数从静态背景中提取移动对象(手势)以单独获取前景对象。
  • 创建 background_model 后,通过一次迭代应用 [3*3] 内核来使用像 erode 这样的形态学操作。在输出中,小对象被移除,因此只剩下实质性对象。然后进行按位“与”操作,只保持输出的相关部分,其他像素变暗。
获取提取手势的二值图像
  • 首先,从背景模型中提取的图像被转换为​​灰色。
  • 然后应用高斯模糊滤波器来降低噪声。选择尺寸通常为标准偏差三倍的掩模。
  • 通过应用一定的阈值将灰度图像转换为二值图像。颜色空间的灰度或子空间在分类中产生了复杂性。这就是为什么最好使用二进制图像。
设置目标图像进行预测
  • 这里堆栈操作执行沿新轴连接图像数组的序列。
  • 目标图像需要调整大小,这样训练后的模型可以预测图像并且不会与图像大小冲突。
  • 进行预测之前的下一步也是最后一步是,目标图像需要重新整形为 224*224*3 (width*height*color_channel_number)。
然后将目标图像输入 predict_rgb_image 函数,该函数返回图像的预测分数和预测类别。
poYBAGNh69SAJ-ROAACgkyLxEf8655.png
经过一系列图像处理操作后从输入到输出的转换。
 

系统工作流程

pYYBAGNh69iAUo_XAACY5TFjZPQ628.png
系统流程
 

硬件

硬件部分分为两个部分:

  • 捕获流,检测手势,通过蓝牙将产品 ID 发送到 Arduino 无触摸控制台:由 Raspberry Pi Zero W 完成。
  • 从 Pi 接收产品 id,发送要购买的物品:由 Arduino 控制台完成。

在硬件部分,我们将尝试仅模拟 AutoVend 的手势检测、显示控制台和功能。我们不会关注它的机械部分。因为,机械部件的功能与任何自动售货机相同。

为了从摄像头流中获取图像帧并检测手势,我们需要给 Raspberry Pi 零 W 上电。为此,我们可以使用 1100mAh 11.1 伏的锂聚合物电池,并通过降压转换器将 11.1 伏转换为 5 伏。

带摄像头设置的 Raspberry-pi 零 W

pYYBAGNh6-KAcmZ2AAQGwV3etyE243.png
带有 Pi 摄像头的树莓派
 

现场直播

poYBAGNh6-iAQ1svAAHFJujWJAk667.png
使用 VNC 查看器从 Raspberry-pi 直播
 

沟通

我们有一个集成的蓝牙模块与我们的 Raspberry-pi 零 W,此外,我们可以使用外部蓝牙模块并通过串口连接它。我们将使用它与 Arduino 进行通信。在 Arduino 部分,我们有 HC-05 蓝牙模块。为了在它们之间建立通信,我们将使用 COM/Serial 端口,它侦听任何尝试连接的外部设备的操作 -like: here on COM8, the Bluetooth module integrated with Arduino is trying to connect with Raspberry-pi.

# Sample Code Snippet

serialPort = serial.Serial(port = "COM8", baudrate=9600,
bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE)

我们需要保持特定的波特率,否则集成 Arduino 的蓝牙模块无法同步。我们需要以下库来完成这项工作。

import serial

展示

模拟购买、订购和向用户显示不同提示的工作;一个 16*2 液晶面板将与 Arduino 集成。

拨动开关

拨动开关将用于唤醒机器。这将使整个相机过程从头开始工作。

力量

一个 9v 电池将为威廉希尔官方网站 供电,使用线性转换器 7805 将其转换为 5v。然后将其馈入模拟自动售货机的面包板。

免触摸控制台

poYBAGNh6_CAGGs1AAG4WnM8I34442.png
威廉希尔官方网站 原理图
 

Arduino 控制台的最终外观

pYYBAGNh6_qAZyqaAAG2IOjm8sk176.png
最终威廉希尔官方网站 组装
 
pYYBAGNh7BaALOsxAArnHvAwvjs280.png
最终威廉希尔官方网站 组装
 

 

我们将如何购买

假设这是 AutoVend 的产品映射,其中 11、12、13 ... ... 64、65、66 代表产品 ID。

poYBAGNh7C-ADa7fAACDX9YYzXk956.png
AutoVend 产品映射
 

现在,我们有这两个手势图可供选择

pYYBAGNh7DKAR8OyAACiOMzgHoM460.png
手势图-1
 

Other Digits(Except from 1 to 3):当我们想选择其他数字,这里没有,我们需要去另一个手势图。最后一个手势模式有助于打破这张地图。

poYBAGNh7DWADX9oAACaLzQ00Sk860.png
手势地图-2
 

其他数字(4 到 6 除外):与前面描述的相同。目的是打破这张地图。

技巧:正如我们所见,所有数字都是使用由三个符号组成的特定模式构建的。如果我们需要选择一个数字(如:4),那么我们必须对所有三个标志进行手势。但是,如果我们要手势多位数字(如:45),那么我们不必两次都手势只需要打手势一次,就可以打手势了。

L + 好的 + 拳头 + 好的 = 数字 (45)

我们想购买 ID-15 的产品

poYBAGNh7DeANdfpAACP9UB32Go459.png
自动售货功能
 

使用这两个地图,我们需要在相机之前顺序显示以下手势

poYBAGNh7DqAYB6lAACr7CPgW50228.png
顺序手势的步骤
 

最后,我们需要显示手势“L”

pYYBAGNh7D2ABGAtAAAj-aQTEdY559.png
恭喜购买
 

所以整个打手势的过程:

Peace + L + Okay + Peace + Okay + Palm + Fist + Okay + Palm + Okay + L = Digit(15)

让我们使用 ID-15 购买产品:

我们将模拟Raspberry Pi 的手势步骤,并了解无触摸Arduino控制台的功能。

 

结论:

我使用本地机器(例如笔记本电脑)和Jupyter Notebook来训练、测试和评估模型。最后,我生成了 TensorFlow lite 模型。在 raspberry pi 零上执行实时手势识别,并在带有VNC 查看器应用程序的笔记本电脑上看到提要。无触摸控制台是用 Arduino Nano 构建的。

使用AutoVend ,不仅可以自动化购买杂货的整个过程,而且还可以成为我们的常规小工具如何智能到足以为我们提供抵御 Covid-19 大流行的安全性的一个很好的例子 :)


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//m.obk20.com/www/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'开源硬件自动售货机',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"https://www.elecfans.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);