尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

富士康金属件尺寸测量:OpenCV与深度学习视觉算法源码包

富士康金属件尺寸测量:OpenCV与深度学习视觉算法源码包 简介本资源面向计算机视觉与工业自动化方向的开发者及算法学习者聚焦富士康金属件的自动化尺寸测量问题。项目尝试用OpenCV模板匹配与深度学习图像识别两种路线先定位目标位置再统计像素面积并结合比例尺换算实际尺寸同时涉及角度测量等难点适合具备一定Python与视觉基础、希望了解工业检测落地思路的读者。压缩包共88个文件约47.56MB包含20个py源码脚本、44张png与9张jpg图像样本、2段mov与2段mp4过程录屏以及json配置、md说明、ipynb实验笔记和Dockerfile等覆盖数据、训练、推理与部署环节。目前已有147人学习。读者可获得完整的测量算法源码、项目说明文档与配套数据参考0/4/7号位置的识别测量结果理解匹配定位、特征提取与比例换算的实现细节并借鉴作者在镜头放大倍数受限、小目标识别与角度处理上的排错经验。1. 富士康金属件尺寸测量一份能跑通的视觉算法源码包产线上量一个金属件的长宽、孔径、角度如果还靠卡尺一个个卡效率低不说人为读数误差也难控。这份资源就是冲着这个场景来的用计算机视觉替代人工卡尺先定位金属件上的关键位置再统计该位置占用的像素面积最后按比例尺换算成实际尺寸。包里给的是 Python 源码、项目说明和配套数据包含 OpenCV 传统匹配、深度学习分割两条路线的尝试记录还有foxconn_aoi.ipynb、topview_training.py、circle_in_images.py这些能直接翻的脚本。适合做工业质检、自动化测量方向的工程师也适合拿它当计算机视觉项目练手的人——前提是你愿意先搞清楚它为什么难再动手复现。2. 先看清这份源码包的结构与两条技术路线2.1 目录里到底有什么从数据到脚本的对应关系拿到一个压缩包最怕的是不知道从哪下手。这份资源的目录结构其实是有逻辑的按“数据—脚本—模型—文档”四块拆开看就清楚了。数据部分集中在code data和dataset里图片命名带视角前缀01_topview_*是顶视图02_frontview_*是前视图03_backview_*、04_backview_*是背视图。01_topview_moving*.mov/mp4是运动状态下的视频用来验证动态场景下的边缘提取。01_topview_sharp_pins.png、a_1.png、a_2.png这些是单帧样本01_topview_sliced.png、01_topview_slice_01.png是切片处理后的中间结果。脚本部分按功能分01_topview_a1.py是顶视图 A1 位置的测量入口01_topview_slices.py、topview_slice.py做切片shapes_training.py、topview_training.py是训练脚本circle_in_images.py专门处理圆孔类特征edge_in_video.py从视频里提边缘。mrcnn目录是 Mask R-CNN 的实现opencv_test是 OpenCV 的试验代码。文档和配置有README.md、docs、requirements.txt、Dockerfile、create-unattended-iso.sh、dsd.seed。test、train.log是训练日志foxconn_aoi.ipynb是完整的 Notebook 流程记录。目录/文件作用是否必须code data样本图片与视频是复现基础dataset训练数据集走深度学习路线时必需mrcnnMask R-CNN 模型代码深度学习路线必需opencv_testOpenCV 试验脚本传统路线参考requirements.txt依赖清单是环境搭建用foxconn_aoi.ipynb完整流程记录建议先读train.log训练日志排查训练问题时看提示先打开foxconn_aoi.ipynb通读一遍比直接跑脚本更能理解作者的思路和踩过的坑。2.2 两条路线怎么选OpenCV 匹配 vs 深度学习分割这份资源最有价值的地方是它没有只给一条“成功路线”而是把两条路都试了并且留下了失败记录。这对后来者很重要——能帮你省掉重复试错的时间。OpenCV 路线用的是模板匹配、边缘检测、轮廓提取这一套。circle_in_images.py里大概率是霍夫圆检测或轮廓拟合edge_in_video.py用的是 Canny 或 Sobel 提边缘。这条路线的优点是快、依赖少、可解释性强缺点是面对“人为定义分割、物体本身是整体”的情况匹配算法很难稳定定位到 1~15 号位置因为位置边界不是物理存在的是人为划的。深度学习路线走的是 Mask R-CNN 分割mrcnn目录和topview_training.py、shapes_training.py都是为这条路服务的。它的优势是能学到语义边界不依赖人工设计的匹配模板难点在于实物尺寸太小CNN 下采样后特征图更小小目标识别精度会掉。作者在记录里也提到工业相机放大倍数有限厂家没有更大倍数的定制镜头这是硬件层面的硬约束。我一般会这样选如果测量位置有明确的物理边缘比如孔、边、角先用 OpenCV 快速验证如果位置是人为定义的、没有物理边界或者光照变化大、传统算法不稳定再上深度学习。这份资源两条路都给了你可以按自己的场景挑。2.3 环境搭建从 requirements 到能跑通第一个脚本环境这一步别偷懒工业视觉项目对 OpenCV 和深度学习框架的版本很敏感。包里给了requirements.txt但没写死版本号的地方要自己注意。# 建议用虚拟环境避免和系统 Python 冲突 python -m venv venv_foxconn source venv_foxconn/bin/activate # Windows 用 venv_foxconn\Scripts\activate # 先装基础依赖 pip install --upgrade pip pip install -r requirements.txt # 单独确认 OpenCV 和深度学习框架 pip install opencv-python opencv-contrib-python pip install tensorflow1.14.0 # Mask R-CNN 老代码通常锁 TF1.x逻辑说明requirements.txt是作者环境的最小依赖集但 Mask R-CNN 这类老项目对 TensorFlow 版本很挑TF2.x 直接跑大概率报tf.placeholder之类的错。参数上opencv-contrib-python比opencv-python多了 SIFT、SURF 等特征匹配模块传统路线里可能用到。如果requirements.txt里没锁版本装完先跑一个最小验证import cv2 import numpy as np print(OpenCV:, cv2.__version__) img cv2.imread(code data/01_topview_sample.png) print(图像尺寸:, img.shape if img is not None else 读取失败)这段代码只做两件事确认 OpenCV 能导入、确认样本图能读进来。如果img是None多半是路径里有空格code data中间有空格或者中文路径问题用cv2.imdecode配合np.fromfile能绕过去。3. 像素面积到实际尺寸比例尺标定与测量脚本拆解3.1 比例尺怎么定像素当量的计算与验证整个测量链路的核心公式就一个实际尺寸 像素尺寸 × 像素当量。像素当量mm/pixel定不准后面所有测量都是白搭。标定方法常见有两种。一种是用已知尺寸的标准件比如量块、标准圆放在同一工位、同一焦距下拍一张用它的像素尺寸除以实际尺寸。另一种是用标定板做相机标定拿到内参和畸变系数后再换算。这份资源里没有明确给标定脚本但从01_topview_a1.py的命名看A1 位置应该是有一个已知参考的。import cv2 import numpy as np # 读取标定参考图假设图中有一个已知直径的标准圆 img cv2.imread(code data/01_topview_sample.png) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 霍夫圆检测找标准圆 circles cv2.HoughCircles( gray, cv2.HOUGH_GRADIENT, dp1, minDist50, param1100, param230, minRadius20, maxRadius200 ) if circles is not None: circles np.round(circles[0, :]).astype(int) for (x, y, r) in circles: # r 是像素半径已知实际半径 R_mm R_mm 5.0 # 举例标准圆实际半径 5mm pixel_per_mm r / R_mm print(f圆心({x},{y}) 像素半径{r} 像素当量{pixel_per_mm:.4f} pixel/mm)逻辑说明HoughCircles的dp是累加器分辨率minDist控制圆心最小间距param1是 Canny 高阈值param2是圆心累加阈值——param2调小会检出更多圆但也更多误检。minRadius/maxRadius按实际圆在画面里的像素范围设设太宽会拖慢速度。验证标定准不准最简单的办法是拿另一个已知尺寸的件再测一遍看误差是否在可接受范围。如果误差随位置变化中心准、边缘偏说明镜头畸变没校正需要上标定板。3.2 定位与分割从整图到目标区域的脚本流程定位这一步传统路线和深度学习路线的脚本入口不一样。传统路线看01_topview_a1.py和circle_in_images.py深度学习路线看topview_training.py和mrcnn。传统路线的典型流程是灰度化 → 滤波 → 边缘/阈值 → 轮廓 → 筛选。下面这段是轮廓筛选的常见写法# 接上面的 gray blurred cv2.GaussianBlur(gray, (5, 5), 0) _, thresh cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) contours, _ cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: area cv2.contourArea(cnt) if area 500: # 过滤噪点阈值按实际最小目标面积设 continue x, y, w, h cv2.boundingRect(cnt) # 用像素当量换算实际宽高 real_w w / pixel_per_mm real_h h / pixel_per_mm print(f目标位置({x},{y}) 实际尺寸 {real_w:.2f}mm x {real_h:.2f}mm)逻辑说明THRESH_OTSU自动选阈值适合光照均匀的场景RETR_EXTERNAL只取外轮廓避免内孔干扰contourArea过滤小噪点这个阈值要按你画面里最小目标的像素面积来定设大了会漏检设小了会误检。深度学习路线则是先用topview_training.py在dataset上训练再用训练好的权重做推理。mrcnn的输出是每个实例的 mask对 mask 做像素统计就是面积。这条路对小目标的处理常见做法是把输入分辨率调大、或者用金字塔/多尺度推理但作者也说了硬件放大倍数有限是硬约束软件层面只能缓解。3.3 角度测量为什么它比长度更难长度测量本质是数像素角度测量则依赖两个边的方向估计对边缘提取的精度要求高一个量级。边缘只要有一两个像素的抖动角度就可能差零点几度。常见做法是先拟合直线再算夹角。OpenCV 里可以用cv2.fitLine对轮廓点做直线拟合# 假设 cnt 是某条边的轮廓点 [vx, vy, x0, y0] cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) import math angle math.degrees(math.atan2(vy, vx)) print(f边缘方向角: {angle:.2f} 度)逻辑说明cv2.fitLine的distType用DIST_L2是最小二乘对离群点敏感如果边缘有毛刺可以先用DIST_HUBER或先做形态学开运算。atan2返回的是方向角两条边的方向角之差才是你要的夹角注意角度归一化到 0~180 度。作者在记录里提到“部分位置需要测量角度也很难处理”原因就在这角度对边缘质量太敏感而金属件表面反光、倒角、毛刺都会让边缘不干净。我的经验是角度测量前一定要做亚像素边缘提取cv2.cornerSubPix或cv2.findContours后插值否则重复性很差。4. 避坑与排查这份资源里最容易翻车的五个点4.1 小目标识别精度掉得厉害现象深度学习路线训练完大目标分割还行1~15 号里偏小的位置 mask 要么缺失要么糊成一团。原因CNN 下采样后特征图尺寸缩小小目标在深层特征图上只剩几个像素信息丢失严重。作者也提到工业相机放大倍数有限源头分辨率就不够。解决优先从数据侧想办法——用更高分辨率拍、或者把相机靠近拍局部软件侧可以改小 stride、用空洞卷积、或者上多尺度训练。如果硬件真没法换就接受小目标精度上限把测量重点放在大尺寸位置上。4.2 OpenCV 匹配定位飘忽不定现象同一工位、同一光照模板匹配今天能中、明天偏几个像素换一个件就完全对不上。原因1~15 号位置是人为定义的物体本身是整体没有物理边界给匹配算法抓。加上金属反光模板和实际图像的相关性不稳定。解决别硬用模板匹配。要么改成基于几何特征的定位找孔、找角点、找直线交点要么上深度学习学语义边界。如果非要用传统方法至少把光照做成可控的环形光、同轴光减少反光干扰。4.3 比例尺标定被忽略现象定位和分割都挺准但换算出来的实际尺寸系统性偏大或偏小换个工位偏得还不一样。原因像素当量没标定或者标定时的焦距、工作距离和实际测量时不一致。镜头畸变没校正边缘位置误差更大。解决每次换工位、换焦距、换镜头都要重新标定。标定件要放在和被测件同一平面。如果精度要求高上标定板做完整相机标定拿畸变系数做去畸变。4.4 环境依赖版本冲突现象pip install -r requirements.txt装完跑topview_training.py报ModuleNotFoundError或 TensorFlow 版本相关错误。原因Mask R-CNN 这类项目通常基于 TF1.x而默认 pip 装的是 TF2.x。OpenCV 不同版本 API 也有差异比如cv2.findContours返回值个数在 OpenCV 3 和 4 之间变过。解决按requirements.txt锁版本装TF 用 1.14 或 1.15。如果非要上 TF2用tf.compat.v1兼容层但 Mask R-CNN 的改动量不小不如直接开个 TF1 的虚拟环境省事。4.5 视频处理帧率与内存现象跑edge_in_video.py处理01_topview_moving*.mov时内存越吃越多或者处理速度远慢于视频帧率。原因逐帧读入后没有及时释放或者把每帧结果都存进列表。视频分辨率高时单帧内存占用不小。解决用cv2.VideoCapture逐帧读、逐帧处理、逐帧释放不要攒。如果只是验证算法抽帧处理就行没必要每帧都跑。写结果视频用cv2.VideoWriter注意编码器和帧率要和源一致。5. 进阶把测量结果做成可复现的验证流程走到这一步脚本能跑了但“能跑”和“测得准、测得稳”是两回事。我一般会强制自己做三件事这里也建议你在这份资源基础上补上。第一件是固定测试集。从code data里挑 10~20 张覆盖不同位置、不同光照的图存成一个test_set目录每次改完算法都跑一遍记录每个位置的测量值和真值。没有真值就用高精度卡尺量一遍哪怕只量几个关键位置。这份资源里inference_0_4_7.jpg、inference_3_5.jpg就是 0/4/7 和 3/5 号位置的推理结果你可以拿它们当起点但样本量太少说明不了稳定性。第二件是量化误差。别只看“看起来对”要算。下面这段是批量验证的骨架import os import cv2 import numpy as np test_dir test_set pixel_per_mm 20.0 # 你的标定值 results [] for fname in sorted(os.listdir(test_dir)): if not fname.endswith(.png): continue img cv2.imread(os.path.join(test_dir, fname)) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 这里替换成你的定位测量逻辑 # ... measured 0.0 # 占位 results.append((fname, measured)) # 和真值对比算绝对误差和重复性 for fname, m in results: print(f{fname}: 测量值 {m:.3f} mm)逻辑说明这段代码的重点不是测量逻辑而是“批量跑 记录”的框架。真值可以单独存一个 CSV跑完用 pandas 合并算 MAE 和最大偏差。重复性验证则是同一张图跑 10 次看结果波动——如果波动超过精度要求说明算法里有随机性比如 RANSAC或者阈值卡在临界点。第三件是留后悔药。每次调参、换模型、改预处理都把配置和结果存一份命名带日期和关键参数。工业视觉项目调到最后往往是某个不起眼的参数决定了成败没有记录就回不去。我自己的习惯是config_20250723_gauss5_thresh_otsu.yaml这种命名配合train.log一起归档。还有个具体技巧foxconn_aoi.ipynb里的流程可以拆成函数但别急着拆太细。先让 Notebook 能端到端跑通再按“读图—定位—测量—输出”四段拆每段一个函数中间结果存图。这样出问题时能一眼看出是哪段崩的比在几百行脚本里打断点快得多。从那以后我每次拿到这类视觉测量项目都强制先跑一遍标定验证和重复性测试再谈精度。希望帮到你。本文还有配套的精品资源点击获取
返回列表