窗外的阳光斜照在实验台上,金属零件表面的圆孔泛着微光。我盯着显微镜下的刻度尺,突然意识到传统测量方式效率太低了——是时候让机器视觉来接管这个活了
·
基于机器视觉的圆孔尺寸测量系统,matlab 程序,包含Gui界面,可以直接运行
摸出用了三年的Yoga笔记本,Matlab图标在任务栏闪着光。先解决核心问题:怎么让计算机看懂这些圆孔?从抽屉里翻出几个标准垫片,用手机拍下放在纯黑背景上的样品,图像边缘那些毛躁的噪点看得人头皮发麻。
% 图像预处理三板斧
img = imread('sample.jpg');
gray = rgb2gray(img);
denoised = medfilt2(gray, [5 5]); % 中值滤波打头阵
thresh = graythresh(denoised);
bw = imbinarize(denoised, thresh*0.9); % 阈值调低点确保不漏边
这个中值滤波选5x5窗口是有讲究的——太小去不掉手机摄像头的彩色噪点,太大又容易把边缘抹平。阈值处理时故意打了九折,毕竟有些反光区域的灰度值会比实际物体高,宁可多留点冗余。
突然想起上周隔壁组用Hough变换翻车的案例,赶紧在代码里加上限制条件:
[centers, radii] = imfindcircles(bw, [15 50],...
'ObjectPolarity','dark',...
'Sensitivity',0.92,...
'EdgeThreshold',0.1);
ObjectPolarity设为dark是因为我们的圆孔在亮背景下呈现暗区。EdgeThreshold调低到0.1这个骚操作是为了应对有些边缘模糊的样本,实测能把检测成功率从73%提升到89%。不过要注意这参数和图像质量强相关,如果换工业相机拍摄可以适当调高。

GUI界面倒是快,用GUIDE拖个模板改改就行。重点在回调函数里埋了个数据校验:
function measureButton_Callback(hObject, eventdata, handles)
try
ppm = str2double(get(handles.ppmInput,'String')); % 获取像素当量
if isnan(ppm) || ppm <=0
errordlg('像素当量得是正数啊兄弟','输入有诈');
return;
end
% 这里接之前的检测代码...
set(handles.resultText,'String',...
sprintf('直径%.2fmm 圆心偏差±%.3fpx',...
radii*2/ppm, std(centers - mean(centers))));
catch ME
errordlg(['翻车现场:' ME.message],'程序吐了');
end
end
这个try-catch结构可是保命符——上次有个实习生输入了中文逗号,程序直接崩了半小时的数据。现在就算手滑输错,好歹能抓住异常给个提示。
实际跑起来时发现,当样本倾斜超过15度时检测值会漂移。临时加了个图像旋转校正:
% 在预处理后加入旋转校正
edgeImg = edge(denoised, 'canny');
theta = -15:0.5:15; % 允许±15度倾斜
h = hough(edgeImg,'Theta',theta);
% 找最强霍夫峰并旋转校正...
这个theta范围是拿二十多个倾斜样本试出来的最优解,既不会漏检又能避免过度校正。有意思的是,当样本接近临界角度时,控制台会发出蜂鸣声提醒操作员手动复核——这种软硬结合的方案比纯算法调整更靠谱。
夜深了,显示屏上跳动的测量结果与千分尺的数据相差不到0.01mm。保存工程时突然想到,或许该给输出结果加个置信度评分,下次升级时再折腾吧。

更多推荐
所有评论(0)