news 2026/9/30 5:10:20

基于机器视觉的硬币分拣系统设计:从成像选型到OpenCV识别全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于机器视觉的硬币分拣系统设计:从成像选型到OpenCV识别全解析

简介:机器视觉技术将计算机视觉与机器人控制相结合,在自动化检测与分拣领域具有典型应用价值。该PDF文档围绕基于机器视觉的硬币分拣系统设计展开,面向自动化设备研发人员、高校机电或测控专业学生,解决硬币识别、定位与抓取分拣中的算法及系统集成问题。文档内容涵盖图像预处理、特征约束、模板匹配等视觉算法,以及相机坐标系与机械臂运动坐标系之间的转换方案,并详细阐述了机械臂抓取完成自动分拣的完整流程。作为一篇技术论文,文中还给出了实验验证结果,表明系统在准确率与漏检率方面满足实际需求,可为银行、商场等场景下的大批量硬币处理提供参考方案。资源为单个PDF文件,压缩包大小约1.04MB,属于技术文档类资料,结构紧凑,便于下载后直接阅读。目前已有266人学习浏览,适合需要快速了解机器视觉分拣系统设计思路的读者。

1. 一枚硬币从出现到入槽:这个机器视觉分拣系统到底要解决什么

收到硬币分拣系统的设计需求时,很多人的第一反应是“用重量区分不就行了吗”,但实际接触过项目就会明白:重量传感器只能区分币种差异大的情况,而且机械结构复杂、响应慢,一旦遇到相同重量不同面值的硬币就彻底失灵。基于机器视觉的硬币分拣系统走的是另一条路——用相机拍下硬币的直径、形状、纹理和颜色,在图像里算出特征,再让执行机构把硬币推进对应的滑道。这个方法的最大价值是柔性:换一套币种,只需改软件里的特征库,不用动机械。

这套系统适合谁?一是做课程设计或毕业设计的学生,需要一份能跑通全流程的方案;二是小型自动化设备厂商,想给分拣机增加视觉识别能力;三是在做硬币清分设备预研的工程师。整条技术链条并不复杂:上料、成像、识别、分拣、统计,每一环都有自己的坑。下面把各环节的选型逻辑、参数设置和踩坑经验一条条拆开讲,目标是让读者照着这套思路能搭出一台样机,而不是停留在PPT设计上。

2. 先算视野和分辨率再选硬件:成像系统的选型搭配

2.1 视野和分辨率:先定物理指标,再碰相机

硬币分拣系统的成像硬件由相机、镜头、光源和触发传感器构成。设计起点不是“买什么相机”,而是“需要看清硬币的什么特征”。人民币硬币的直径在19mm到25mm之间,如果要同时拍摄多枚硬币,视野通常要覆盖整个分拣通道,宽度会到40mm左右。判断一个硬币的面值最可靠的视觉特征是直径,所以成像系统必须保证直径测量误差小于0.1mm。

按视野40mm、最小精度0.1mm算,横向像素至少需要400个。实际工程上不会卡着下限设计,一般会把精度余量放到3到5倍,也就是视野40mm时用1200到2000像素。这样算下来,500万像素级别(2448×2048)的工业面阵相机是常见选择。如果只是单枚硬币逐个拍,视野收窄到30mm,200万像素也够用。镜头方面,定焦C接口镜头,焦距按工作距离反推:

焦距 = 工作距离 × 传感器靶面宽度 ÷ 视野宽度

比如工作距离150mm、视野40mm、靶面宽度6.4mm(1/1.8英寸),焦距约为24mm。实际项目里因为支架尺寸限制,常用8mm到16mm的短焦镜头配合更大工作距离,关键是锁死后不要再动,否则标定会失效。

注意:分辨率标称值不等于实测精度。要拿钢尺或标准量块放在视野里拍一张,用像素数和实际尺寸反向算出每像素对应的毫米数,这个数才是真正影响分拣准确率的标定系数。

2.2 光源方案:背光边缘优先,前光做纹理辅助

