零根底体验AI模子操练-用SenseCAP视觉传感器无代码体验机器进修过程
AI与机器进修的连系给机器视觉行业带来了新的开展,在机器进修模子、算法加持之下,使得处理更具挑战性的问题成为可能。那你有想过利用视觉AI传感器自行构建机器进修模子吗?
今天的分享来自 柴火认证会员 温燕铭,手把手带你用工业级SenseCAP A1101 视觉AI传感器体验机器进修。
做者介绍
温燕铭
会员编号:CHSZ2020001034
90后,女,香港中文大学法学硕士,硬件产物司理,创造喜好者,创业者,十多年科技理论和创客体味。曾就职于迪拜的科技立异加速器、深圳创客教导机构、开源硬件企业,在深圳兴办了公司专门处置专利和产物研发,拥有二十余项国度专利受权,国度法令职业资格证,教师资格证,多旋翼无人航空系统机长证。曾获深圳市无人机组拆大赛冠军,深圳逐梦杯大学生立异创业大赛二等奖。
本案例将通过一个目标分类的模子操练过程,让任何对机器进修没有概念的用户都能够随便体验机器进修模子操练中数据摘集、数据标识表记标帜、模子操练、设备摆设的完全模子操练流程。
展开全文
机器进修属于人工智能的子集,人工智能是基于数据处置来做出决策和揣测。在机器进修中,通过给计算机输进颠末报酬标识表记标帜过的数据集,算法会不竭停止操练,从数据集中发现形式和相关性,然后根据数据阐发成果做出更佳决策和揣测。操练模子是机器进修中重要的一环,一个根本的模子操练和摆设流程包罗数据摘集、数据标识表记标帜、模子操练和设备摆设。
一、预备
1.1
硬件预备
SenseCAP A1101 视觉 AI 传感器
SenseCAP M2 Data Only LoRaWAN 网关
电脑
USB Type-C 线
1.2
硬件介绍
SenseCAP A1101
和SenseCAP系列出的所有的工业传感器节点一样,产物自带IP66品级防水外壳,适用于摆设到户外情况,19Ah大容量锂电池能够让设备长时间免庇护。
SenseCAP M2 LoRaWAN网关
LoRa是一种低功耗、长间隔的无线传输手艺,差别于高功耗、室内利用的WiFi,LoRa更适用于低带宽、数据量小、持久免庇护场景下的户外摆设,能够做到长达数公里的收集笼盖。
SenseCAP M2是一个高性能的可供给LoRa信号笼盖的LoRaWAN网关,撑持毗连到Helium LongFi收集,可以为长途LoRaWAN设备供给数公里的无线收集笼盖范畴和数据传输才能,并通过Helium获得此外用户操纵网关停止数据传输产生的数据收益。
SenseCAP M2目前有868mHz和915mHz两种频段版本可选,因为SenseCAP A1101撑持860-930mHz频段,所以能够抉择肆意一个版本停止测试。SenseCAP暂时还没推出国内470mHz频段版本的A1101。
1.3
软件预备
1.3.1 电脑情况安拆
图像摘集需要通过USB毗连设备到电脑,通过运行脚本法式来实现,在此之前,我们需要给电脑安拆好情况。Windows、Linux和 Intel Mac电脑系统的软件设置不异,而M1/M2 Mac则有所差别。
针对Windows、Linux、Mac:
确保计算机上已经安拆了Python。假设没有,请拜候Python官方页面(版本。
运行以下代码安拆libusb1依靠库。
pip3installlibusb1
针对M1/ M2芯片的Mac:
起首通过以下代码安拆Homebrew软件:
/bin/bash -c " $(curl -fsSL )"
通过以下代码安拆conda:
brewinstall conda
通过以下代码下载 libusb
wget
通过以下代码安拆 libusb
condainstalllibusb-1.0.26-h1c322ee_100.tar.bz2
1.3.2 下载SenseCAP Mate 利用法式
SenseCAP Mate是矽递推出的针对SenseCAP LoRa系列产物的设备添加、设置装备摆设、治理和数据展现的手机端App,在本案例顶用于毗连SenseCAP A1101,设置装备摆设设备,和停止数据展现。根据手机操做系统通过以下链接下载安拆。
安卓
Google Play
Google Play
APK 下载
APK 下载
iOS
1.3.3 下载SenseCAP A1101固件设备原始固件
A1101_default_firmware.uf2
图像摘集固件
capture_images_A1101_firmware.uf2
二、模子操练过程
2.1
第一步:图像摘集
2.1.1拷录图像摘集固件
通过USB Type-C毗连线将SenseCAP A1101毗连到PC,双击设备上的设置装备摆设按钮进进大容量存储形式,此时电脑会弹出一个定名为“VISIONAI”的驱动器。
将适才下载好的SenseCAP A1101图像摘集固件“capture_images_A1101_firmware.uf2”文件挈放到电脑弹出的“VISIONAI”驱动器,一旦uf2 完成复造到驱动器中,驱动器就会主动消逝阐明已经胜利上传到设备中。
2.1.2在电脑运行图像摘集脚本
图像摘集脚本代码请见文末附件,也可通过以下链接获得:
间接下载.py文件或将链接中的代码复造到一个新建记事本,定名为“ capture_images_.py”,保留到所在目次,通过以下号令行运行脚本。
python3capture_images_.py
该脚本默认每300ms摘集一张图片,假设需要修改摘集时间间隔,做为例子,改为1000ms摘集一次,能够参照利用以下代码:
python3capture_images_.py--interval1000
脚本运行后,就能够用SenseCAP A1101摄像头瞄准要摘集的目标停止图像摘集了。此时电脑会主动新建一个名为“save_img”的文件夹,摘集到的照片会实时存储在该文件夹内,同时也能够通过脚本运行获得实时摄像头数据。
2.1.3退出图像摘集
拍摄完足够的图像后,单击末端窗口并按下以下组合键能够停行拍摄:
Windows: Ctrl + Break
Linux: Ctrl + Shift + \
Mac: CMD + Shift + \
2.1.4从头拷录原始设备固件
因为图像摘集固件是零丁的固件,和SenseCAP A1101设备出厂固件纷歧致,在完成数据集的图像摘集后,需要将SenseCAP A1101内部的固件更改回原始形态,以便再次加载对象检测模子停止检测。
参照上文拷录图像摘集固件的步调,再次通过USB Type-C毗连SenseCAP A1101设备,双击设置装备摆设按钮进进引导形式将已经下载的名为“A1101_default_firmware.uf2”的设备原始固件从头拷录到SenseCAP A1101中 。
2.2
第二步:图像标识表记标帜
Roboflow(文件或代码,在利用前,我们需要注册一个账号并新建一个项目。
2.2.1创建项目
需要设置项目名称,开源答应体例,项目类型和项目介绍,项目类型我们那里抉择“Object Detection”目标检测。
2.2.2 上传图片
我们能够便利地在“Upload”栏目里将设备摘集到的图像数据用间接挈拽或文件夹拔取的体例上传到Roboflow。
上传完成后,能够根据需要,调整“Train”、“Valid”、“Test”数据的比例,别离用于操练、验证、和测试。
2.2.3 停止标识表记标帜
因为图片数量较多,标注起来需要点耐烦,越多的数据输进能包管更高的准确度,我那里为了简单演示,只摘集和标注了300张摆布,关于模子操练来说,那算是一个十分十分小的数据集。
在Preprocessing一栏,定见将图像大小更改为192x192像素,因为我们将利用那个大小停止操练,而且操练会更快。不然,在操练过程中必需将所有图像转换为192x192,那会消耗更多的CPU资本,使操练过程变慢。
2.2.4 模子导出
完成数据集设置后,就能够在“Generate”栏目停止数据集生成了,能够根据差别的图片和设置生成差别的数据集版本,生成后能够导出为代码,也能够间接导出为.zip文件。在那里,我们需要导出为代码,抉择“YOLO v5 Pytorch”格局,“show download code”,最初点击“Continue”。
在导出代码的页面,我们需要将整段代码复造下来,鄙人一步操练模子的时候将会用到。你会得到一个被粉饰的“api_key”,请不要和他人分享。
2.3
第三步:模子操练
操练能够在当地计算机停止,也能够在云长进行,供给模子操练的云办事平台有良多,我们那里抉择Google Colab和矽递官方供给的操练代码,不需要本身编写代码,导进数据集后,跟着代码运行就能够完成一站式整个操练流程。
Google Colab项目链接:
在那个链接的代码里,Google Colab次要完成以下几步:
•成立培训情况
•导进数据集
•摘用YOLOv5算法停止模子操练
•下载操练好的模子
点击每一段的代码,我们会间接看到运行的过程和成果。
在Step4的代码框里,我们将适才在Roboflow导出的模子代码全数复造进往替代掉原有内容,然后点击左侧运行按钮。
在最初,我们将能够得到一个名为“model-1.uf2”的模子文件,那时,我们就能够将操练好的模子摆设到SenseCAP A1101设备中了。
2.4
第四步:设备摆设
设备摆设包罗两个步调,将模子摆设到设备上,再将设备摆设在现实利用场景里,那里我们欠缺现实可摆设的场景,只是做为模子验证利用的话,我们就简单介绍若何将模子摆设到设备。
拷录模子的过程和拷录固件流程是一样的,通过USB Type-C将SenseCAP A1101毗连到电脑,通过USB Type-C毗连线将SenseCAP A1101毗连到PC,双击设备上的设置装备摆设按钮进进大容量存储形式,将模子文件间接挈到弹出的“VISIONAI”的驱动器,驱动器闪退就代表模子拷录胜利了。
SenseCAP A1101一共撑持添加4个模子,假设用户有多个模子需要拷录,只需要反复上述步调即可。
三、验证模子
一切预备停当,我们能够通过电脑和手机App来测试我们的测试我们的模子输出的成果了!
3.1
App设备毗连
3.2
设备设置装备摆设
毗连设备后,在Settings设置页面起头停止以下设置装备摆设:
“Platform”:指的是数据传输到哪个云平台,SenseCAP M2是供给Helium LoRa收集的网关,同时也能够毗连到SenseCAP Cloud云平台停止数据展现,在那里我们抉择“SenseCAP for Helium”;
“Algorithm”:抉择算法类型“Object Detection”目标检测;
“AI Model”:抉择“user defined”用户自定义的model;
“Credibility”,指的是抉择的置信度,抉择范畴从1-100%,意思是模子揣度为一个目标的可信度到达几的时候,设备才会认为特定目标被检测到,我们能够自行抉择,那里设置50%。
“Frequency Plan”,频段方案,因为SenseCAP M2网关目前只要US915和EU868两种国外频段做为抉择,我们那里肆意抉择一个,频段和网关利用的频段对应即可。
“Uplink Interval”,设置每隔多久上传一次数据到云平台,根据LoRa的低功耗特征,一般设置5分钟以上。
“Packet Policy”,抉择默认“2C+1N”形式即可。
点击“Send”发送完成设置装备摆设,然后回到“General”页,点击下方“Detect”按钮起头检测。
3.3
网页端展现
将SenseCAP A1101 通过USB Type-C 线毗连到电脑,此时电脑会弹出一个弹窗。点击弹窗,即可进进到实时检测的预览界面。假设有些电脑没有主动弹出,也能够拜候网址:
翻开网页后抉择毗连的设备“SenseCAP A1101” 并点击“Connect” 按钮,那时就能够在屏幕上看到实时检测的界面和目标检测成果了!
实时检测预览中不会对应展现我们数据集中定义的数据标签,只会展现数值做为区分,从成果看到,1 对应“石头”,2 对应“布”,3 对应“剪刀”。一些特殊的和“剪刀”和“布”有着配合特征的不在数据集内的手势,设备根据其特征,也做出了一个揣度并给出一个置信度,但比拟于实正的“布”置信度为91% ,给的置信度较低,只要77% 。
3.4
上传数据到云平台
除了能够在当地间接毗连电脑查看实时检测数据外,那些数据还能够以我们在App 设置装备摆设的时间间隔上传到SenseCAP 云平台( 用的是统一个账号系统。
因为本案例重点在于讲述模子操练过程,就此略往云平台数据展现的部门,有兴致的用户能够到SenseCAP 云平台测验考试添加设备和查看数据。
四、总结
数据集数量相对较小,总共才摘集和标识表记标帜 300 多张图片,不敷以让算法深进进修并给出可靠模子和高精度的成果;
数据摘集的情况不睬想,强光反射、纷杂布景等因素影响,对数据集的量量产生影响;
仅通过通用算法停止了一次简单的操练,未有通事后续的揣度成果陆续停止屡次操练优化模子以得到抱负效果
附录
图像摘集脚本代码:
1importos
2importusb1
3fromPIL importImage
4fromio importBytesIO
5importargparse
6importtime
7importcv2
8importnumpy asnp
9fromthreading importThread
10
11WEBUSB_JPEG_MAGIC = 0x2B2D2B2D
12WEBUSB_TEXT_MAGIC = 0x0F100E12
13
14VendorId = 0x2886# seeed studio
15ProductId = [ 0x8060, 0x8061]
16
17classReceive_Mess:
18def__init__(self, arg, device_id):
19self.showimg = notarg.unshow
20self.saveimg = notarg.unsave
21self.interval = arg.interval
22self.img_number = 0
23self.ProductId = []
24os.makedirs( "./save_img", exist_ok= True)
25self.expect_size = 0
26self.buff = bytearray
27self.device_id = device_id
28self.context = usb1.USBContext
29self.get_rlease_device(device_id, False)
30self.disconnect
31self.pre_time = time.time * 1000
32time.time_ns
33
34defstart(self):
35whileTrue:
36ifnotself.connect:
37continue
38self.read_data
39delself.handle
40self.disconnect
41
42defread_data(self):
43# Device not present, or user is not allowed to access device.
44withself.handle.claimInterface( 2):
45# Do stuff with endpoints on claimed interface.
46self.handle.setInterfaceAltSetting( 2, 0)
47self.handle.controlRead( 0x01 5, request= 0x22, value= 0x01, index= 2, length= 2048, timeout= 1000)
48# Build a list of transfer objects and submit them to prime the pump.
49transfer_list = []
50for_ inrange( 1):
51transfer = self.handle.getTransfer
52transfer.setBulk(usb1.ENDPOINT_IN | 2, 2048, callback=self.processReceivedData, timeout= 1000)
53transfer.submit
54transfer_list.append(transfer)
55# Loop as long as there is at least one submitted transfer.
56whileany(x.isSubmitted forx intransfer_list):
57# reading data
58self.context.handleEvents
59
60defpare_data(self, data: bytearray):
61iflen(data) == 8andint.from_bytes(bytes(data[: 4]), 'big') == WEBUSB_JPEG_MAGIC:
62self.expect_size = int.from_bytes(bytes(data[ 4:]), 'big')
63self.buff = bytearray
64eliflen(data) == 8andint.from_bytes(bytes(data[: 4]), 'big') == WEBUSB_TEXT_MAGIC:
65self.expect_size = int.from_bytes(bytes(data[ 4:]), 'big')
66self.buff = bytearray
67else:
68self.buff = self.buff + data
69
70ifself.expect_size == len(self.buff):
71try:
72Image.open(BytesIO(self.buff))
73except:
74self.buff = bytearray
75return
76ifself.saveimg and((time.time * 1000- self.pre_time) self.interval):
77withopen( f'./save_img/ {time.time}.jpg' , 'wb') asf:
78f.write(bytes(self.buff))
79self.img_number += 1
80print( f'\rNumber of saved pictures on device {self.device_id}: {self.img_number}' , end= '')
81self.pre_time = time.time * 1000
82
83ifself.showimg:
84self.show_byte
85self.buff = bytearray
86
87defshow_byte(self):
88try:
89img = Image.open(BytesIO(self.buff))
90img = np.array(img)
91cv2.imshow( 'img', cv2.cvtColor(img,cv2.COLOR_RGB2BGR))
92cv2.waitKey( 1)
93except:
94return
95
96defprocessReceivedData(self, transfer):
97iftransfer.getStatus != usb1.TRANSFER_COMPLETED:
98# transfer.close
99return
100
101data = transfer.getBuffer[:transfer.getActualLength]
102# Process data...
103self.pare_data(data)
104# Resubmit transfer once data is processed.
105transfer.submit
106
107defconnect(self):
108'''Get open devices'''
109self.handle = self.get_rlease_device(self.device_id, get= True)
110ifself.handle isNone:
111print( '\rPlease plug in the device!')
112returnFalse
113withself.handle.claimInterface( 2):
114self.handle.setInterfaceAltSetting( 2, 0)
115self.handle.controlRead( 0x01 5, request= 0x22, value= 0x01, index= 2, length= 2048, timeout= 1000)
116print( 'device is connected')
117returnTrue
118
119defdisconnect(self):
120try:
121print( 'Resetting device...')
122withusb1.USBContext ascontext:
123handle = context.getByVendorIDAndProductID(VendorId, self.ProductId[self.device_id],
124skip_on_error= False).open
125handle.controlRead( 0x01 5, request= 0x22, value= 0x00, index= 2, length= 2048, timeout= 1000)
126handle.close
127print( 'Device has been reset!')
128returnTrue
129except:
130returnFalse
131
132defget_rlease_device(self, did, get=True):
133'''Turn the device on or off'''
134tmp = 0
135print( '*'* 50)
136print( 'looking for device!')
137fordevice inself.context.getDeviceIterator(skip_on_error= True):
138product_id = device.getProductID
139vendor_id = device.getVendorID
140device_addr = device.getDeviceAddress
141bus = '-'.join(str(x) forx in[ 'Bus %03i'% (device.getBusNumber,)] + device.getPortNumberList)
142ifvendor_id == VendorId andproduct_id inProductId andtmp == did:
143self.ProductId.append(product_id)
144print( '\r'+ f'\033[4;31mID {vendor_id: 04x} : {product_id: 04x} {bus}Device {device_addr}\033[0m' ,
145end= '')
146ifget:
147returndevice.open
148else:
149device.close
150print(
151'\r'+ f'\033[4;31mID {vendor_id: 04x} : {product_id: 04x} {bus}Device {device_addr}CLOSED\033[0m' ,
152flush= True)
153elifvendor_id == VendorId andproduct_id inProductId:
154self.ProductId.append(product_id)
155print( f'\033[0;31mID {vendor_id: 04x} : {product_id: 04x} {bus}Device {device_addr}\033[0m' )
156tmp = tmp + 1
157else:
158print(
159f'ID {vendor_id: 04x} : {product_id: 04x} {bus}Device {device_addr}' )
160
161
162defimplement(arg, device):
163rr = Receive_Mess(arg, device)
164time.sleep( 1)
165rr.start
166
167
168if__name__ == '__main__':
169opt = argparse.ArgumentParser
170opt.add_argument( '--unsave', action= 'store_true', help= 'whether save pictures')
171opt.add_argument( '--unshow', action= 'store_true', help= 'whether show pictures')
172opt.add_argument( '--device-num', type=int, default= 1, help= 'Number of devices that need to be connected')
173opt.add_argument( '--interval', type=int, default= 300, help= 'ms,Minimum time interval for saving pictures')
174arg = opt.parse_args
175ifarg.device_num == 1:
176implement(arg, 0)
177elifarg.device_num = 0:
178raise'The number of devices must be at least one!'
179else:
180pro_ls = []
181fori inrange(arg.device_num):
182pro_ls.append(Thread(target=implement, args=(arg, i,)))
183fori inpro_ls:
184i.start
上下滑动查看更多
新一代信息手艺赋能|人才晋级|财产立异
驻场会员招募 炽热招募中
数字村落晋级,邀你同业
社区功效转化 | 与社区共创生长
----END----
Chaihuo x.factory|深圳,河北