唐旭 编译自Jacques Mattheij博客 量子位 出品 | 公众号 QbitAI 本文的作者Jacques Mattheij自小就是一名乐高粉。在接触乐高的过程中,他发现了这么一种现象:不同种类的乐高售价是不同的。比如精装乐高的售价大概是每公斤40欧元,散装的乐高只需要10欧元;而一些限量、稀有版本以及乐高机械组的售价能达到每公斤100欧元。 为此甚至有人专门去买那些散装和精装新品的乐高,然后把它们进行重新分类以获取更高的价值。 然而,手动给那些千奇百怪的乐高分类看上去并不是个好主意。于是Mattheij某日突发奇想,决定尝试用机器干这件事。他在各个拍卖网站上拍下了能装满一整车库的乐高(运回来途中还丢了辆卡车)来做这个实验。 这是Mattheij在个人网站上发布的第二篇帖子,讲的是他为给这堆乐高分类而在软件上尝试过的方法;在第一篇帖子里,他介绍了硬件方面的准备和面临的困难。 我们先跳过买几车乐高、安装摄像头、传送带等等过程,来看看他是怎么写这个分类程序的。如果你对硬件部分更有兴趣,请到这里围观:https://jacquesmattheij.com/sorting-two-metric-tons-of-lego 以下内容编译自Mattheij的第二篇帖子:
概述 全部的软件都是用Python写出来的。我本人并不是Python专家,不过好在我也不至于花一辈子才能把它弄会。Anaconda是一种非常好用的Python分发工具。原本,要解决各种关联性和版本问题,给Python设置一个虚拟环境这种事简直就是个噩梦。而对我来讲,Anaconda能帮上很大的忙。 关于乐高分类软件,有个主要部分。比如说,一个通过摄像头实现的图像采集系统:
扫描仪/“图像缝纫机” 采集器完成工作后,会将图像发送到“图像缝纫机”(把两张图接在一起)上,后者的主要任务是两件事:一是判定自从上一张图像之后带着某块乐高的传送带移动了多少( 看视频里的波浪线),二是更新一张新扫描进来的内存图像。在两块乐高中间隔开的部分“缝纫机”会剪一下,然后把下一张扫进来的乐高图像接上。 上述这些都是用OpenCV写出来的。 扫描器和“图像缝纫机”完成了自己的工作后,成果看起来是这样的:
分类 这是这件事真正有趣的部分。这块我弄过好多次,现在已经烦得不行了。 OpenCV基元 我第一次选择的方法是用OpenCV基元,特别是其中的轮廓匹配和圆检测。只要处理乐高的种类没那么多,用这种方式就还能保证一个相对不错的识别准确率。结合一部分简单的元数据(比一块乐高的长、宽、高),它就能分辨出所有基本型乐高积木块之间的区别,不过也不能再多了。 贝叶斯 换种方式,我们试试贝叶斯。贝叶斯分类器相当好理解:你先设计一大堆特征,然后依据这些特征构建检测器,之后再创建一个测试集以保证你的检测器运行得就像他们告诉你的那样好,都完成之后,你就尽己所能提高系统对那些特征的识别能力。你要把一个尽可能大的测试图像集扔到这个系统里去跑,以确定你所设定特征的优先级,进而确定每个特征所占的权重——如果某一特征出现就会被检测为“正确”,特征没有出现就会被检测为“错误”。 我用这种方法建立了一个基于如下特征的分类器: 交叉(两条线在中间某处相交) 圆(积木里包含比螺柱更大的圆形) 侧螺柱(侧面可见的螺柱) “饱满”(the part occupies a large fraction of its outer perimeter)(PS:这个表述量子位也不懂┑( ̄Д  ̄)┍) 高度 洞(积木上某处有个洞) 洞穿(这块积木被打通了) 长度 盘子(积木大概跟个盘子那么高) 矩形(积木大致是长方形) 斜坡(积木上有斜坡) “皮包骨”(the part occupies a small fraction of its outer perimeter)(PS:没怎么玩过乐高的量子位依旧是不懂┑( ̄Д  ̄)┍) 正方形(积木大概是正方形) 螺柱(积木上有可见的螺柱) “透”(积木是透明的) 体积(以立方毫米表示) 楔形(积木是楔形的) 宽度 (责任编辑:本港台直播) |