硬币识别的一个核心难题是表面反光。硬币是金属材质,币面有浮雕图案,如果只用前光(环形光从上方打),图像里会出现高光和阴影交错的现象,二值化后硬币边缘变得参差不齐,直径提取误差会被放大到肉眼可见的程度。

我在实际方案里最常用的是背光照明:把硬币放在透射光源上方,相机从顶部拍。此时硬币在图像里呈现为黑色实心圆,背景是亮的,轮廓极其干净,直接用大津法就能稳定分割。这种方案损失的是币面纹理信息,但直径、形状因子这些最核心的特征已经足够完成人民币硬币的分拣。

如果项目要求识别币面图案(比如区分同直径同厚度的纪念币),就在背光基础上增加一个低角度环形前光,让币面字符和花纹进入图像,用纹理特征做二次分类。两种光源不要同时全亮度工作,否则图像容易出现过度曝光。照明时序上,建议用控制器让光源只在相机曝光期间点亮,这样既省电又减少发热对相机的影响。

2.3 输送、触发和遮光,三个容易被忽略的配套环节

相机决定了成像质量的上限,但输送机构才是决定系统能不能稳定运行的基础。常见的方案有两种:振动盘加直振轨道(适合单枚分离后逐个拍照)和平带输送(适合连续检测后分拣)。振动盘方案的优势是硬币排列有序、间距可控,但上料速度有限;平带方案速度快,但硬币姿态随机,需要图像算法适应各种偏转角度和位置,这给后续的轮廓提取增加了难度。对设计任务来说,振动盘加直振轨道更容易把识别率做高,建议优先考虑。

触发传感器建议选对射式光电开关或金属接近开关。传感器信号触发相机采集,避免让相机一直处于连续采集状态,既节省算力又保证每一帧图像里都恰好只有一枚硬币。遮光罩也是必装的:环境光变化会让图像的灰度分布整体漂移,室内灯光、窗户透光、人员走动产生的阴影都会干扰阈值分割。用铝型材加遮光布做一个封闭小暗箱,成本不到一百元,能把环境光的干扰降到最低。

3. 图像处理与特征提取:从灰度图到面值判决的完整流程

3.1 图像预处理:滤波、二值化与形态学操作

拿到相机原始图像后,第一步不是直接找轮廓,而是做预处理。常规流程是:灰度化、滤波去噪、二值化、形态学处理。工业相机输出的是彩色图像或Bayer格式图像,灰度化后用3×3或5×5的中值滤波去除传感器噪声。中值滤波对椒盐噪声效果好,而且不会像高斯滤波那样把边缘磨糊,是硬币图像的首选。

二值化是整个流程里最影响成败的一步。固定阈值在环境光稳定的暗箱里可用,但更推荐大津法(Otsu),它按图像的灰度分布自动算出阈值,天然适应轻微的光照变化。OpenCV里的写法是:

import cv2 import numpy as np # 读取灰度图 img_gray = cv2.imread("coin.jpg", cv2.IMREAD_GRAYSCALE) # 中值滤波去噪,核大小取5 img_filtered = cv2.medianBlur(img_gray, 5) # 大津法二值化:自动求阈值,高于阈值为255(背景),低于阈值为0(硬币) _, img_binary = cv2.threshold(img_filtered, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 形态学开运算,去除二值图里的小噪点 kernel = np.ones((3, 3), np.uint8) img_morph = cv2.morphologyEx(img_binary, cv2.MORPH_OPEN, kernel, iterations=1)

这段代码里用了THRESH_BINARY_INV + cv2.THRESH_OTSU的组合,目的是让背光下的硬币变成白色前景、黑色背景,后续findContours找轮廓时逻辑更直观。MORPH_OPEN的作用是去掉硬币内部和边缘上的零星白点,避免轮廓提取时出现毛刺。如果硬币表面有大面积高光反射残留下黑斑,开运算核大小可以加到5×5,但核太大会让边缘向内收缩,影响直径测量精度,这一点要特别注意。

