资讯动态

旋转编码器表面缺陷检测的机器视觉方案:从硬件选型到形态学算法落地

发布时间:2026/10/9 12:07:59 来源:尧图企业网站定制
简介一套基于机器视觉的旋转编码器缺陷检测系统完整代码与实验样本面向伺服电机生产线质检工程师、机器视觉初学者及智能制造相关专业学生解决旋转编码器表面断裂、孔洞、凸起等缺陷的人工检测效率低、易疲劳、标准不一致等实际问题。系统采用工业相机采集图像结合自适应ROI提取算法动态锁定分析区域以削减计算量再通过形态学腐蚀、膨胀、开闭运算去除噪声并强化缺陷边缘最终实现对编码器表面质量的高效、精准自动判别可满足产线连续监测需求。压缩包共30个文件总体积76.82MB内含4个Python源程序、2个pyc中间文件、9张PNG及10张BMP测试图并附带README、说明文档、附赠word资料与LICENSE授权信息代码结构清晰、测试样本多样能支撑算法复现、参数调试和二次开发。目前已有60人学习浏览内容兼顾从相机接口、图像预处理到缺陷分类的完整技术链路也提供了可直接修改的形态学算子与ROI策略适合作为机器视觉质检项目起步参考或课设/毕设拓展素材。1. 旋转编码器表面缺陷检测为什么值得上机器视觉伺服电机产线上旋转编码器表面一旦有断裂、孔洞、凸起装配后轻则影响零位信号重则造成伺服抖动甚至停机。人工目检只能看到正面翻转、照明、疲劳都会让判定结果漂移而且每件产品的缺陷留证基本靠拍照登记效率极低。基于机器视觉的旋转编码器缺陷检测系统用工业相机在固定工位抓拍编码器表面再通过自适应ROI提取和形态学算法自动分割出缺陷区域按几何特征分类成断裂、孔洞、凸起把产线质检从“目检抽查”升级成“全检可追溯”。本文直接给出能落到伺服电机生产线的完整路线硬件怎么选、ROI怎么自适应、形态学参数怎么调、现场踩过哪些坑以及最后怎么验证这套系统真的稳定。2. 系统结构与相机选型从产线节拍反推硬件参数2.1 检测对象与工位布局旋转编码器在伺服电机产线上一般以端面朝上或侧面朝上两种姿态进入检测工位最常见的是端面朝上因为断裂、孔洞、凸起这类表面缺陷大多集中在外壳端面和码盘面。视觉系统的标准布局是工业相机垂直安装在编码器正上方镜头光轴与检测面垂直光源围绕镜头或放在检测面四周形成均匀照明。先把三类缺陷的成像特征理清楚后面设定算法阈值才有依据。缺陷类型物理成因成像特征断裂/裂纹装配磕碰、压铸应力、运输挤压细长线状方向随机长度跨度大与背景有稳定灰度反差孔洞注塑/压铸不完整或异物脱落残留近圆形凹坑边缘带毛刺尺寸一般集中在几像素到几十像素凸起金属翻边、注塑流痕、焊点残留局部亮块或暗块面积小与背景灰度存在明显台阶工位布局还要考虑编码器是如何进入视野的。如果靠托盘直线运输相机只需要垂直正拍如果靠转盘切换工位就要把转盘停止抖动时间计入拍照窗口。我一般会在相机固定支架上留三向调节结构方便现场对着夹具中心微调而不是靠改程序去补安装偏差。提示定位夹具的重复定位精度尽量控制在±0.5mm以内。自适应ROI能消除的偏差是图像层面的如果机械上每次偏了5mm镜头视野就必须开得很大像素当量会被稀释小缺陷就看不出来了。2.2 相机、镜头与光源选型边界相机分辨率的计算逻辑要先定精度需求。伺服电机编码器的表面缺陷如果要求检出最小0.1mm按工程习惯至少要让缺陷在图上占3×3像素否则形态学运算和阈值分割都容易把真实缺陷当噪声滤掉。换算成像素当量就是0.033mm/pixel。像素当量的计算公式是fov_w 85.0 # 视野宽度单位 mm camera_w 2592 # 相机横向像素数 pixel_mm fov_w / camera_w print(f像素当量: {pixel_mm:.3f} mm/pixel)这行代码说明一个基础换算像素当量等于视野宽度除以横向像素数。2592像素对应500万像素级别相机85mm视野下像素当量约0.033mm/pixel刚好满足0.1mm缺陷占3像素的需求。如果视野要开到120mm同样相机像素当量会变成0.046mm/pixel0.1mm缺陷只占2像素左右形态学处理时很容易被开运算吃掉这就是为什么选相机不能只看分辨率要把视野和最小缺陷一起算。光源选型是另一个容易翻车的点。编码器端面常有金属亮圈或螺丝孔用高角度环形光会形成强烈的镜面反射反光带在顶帽变换里会被误检成凸起。低角度环形光对减少镜面反射更有效同轴光适合检测刻痕类浅缺陷。如果编码器外壳是深色塑料低角度环形光加固定曝光是最稳的组合。硬件项推荐方向理由相机500万~1200万像素面阵全局快门满足0.1mm精度全局快门避免运动模糊镜头定焦低畸变焦距35mm或50mm工作距离200~300mm时有足够景深光源低角度环形光或同轴光抑制弧面反光提高表面细节反差曝光固定曝光时间关闭自动曝光保证形态学阈值随图像灰度稳定2.3 像素-毫米标定流程像素当量的精确值不能只靠公式算要用棋盘格标定板实测。因为镜头实际工作距离、安装俯仰角都会影响最终像素尺寸。标定时把棋盘格平放在编码器检测面同一高度确认标定板完全在视野内并且反光不严重。import cv2 import numpy as np def calc_pixel_mm(gray, square_mm): 根据棋盘格灰度图计算像素当量mm/pixel cols, rows 11, 8 # 内角点数量必须与棋盘格一致 found, corners cv2.findChessboardCorners(gray, (cols, rows)) if not found: raise RuntimeError(棋盘格角点检测失败请检查视野和反光) corners corners.reshape(-1, 2) dists [] for i in range(len(corners) - 1): if (i 1) % cols 0: continue # 跳过换行处只统计同一行相邻角点 dists.append(np.linalg.norm(corners[i 1] - corners[i])) px_per_square np.mean(dists) return square_mm / px_per_square这段代码的逻辑是棋盘格角点按行逐点排列同一行相邻角点之间的距离对应一个真实物理边长把所有行内相邻距离取平均就能得到每格对应的像素数。square_mm是已知的棋盘格单格物理尺寸除以平均像素数就是像素当量。跳过换行处很关键如果不跳过行列交界处的角点会额外算出一段斜向大距离标定结果直接被拉偏。标定完成后把像素当量写入配置文件每次换镜头或改工作距离都要重新标定一次。镜头固定死、光源固定死、编码器高度固定死之后这个值一般不需要频繁修正。3. 自适应ROI提取从“固定框”到“跟随姿态变化的检测窗口”3.1 为什么固定ROI在产线上会翻车很多第一次做编码器检测的工程师会直接画一个固定ROI觉得定位夹具已经把编码器卡死了。实际上夹具磨损、托盘公差、来料尺寸波动、产线振动叠加起来编码器在画面里的位置很容易偏移3到5个像素还会伴随1°以内的角度偏摆。固定ROI的后果是检测窗口边缘正好切在编码器外壳弧线上背景被框进来或者真实缺陷落在ROI边界外直接漏检。更麻烦的是角度偏摆固定ROI没法跟着旋转原本应该水平的裂纹在框内变成倾斜长宽比特征被扭曲分类结果就乱了。自适应ROI的思路是每帧重新定位编码器的旋转外接矩形然后做旋转校正把所有样本归一化到同一角度和同一中心。这样后面所有形态学处理和缺陷判定都基于一个稳定的坐标系误检和漏检才压得下来。3.2 基于轮廓的旋转外接矩形提取自适应ROI的定位我用的是轮廓法不需要任何样本训练速度快而且对缺陷本身不敏感因为定位只依赖编码器整体外形。import cv2 import numpy as np def locate_encoder_roi(gray): 自适应定位编码器所在旋转矩形。 返回 ((cx, cy), (width, height), angle)定位失败返回 None blur cv2.GaussianBlur(gray, (5, 5), 0) # 编码器表面一般比背景暗用 INV 模式 # 如果现场是暗背景亮工件改成 THRESH_BINARY _, bin_img cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU) # 15x15 的闭运算把表面孔洞、刻线整体填平 # 避免孔洞边缘把外轮廓拉出锯齿导致矩形角度抖动 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15)) closed cv2.morphologyEx(bin_img, cv2.MORPH_CLOSE, kernel) contours, _ cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return None # 取最大轮廓其余小块都视为背景噪点 largest max(contours, keycv2.contourArea) rect cv2.minAreaRect(largest) return rect这段代码的作用是把编码器从背景里“框”出来。GaussianBlur先降噪THRESH_OTSU自动算二值化阈值MORPH_CLOSE用15×15椭圆核做闭运算把表面孔洞填平这样外轮廓才是一个完整闭合的编码器外形。minAreaRect返回旋转矩形包含中心坐标、宽高和角度三个关键量。闭运算核的大小需要按实际图像分辨率调。如果编码器表面的孔洞直径在图上占10个像素15×15的核刚好能盖住核太小孔洞填不平轮廓会缺一块矩形角度每帧抖动核太大又会把编码器外轮廓和相邻背景粘在一起矩形面积突然变大。我一般先量一下最大孔洞的像素直径再取它的1.5倍作为闭运算核尺寸。3.3 旋转校正与标准化裁剪拿到旋转矩形后不能直接在这个斜矩形上做形态学因为形态学核本身是有方向的不校正的话同一个缺陷在不同角度下检出的特征完全不一致。所以要先做旋转校正把矩形摆正再裁剪出ROI。def normalize_roi(gray, rect): 把旋转矩形校正为水平方向并裁剪出 ROI。 返回 (roi图像, 有效掩膜) ((cx, cy), (w, h), angle) rect # minAreaRect 的角度范围是 [-90, 0)宽高定义可能互换 # 这里统一为水平方向为准避免后续特征判断错乱 if angle -45: angle 90 angle w, h h, w M cv2.getRotationMatrix2D((cx, cy), angle, 1.0) rotated cv2.warpAffine(gray, M, (gray.shape[1], gray.shape[0]), flagscv2.INTER_CUBIC, borderModecv2.BORDER_CONSTANT, borderValue0) # 从旋转图中心按矩形宽高切出 ROI x0 int(round(cx - w / 2)) y0 int(round(cy - h / 2)) roi rotated[y0:y0 int(h), x0:x0 int(w)] return roi这段代码解决了两个问题一是把倾斜的编码器旋转到水平二是把有效的检测区域裁剪出来。angle -45的判断非常关键因为minAreaRect的角度定义会在某些姿态下把宽度和高度互换如果不统一后续长宽比特征的方向就反了。INTER_CUBIC插值比最近邻平滑能保留裂纹边缘的连续性。旋转后矩形四角可能带进背景区域因为编码器外形是圆盘而旋转矩形是正方形。对圆盘形编码器我会再生成一个椭圆掩膜把矩形四角的背景排除掉def make_ellipse_mask(roi): h, w roi.shape[:2] mask np.zeros((h, w), dtypenp.uint8) cv2.ellipse(mask, (w // 2, h // 2), (max(1, w // 2 - 4), max(1, h // 2 - 4)), 0, 0, 360, 255, -1) return mask这个椭圆掩膜比实际编码器边缘内缩4个像素用来吸收旋转校正的残余误差。如果编码器外壳是方形端盖就去掉这一步改用轮廓填充掩膜。自适应ROI做到这一步整套系统就有了一个稳定坐标系不管编码器怎么偏移、怎么旋转送入缺陷检测模块的图像都是居中、摆正、掩膜完整的标准ROI。4. 形态学缺陷检测断裂、孔洞、凸起的完整处理流程4.1 光照归一化与形态学通道划分编码器表面存在光照不均匀原因包括光源衰减、端面弧度和金属亮带反光。如果用固定阈值直接做二值化同一类缺陷在不同位置会有完全不同的分割结果。所以我先把ROI除以它的低频背景得到光照归一化图像。def remove_background(roi): 用大尺度高斯低通估算背景ROI 除以背景做光照归一化。 bg cv2.GaussianBlur(roi, (0, 0), 15) norm cv2.divide(roi, bg, scale255) return norm这里的逻辑是背景变化是低频的缺陷是高频的用大尺度高斯低通把背景单独提取出来原图除以背景后暗角和亮带就被抹平了缺陷相对背景的对比度变得全局一致。GaussianBlur的sigma取15是因为编码器ROI尺寸在512像素量级缺陷宽度一般不超过10像素15既能保留缺陷细节又能把光照缓变滤干净。归一化之后缺陷检测分成两个形态学通道暗缺陷通道黑帽变换提取比背景暗的裂纹、孔洞亮缺陷通道顶帽变换提取比背景亮的凸起。这样划分是为了避免裂纹和凸起在一个阈值体系里互相干扰。裂纹是暗目标在顶帽图里几乎不可见凸起是亮目标在黑帽图里也不可辨。分开处理每种缺陷用最适合的对比度方向和阈值策略。4.2 断裂与裂纹检测黑帽通道加几何约束裂纹在归一化图里表现为局部灰度低谷黑帽变换的定义是“闭运算结果减去原图”闭运算会抹平比结构元素小的暗区域原图减闭运算后那些被抹掉的暗区域就单独显现出来了。def detect_cracks_and_holes(norm, params): 黑帽通道检测暗缺陷再按长宽比区分裂纹和孔洞。 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9)) blackhat cv2.morphologyEx(norm, cv2.MORPH_BLACKHAT, kernel) # OTSU 自动定阈值裂纹越明显黑帽响应越强 _, dark_bin cv2.threshold(blackhat, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 3x3 开运算去掉单像素噪点 dark_bin cv2.morphologyEx(dark_bin, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) n, labels, stats, _ cv2.connectedComponentsWithStats(dark_bin, 8) cracks, holes [], [] for i in range(1, n): x, y, w, h, area stats[i] if area params[min_area]: continue aspect max(w, h) / max(1, min(w, h)) if aspect params[crack_aspect]: cracks.append((x, y, w, h, area)) else: holes.append((x, y, w, h, area)) return cracks, holes这段代码的核心是把黑帽响应图做连通域分析每个连通域代表一个候选缺陷。min_area过滤掉小于9像素的噪声块crack_aspect设成3意思是长宽比大于等于3的候选判为裂纹小于3的归到孔洞。裂纹的物理特征是细长所以长宽比是它的强判别项。这里有个经验值黑帽提取暗缺陷时结构元素要比最宽的裂纹略大。如果裂纹宽度在5像素左右9×9椭圆核比较合适核太小会漏掉宽裂纹核太大又会把邻近的暗区域粘连成一个块裂纹长度特征失真。参数不是固定死的换分辨率后第一件事就是重新量裂纹宽度再反推核尺寸。4.3 孔洞缺陷的圆形度判定与毛刺过滤孔洞和裂纹在暗通道里都会出现只用长宽比区分还不够。真实孔洞边缘常带毛刺毛刺会把孔洞的外接矩形拉长长宽比就可能超过3被误判成裂纹。所以我给孔洞加了一个圆形度约束。def circularity_from_label(labels, i): 计算单个连通域的圆形度圆为1越扁越小。 area np.sum(labels i) sub (labels i).astype(np.uint8) * 255 cnts, _ cv2.findContours(sub, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) perimeter cv2.arcLength(cnts[0], True) if perimeter 0: return 0.0 return 4.0 * np.pi * area / (perimeter * perimeter)圆形度的公式是4π面积除以周长的平方。标准圆的圆形度为1带毛刺的孔洞因为周长变大圆形度会跌到0.4到0.6之间。实际使用中孔洞判定的圆形度阈值取0.6以上裂纹因为细长圆形度普遍低于0.3两者能拉开明显距离。孔洞和裂纹的分支判定逻辑可以写成if aspect params[crack_aspect] and circularity 0.3: cracks.append((x, y, w, h, area)) elif circularity 0.6: holes.append((x, y, w, h, area))这样调整后一条宽0.5mm、长1mm的短裂纹不会因为长宽比刚好超过3就被误判成孔洞一个边缘带毛刺的大孔洞也不会因为毛刺拉长了外接矩形就变成裂纹。4.4 凸起检测顶帽通道加亮度阈值凸起的成像特点是局部亮度高于周围背景顶帽变换正好提取这类亮结构。和裂纹检测不同的是凸起检测不推荐用OTSU全局阈值因为凸起面积小、数量少在全图范围内占的灰度比例太低OTSU的分割点经常把凸起和背景一起吞掉。我改成固定亮度阈值阈值通过离线样本标定。def detect_bumps(norm, params): 顶帽通道检测凸起亮度和面积双阈值过滤。 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)) tophat cv2.morphologyEx(norm, cv2.MORPH_TOPHAT, kernel) _, bump_bin cv2.threshold(tophat, params[bump_bright], 255, cv2.THRESH_BINARY) n, labels, stats, _ cv2.connectedComponentsWithStats(bump_bin, 8) bumps [] for i in range(1, n): x, y, w, h, area stats[i] if area params[bump_area]: bumps.append((x, y, w, h, area)) return bumpsbump_bright是顶帽响应图的亮度阈值一般在20到50之间浮动。低于20会把正常纹理的微小起伏当成凸起高于50又会放过亮度偏低的真实凸起。我建议先收集30个以上真实凸起样本统计它们在顶帽图里的灰度直方图取直方图低谷作为初始阈值再用误检率修正。凸起检测的核尺寸比暗缺陷检测大一号因为凸起的物理尺寸通常比裂纹宽。11×11椭圆核能保留凸起的整体轮廓又不至于把相邻的小凸起合并成一个。4.5 缺陷判定规则的汇总三段检测通道最后汇成一张判定表每类缺陷的检测通道和特征约束都清晰对应。缺陷类型检测通道判别特征常见问题断裂/裂纹黑帽长宽比≥3圆形度0.3面积≥9裂纹两端过浅黑帽响应不足被漏检孔洞黑帽圆形度≥0.6面积区间内孔洞内有填充物暗通道不显凸起顶帽亮度阈值面积阈值反光带在顶帽图里形成假凸起判定输出统一记为(类型, x, y, w, h)原始图像和判定框一起存盘作为产线追溯依据。这个结构后面做离线参数回归时也方便直接回放历史图像就能验证参数效果。5. 产线落地避坑采集、光源、参数与误检的排查5.1 合格品被频繁误判为凸起金属反光带干扰现象产线试运行第一天合格品误判率超过10%人工复查发现被判定为凸起的区域全部集中在编码器端面的金属亮环上。原因金属端面在低角度环形光下产生镜面反射局部像素接近饱和顶帽变换对这类高灰度带响应非常强阈值分割后形成大面积候选块。解决在凸起检测前用原图亮度信息生成过曝掩膜把灰度值大于等于250的区域从凸起候选里剔除。过曝区里的信息已经饱和任何算法都拿它做不了可靠判定不如直接屏蔽。over_exposed roi 250 bump_bin[over_exposed] 0这样处理后反光带不再产生虚检。我另外把环形光的角度从30°调到了15°让金属亮圈的反光整体偏出相机视野误检率进一步降到1%以下。5.2 ROI角度跳变导致漏检对称形状的矩形角度歧义现象同一批编码器大多数图像ROI定位正常但每隔几件就会有一次矩形角度跳变90°旋转校正后的ROI内容翻转缺陷位置对不上出现漏检。原因编码器外壳接近圆形或正方形时minAreaRect返回的角度在90°范围内存在两个等价解宽和高的定义互相切换角度就从45°附近跳到-45°附近。解决先做角度归一化把angle -45的情况转成angle 90并交换宽高再对连续帧的角度做滑动平均。产线上编码器到达检测工位时姿态基本固定角度不会真的突变滑动平均能把跳变帧拉回正常值。if abs(angle - last_angle) 10: angle last_angle else: last_angle angle角度跳变问题如果放任不管后续形态学检测的所有特征都会因为坐标系翻转而失真。加了这个保护后连续1000个工件的ROI角度保持了稳定。5.3 检测节拍跟不上形态学大核耗时失控现象单张图像的软件处理耗时从最初的30ms涨到200ms产线节拍只有100ms视觉系统成了整条线的瓶颈。原因我把暗缺陷检测和凸起检测的形态学核都调大了31×31的结构元素在500万像素全分辨率上做顶帽和黑帽计算量翻了十几倍。解决改成两步法。第一步先在缩小后的图像上用大核粗筛缩放到256像素宽第二步只在粗筛命中的候选区域原图坐标上做精细的黑帽和顶帽。大部分合格品在第一步就返回了只有少数可疑区域才走完整流程。两步法需要额外注意粗筛的阈值要放松一点宁可多筛出几个候选也不能在粗筛阶段把真实缺陷丢掉。粗筛漏了的缺陷后面精细阶段不会再出现。5.4 换批次后漏检率上升光照模型漂移现象同一套参数稳定运行两周后厂家换了一批外壳材料漏检率从1%直接涨到15%而误检率反而下降。原因新批次外壳表面粗糙度和底色不同整体灰度分布变了原先离线标定的亮度阈值和OTSU分割点不再适用。检测算法对绝对灰度敏感光照模型一变所有阈值都失效。解决把阈值参数和批次绑定换型时加载对应的参数文件。同时做一个自动校验流程每个批次上线前用20个合格品和20个已知缺陷品跑一遍统计误检率和漏检率不达标就不放行。这个坑的根源在于我一开始把阈值当成了固定常量实际上阈值应该跟着来料的光学特性走。参数文件化之后换批次不再需要重新写算法只需要重新标定一次。5.5 裂纹与划痕混在一起几何特征不足以细分现象人工复核时发现大量被判为“断裂”的区域其实是装配划痕表面压痕和真实裂纹在图像上都是细长暗线长宽比特征无法区分。原因裂痕和划痕的几何维度差异不在长宽比而在宽度一致性。真裂纹沿走向宽度均匀宽度较细划痕往往是硬物刮擦造成宽度起伏大且整体偏宽。解决引入骨架平均宽度特征。用距离变换求每个候选区域的局部宽度再沿骨架方向取平均宽度作为裂纹与划痕的区分依据。def crack_mean_width(mask): 用距离变换估算缺陷区域的平均宽度 dist cv2.distanceTransform(mask, cv2.DIST_L2, 3) _, skeleton cv2.threshold(dist, 0.5 * dist.max(), 255, cv2.THRESH_BINARY) return 2 * np.sum(dist[skeleton 0]) / max(1, np.sum(skeleton 0))距离变换的像素值代表该点到最近背景的距离骨架位置上的距离值乘以2就是该处的目标宽度。真实裂纹平均宽度一般在0.2mm以下且方差小划痕平均宽度普遍超过0.3mm且方差大。加上这个特征后裂纹和划痕的分类准确率明显提升。6. 离线参数回归与产线验证让阈值从“试出来”变成“调出来”6.1 用缺陷样本库做阈值曲线搜索形态学参数不能靠拍脑袋定尤其min_area、crack_aspect、bump_bright这三个阈值每个都直接影响漏检和误检的平衡。常见做法是先建一个样本库至少包含50个真实缺陷样本和50个合格品样本然后对目标参数做扫描记录每个参数值下的漏检数和误检数。for min_area in range(5, 51, 5): fn sum(1 for s in defect_samples if not detect_defects(s, min_areamin_area)) fp sum(1 for s in ok_samples if detect_defects(s, min_areamin_area)) print(min_area, fn, fp)这段扫描代码的逻辑很简单遍历参数值分别统计缺陷样本的漏检数和合格品样本的误检数最后选一个漏检数最低、同时误检数可接受的参数点。伺服电机产线上漏检风险远大于误检漏出一个真缺陷可能造成整批电机返工所以选点时优先压低漏检数再考虑误检率。6.2 上线前的影子运行与每天回归基线参数定好后不要直接接入自动排除机构先在产线上跑三天影子模式。算法照常判定但结果只进数据库不触发剔除动作。每天用人工复核结果去对比算法判定统计两类指标合格品被误判的比例和真实缺陷被漏掉的比例。我养成的习惯是每天保存所有NG图像按日期和设备号建目录保留至少30天。产线上反馈某一个电机有问题时还能回放当时的图像看是算法漏检还是压根没拍到缺陷面。这个习惯救过我一次有一批电机客户反馈零位漂移追回来查图像数据发现缺陷出现在编码器侧面而相机只拍了端面。后来在工位加了侧拍相机问题才彻底解决。最后一句话送给想动手的同行这套方案的价值不在于用多高深的算法而在于用自适应ROI把坐标系稳住用形态学把缺陷从背景里干净地分离出来再靠离线数据把阈值调到合适位置。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