提示:如果二值化后硬币内部出现黑色空洞(由币面反光或污渍引起),不要简单加大核。先用cv2.morphologyEx做闭运算把空洞补上,再对轮廓做一次平滑处理,效果比单纯调核参数好得多。

3.2 轮廓提取与最小外接圆:直径和形状因子的计算

二值化之后就可以提取轮廓了。OpenCV 的findContours返回所有连通区域,需要按面积过滤掉噪点和无关区域。硬币的面积在图像里是固定的几千到几万像素,设一个面积上下限就能把干扰滤掉。然后对每个候选轮廓计算最小外接圆直径、轮廓面积、轮廓周长、圆形度(形状因子),这些特征就是后续分类的依据。

# 提取轮廓,只取最外层轮廓 contours, _ = cv2.findContours(img_morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 面积阈值:像素面积小于8000的多半是噪点,超过20000的可能是粘连目标 valid_contours = [] for cnt in contours: area = cv2.contourArea(cnt) if 8000 < area < 20000: valid_contours.append(cnt) for cnt in valid_contours: # 最小外接圆:得到圆心坐标和半径 (cx, cy), radius = cv2.minEnclosingCircle(cnt) diameter_pixel = radius * 2 # 轮廓周长与圆形度:圆形度越接近1,外形越接近标准圆 perimeter = cv2.arcLength(cnt, True) circularity = 4 * np.pi * area / (perimeter * perimeter) print(f"直径(像素): {diameter_pixel:.2f}, 圆形度: {circularity:.4f}")

这段代码的关键逻辑有两个:一是用面积先过滤掉明显不可能是硬币的连通域,二是用minEnclosingCircle而非外接矩形求直径——因为硬币在传送带上会随机旋转,外接矩形受姿态影响,最小外接圆则对旋转不敏感。圆形度可以用来剔除折角、铁片等异形干扰物:圆形度低于0.9的目标直接丢弃,不再进入分类环节。

3.3 特征数据库与分类判据:直径为主,灰度纹理为辅

特征准备好以后,下一步是建立分类标准。常见做法是把每种硬币的直径像素值、面积、圆形度、灰度均值写进一个特征表,分类时逐一比对。以人民币硬币为例,不同面值的直径差异明显:1元硬币直径25mm,5角硬币直径20.5mm,1角硬币直径19mm。像素值需要乘以标定系数换算成毫米,再与标准值比对。单纯靠直径其实已经能区分人民币的常见币种,但同直径的版本差异(比如不同年份的1元硬币)就需要靠纹理特征辅助。

# 标定系数:相机标定时测得的每像素对应毫米数 pixel_to_mm = 0.025 # 示例值,实际需用标准量块标定 class CoinClassifier: def __init__(self): # 特征库:直径(mm)下限、上限,灰度均值范围 self.feature_db = { "1元": {"d_min": 24.5, "d_max": 25.5, "gray_min": 100, "gray_max": 160}, "5角": {"d_min": 20.0, "d_max": 21.0, "gray_min": 60, "gray_max": 120}, "1角": {"d_min": 18.5, "d_max": 19.5, "gray_min": 80, "gray_max": 140}, } def classify(self, diameter_pixel, gray_mean): diameter_mm = diameter_pixel * pixel_to_mm for coin_type, feature in self.feature_db.items(): if feature["d_min"] <= diameter_mm <= feature["d_max"]: if feature["gray_min"] <= gray_mean <= feature["gray_max"]: return coin_type return "unknown"

分类逻辑采用的是区间匹配而不是最近邻匹配,原因在于实际测量一定会存在误差:硬币磨损、镜头畸变、光照波动都会让直径发生0.1到0.3mm的偏移。给每个币种留10%左右的阈值余量能明显降低误判率。灰度均值的引入是作为辅助判据,区分直径接近但材质不同的硬币(例如旧版1元硬币和新版1元硬币的灰度值有明显差异)。

3.4 实时性优化:ROI裁剪和多线程采集

识别速度直接影响分拣吞吐量。相机分辨率越高,图像处理耗时越长。如果目标速度是每秒5枚硬币,每帧图像的处理时间必须控制在200ms以内。优化手段有两个:一是裁剪感兴趣区域,通过光电触发信号估算硬币位置,只处理硬币周围的局部图像;二是把图像采集和处理放在两个线程,采集线程持续写入缓存,处理线程从缓存取帧进行识别。实测下来,ROI裁剪能把处理时间缩短到原来的1/3左右,效果立竿见影。

另外需要注意的一点是,相机曝光时间尽量调短。硬币在直振轨道上并非绝对静止,曝光时间大于1ms时容易产生运动模糊,导致轮廓边缘发虚。建议曝光时间设定在0.2ms到0.5ms之间,配合背光光源的亮度补偿,画面依然清晰。

4. 分拣执行与联动控制:视觉结果怎么变成推杆动作

4.1 像素坐标与物理坐标的映射

视觉识别输出的是硬币在图像里的位置和类别,但执行机构需要的是“在哪个物理位置推动哪个滑道”。这中间需要做坐标映射。对固定安装的相机来说,像素坐标到物理坐标的变换可以用最简单的等比例换算实现——前提是相机光轴垂直于传送面且没有透视畸变。安装相机时用水平尺校准,让镜头平面与传送带平行,这样标定只需要一个比例系数就够了。

如果安装角度无法保证垂直,就要用透视变换。常见做法是放一张棋盘格标定板,提取角点后计算单应性矩阵,OpenCV 的findHomography可以一行代码完成:

# 用四组对应点计算单应性矩阵 pts_src = np.array([[x1, y1], [x2, y2], [x3, y3], [x4, y4]], dtype=np.float32) pts_dst = np.array([[0, 0], [width, 0], [width, height], [0, height]], dtype=np.float32) homography_matrix, _ = cv2.findHomography(pts_src, pts_dst) # 像素坐标映射到物理坐标 pixel_coord = np.array([[[cx, cy]]], dtype=np.float32) physical_coord = cv2.perspectiveTransform(pixel_coord, homography_matrix)

这里pts_src是图像中棋盘格四个角点的像素坐标,pts_dst是对应物理位置坐标。透视变换的好处是允许相机有一定的安装倾角,不必苛求绝对垂直。但要注意:一旦相机位置动了,单应性矩阵就失效,必须重新标定,所以相机固定支架一定要用带锁紧的金属件,不能靠摩擦力定位。

4.2 PLC通讯与分拣时序:提前量计算是核心

识别到硬币类别之后,需要把结果传给执行机构。常见执行方案有电磁推杆式、气动吹除式和翻板式。电磁推杆结构简单,适合低速分拣;气动吹除响应快,适合高速场景;翻板式适合硬币从轨道末端下落时改变轨迹。无论哪种方式,PLC 都是控制核心。视觉系统通过串口(RS232/RS485)或以太网把分类结果发送给 PLC,PLC 根据光电传感器的位置确定推杆动作时机。

这里的核心参数是“提前量”,也就是从拍照点到分拣点的距离除以传送带线速度。比如拍照点距离推杆200mm,传送带速度200mm/s,那么推杆动作信号必须在识别完成后的1秒触发。触发太早或太晚,硬币都会错过推杆行程。一个更稳妥的做法是:在每个分拣点前装一个光电传感器,当硬币通过该传感器时,PLC 立即查询最近一次视觉结果并决定是否动作,这样就不依赖精确的速度计算了。

# 简化版的串口输出逻辑:识别到1元时发送字符 '1',5角发送 '2' import serial ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.1) result = classifier.classify(diameter_pixel, gray_mean) if result == "1元": ser.write(b'1') elif result == "5角": ser.write(b'2') else: ser.write(b'0') # 未知类别,默认不动作 ser.close()

串口通讯是视觉系统与PLC之间最稳妥的方式。波特率9600虽然慢,但一帧数据只有几个字节,延迟可以忽略不计。要注意的是串口线缆必须用屏蔽双绞线,并且与电机动力线分开走线,否则变频器或步进驱动器启动时产生的电磁干扰会让通讯数据频繁出错——这是现场最隐蔽的坑之一。

5. 硬币分拣常见问题排查:5个翻车现场与整改措施

5.1 币面反光导致二值化后出现“黑洞”

现象:背光照明下,硬币内部出现不规则黑色区域,轮廓提取后硬币边缘呈锯齿状,直径计算忽大忽小。

原因:硬币表面并非完全均匀。币面浮雕图案在透射光下仍会形成局部高光或阴影,导致二值化后内部产生空洞;此外,如果硬币有污渍或氧化层,也会让局部灰度低于阈值。

解决:先做形态学闭运算填补内部空洞,再做轮廓提取。闭运算的核大小从3×3试到7×7,以硬币边缘不产生明显膨胀为准。如果空洞仍严重,调整背光亮度,让硬币整体亮度落在阈值曲线的中间区域,而不是接近边界。

5.2 硬币粘连导致轮廓错分

现象:两枚硬币在轨道上挨得很近,二值化后变成一个连通域,面积翻倍,无法正确识别任何一枚。

原因:振动盘送料节奏不稳定,或者直振轨道上硬币间距过小。面积筛选无法区分两个粘连硬币与一个大面积异物。如果强行按面积上限截断,则粘连硬币的直径特征也会被污染。

解决:优先在机械上拉开间距,振动盘的频率和直振轨道的振幅是主要调节手段。图像侧可以加一层保护:检测到连通域面积超过单枚硬币面积上限的1.5倍,就判定为“多枚粘连”,直接发送剔除信号,不进入分类。这样可以避免把粘连目标误判成某种币。

5.3 运动模糊:硬币边缘不是圆而是椭圆

现象:图像中硬币边缘沿运动方向拖尾,测量出的直径在运动方向上偏大。

原因:硬币在轨道上存在滑动或微小跳动,曝光时间内目标位移超过一个像素。虽然直振轨道的振动幅度很小,但在曝光时间偏长时依然会产生明显影响。

解决:把相机曝光时间从1ms往下调,配合更高亮度的背光源来补偿进光量。经验值是把曝光时间控制在0.3ms以内,光源亮度调到相机灰度直方图最高峰在180到220之间。如果硬币确实存在跳动,还需要检查轨道是否有台阶或磨损点,机械问题靠图像处理是救不了的。

5.4 环境光导致阈值漂移

现象:白天的识别率正常,到了傍晚识别率下降,固定阈值方案尤其明显。

原因:遮光罩没有完全密封,视觉系统安装在窗边或靠近门口,环境光照强度随天气和时间变化。

解决:两个手段并用。算法上用大津法替代固定阈值,让阈值自动适应灰度分布;硬件上把遮光罩的接缝用黑色遮光布或密封条堵死,相机镜头前加装偏振片,进一步减少杂散光。这套组合能解决绝大部分环境光干扰。

5.5 标定失效:识别率突然集体下降

现象:系统运行一段时间后,所有硬币的直径测量值整体偏移0.5mm以上,分类大面积出错。

原因:相机支架松动、镜头调焦环转动、传送带更换造成拍照距离变化,都会让像素当量失效。还有一种隐蔽原因:相机重启后自动增益功能开启,导致图像整体变亮或变暗,灰度特征发生漂移。

解决:每次开机后自动执行一次标定验证,在轨道上放一枚已知直径的标准硬币,测量直径偏差是否在允许范围内。超出允许范围就停机报警。给相机的手动/自动增益模式锁死为手动,曝光时间、增益、白平衡参数全部固定写入配置文件,不许运行时自动调整。

6. 让系统真正可交付:验证指标与上线前的小技巧

样机跑通不等于系统稳定,交付前需要一套客观的验证方法。先采集每种硬币各100枚以上,建立标准样本库,记录每枚硬币的直径、面积、圆形度、灰度均值,算出均值和标准差。然后用这份样本库的统计量生成分类阈值,而不是凭经验拍脑袋。分类效果的衡量指标用精确率和召回率:精确率是分拣结果中正确的比例,召回率是所有该分拣出的硬币中被正确分拣出来的比例。对分拣系统来说,召回率比精确率更重要——漏掉一枚1元硬币的代价比误判一枚5角硬币更大,所以分类阈值可以设计得偏向“不确定就剔除”,由人工复检。

调试顺序上也有一个实用技巧:先关闭剔除机构,让系统只做识别和统计,观察连续100枚硬币的分类准确率。识别率达标后再打开剔除机构,此时错误集中在机械位置偏差而不在视觉算法,排查范围立刻缩小一半。这个习惯能省下大量现场调试时间。

最后我自己的习惯是准备一个配置文件,位置、曝光、阈值、特征库全部外置,不写死在代码里。每次换币种、换镜头、换轨道,只改配置不碰程序,系统维护的人从我自己变成任何会写配置文件的人。这个习惯不一定漂亮,但让项目交付后的支持成本低了不少。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 5:10:05

YOLO宠物行为数据集:猫情绪检测的物理可观测基座

1. 这不是一张“猫脸图集”&#xff0c;而是一套可直接驱动YOLO模型的情绪行为理解基座你在网上搜“猫情绪检测”&#xff0c;大概率会看到一堆模糊的公众号推文、短视频标题&#xff0c;或者某篇论文里轻描淡写提了一句“我们采集了200只猫的视频片段”。但真正能让你打开终端…

作者头像 李华
网站建设 2026/9/30 5:09:22

VMware虚拟机安装CentOS与宝塔面板完整指南

1. 为什么新人不建议“裸装”服务器&#xff1a;选型思路与前置准备1.1 这套组合到底解决什么问题很多刚接触网站搭建的朋友&#xff0c;第一次接触“宝塔”都是因为在云服务器上装网站环境太麻烦。你想想看&#xff0c;要在Linux上手动装Nginx、MySQL、PHP&#xff0c;再从源码…

作者头像 李华
网站建设 2026/9/30 5:08:46

STM32 HAL库 CubeMX 直流电机PID转速闭环控制实战

1. 从需求出发&#xff1a;这套直流电机闭环到底解决什么问题做电机控制的朋友应该都有过这种体会&#xff1a;开环调速就是"看天吃饭"&#xff0c;电池电压掉一点、负载变一点、电机温度升一点&#xff0c;转速立马跟着飘。想让一台普通的直流有刷电机稳稳停在设定转…

作者头像 李华
网站建设 2026/9/30 5:08:24

开源ArmorPaint实战:Blender PBR材质贴图高效绘制与避坑指南

写材质贴图这几年&#xff0c;我换过不少工具&#xff1a;PS手绘没有3D视图实时反馈&#xff0c;Quixel Mixer功能不错但商业授权要求绕来绕去&#xff0c;Substance Painter个人版一年上千块咬咬牙也忍过。后来在一个Blender社区帖子里看到有人提ArmorPaint&#xff0c;说它是…

作者头像 李华
网站建设 2026/9/30 5:08:13

企业智能体落地难?文件解析才是第一道墙

1. 为什么“文件问题”成了企业智能体落地的第一道墙我去年帮三家企业部署内部知识助手&#xff0c;每家都卡在同一个地方&#xff1a;不是模型调不起来&#xff0c;不是API调不通&#xff0c;而是上传一份PDF后&#xff0c;系统要么返回空结果&#xff0c;要么把合同条款和页眉…

作者头像 李华
网站建设 2026/9/30 5:07:03

从零实现Tracert:原始套接字与ICMP路由跟踪详解

简介&#xff1a;一份以计算机网络课程设计为背景的Tracert程序设计报告&#xff0c;面向学习原始套接字编程、ICMP协议与路由跟踪原理的学生或开发人员。报告从设计目的出发&#xff0c;逐步讲解路由跟踪的工作机制&#xff0c;并给出基于Windows Socket API的程序框架与流程分…

作者头像 李华