视觉算法模块听起来吓人,但每一个都可以用日常生活的比喻来理解。下面把最常用的模块翻译成“人话”。
一、预处理模块:给图像“洗澡”
滤波(Filtering)—— 把噪点抹平
想象你在一张砂纸上写字,字迹毛毛糙糙。滤波就是用一块软布把砂纸擦平,让字迹更清晰。高斯滤波像用海绵轻轻擦,中值滤波像用橡皮擦掉一个个小黑点。
Cv2.GaussianBlur(gray,gray,newSize(5,5),0);// 海绵擦Cv2.MedianBlur(gray,gray,5);// 橡皮擦形态学(Morphology)—— 修修补补
二值化后的图像常有毛刺和小孔。开运算像用砂纸打磨边缘,去掉凸起;闭运算像用腻子填平小坑,补上小孔。
Cv2.MorphologyEx(binary,binary,MorphTypes.Open,kernel);// 去毛刺Cv2.MorphologyEx(binary,binary,MorphTypes.Close,kernel);// 填小孔二、分割模块:把“要找的东西”圈出来
阈值分割(Threshold)—— 划线站队
老师让学生按身高站队:超过 170cm 的站左边,不到 170cm 的站右边。阈值分割就是划一条灰度线,比线亮的归为白,比线暗的归为黑。
Cv2.Threshold(gray,binary,100,255,ThresholdTypes.Binary);// 灰度 > 100 的变成 255(白),其余变成 0(黑)自适应阈值(AdaptiveThreshold)—— 因地制宜
如果教室左边有阳光、右边背光,用同一条身高线就不公平。自适应阈值给每个区域单独划线,光照不均时特别管用。
Cv2.AdaptiveThreshold(gray,binary,255,AdaptiveThresholdTypes.GaussianC,ThresholdTypes.Binary,11,2);Canny 边缘检测 —— 描边
拿一支笔沿着物体的轮廓描一圈,描出来的线就是边缘。Canny 就是自动描边的算法,它找的是“亮度变化最剧烈的地方”。
Cv2.Canny(gray,edges,50,150);三、特征提取模块:把“区域”变成“形状”
轮廓(Contours)—— 把色块变成线
二值化后,白色区域是一堆像素。轮廓算法把这些像素的外边界连成一条线,就像把地图上的色块描成国界线。
Cv2.FindContours(binary,outvarcontours,out_,RetrievalModes.External,ContourApproximationModes.ApproxSimple);最小外接矩形(MinAreaRect)—— 给形状套个框
不管轮廓多歪,总能找到一个最小的旋转矩形把它框住。这个矩形告诉你:物体在哪、多大、转了多少度。
varrect=Cv2.MinAreaRect(contours[0]);// rect.Center 中心点,rect.Size 宽高,rect.Angle 角度霍夫变换(Hough)—— 找直线和圆
在一堆散点中找直线,就像在一群人中找排成一排的人。霍夫变换让每个点“投票”,票数最多的那条线就是答案。找圆同理。
Cv2.HoughLinesP(edges,outvarlines,1,Math.PI/180,50,50,10);Cv2.HoughCircles(gray,outvarcircles,HoughModes.Gradient,1,20);四、测量模块:把“形状”变成“数字”
面积与周长(ContourArea / ArcLength)—— 量大小
轮廓围住的像素有多少个,就是面积;轮廓线有多长,就是周长。这是最基础的测量。
doublearea=Cv2.ContourArea(contours[0]);doubleperimeter=Cv2.ArcLength(contours[0],true);拟合(FitLine / FitCircle)—— 找规律
给一堆点,找一条最“贴合”它们的直线或圆。就像给一群人的身高数据画一条趋势线。
Cv2.FitLine(points,outvarline,DistanceTypes.L2,0,0.01,0.01);亚像素角点(CornerSubPix)—— 精确到小数点后
普通角点定位只能精确到 1 个像素。亚像素算法在像素内部继续细分,把定位精度提升到 0.1 像素甚至更高。这在精密测量中至关重要。
Cv2.CornerSubPix(gray,corners,newSize(5,5),newSize(-1,-1),newTermCriteria(CriteriaTypes.Eps|CriteriaTypes.MaxIter,30,0.01));五、识别模块:把“数字”变成“类别”
模板匹配(MatchTemplate)—— 找相同的图案
拿一张小图(模板)在大图里滑动,看哪个位置最像。就像在一堆拼图中找特定的一块。
Cv2.MatchTemplate(src,template,result,TemplateMatchModes.CCoeffNormed);Cv2.MinMaxLoc(result,out_,outdoublemaxVal,out_,outPointmaxLoc);// maxLoc 就是最佳匹配位置,maxVal 是匹配分数OCR / 条码识别 —— 读字和读码
OCR 把图像中的文字变成字符串,条码识别把黑白条纹变成数字。工业上常用 ZXing(条码)和 Tesseract(OCR)。
// ZXing 示例varreader=newBarcodeReader();varresult=reader.Decode(bitmap);stringtext=result.Text;六、一句话记住每个模块
| 模块 | 通俗理解 | 核心函数 |
|---|---|---|
| 滤波 | 给图像洗澡 | GaussianBlur |
| 形态学 | 修修补补 | MorphologyEx |
| 阈值分割 | 划线站队 | Threshold |
| 自适应阈值 | 因地制宜划线 | AdaptiveThreshold |
| Canny | 描边 | Canny |
| 轮廓 | 色块变线 | FindContours |
| 最小外接矩形 | 给形状套框 | MinAreaRect |
| 霍夫变换 | 找直线和圆 | HoughLines/HoughCircles |
| 面积/周长 | 量大小 | ContourArea/ArcLength |
| 拟合 | 找规律 | FitLine |
| 亚像素 | 精确到小数 | CornerSubPix |
| 模板匹配 | 找相同图案 | MatchTemplate |
| OCR/条码 | 读字和读码 | ZXing/Tesseract |
七、组合起来:一个完整的“找孔并测量”流程
// 1. 洗澡Cv2.GaussianBlur(gray,gray,newSize(5,5),0);// 2. 划线站队Cv2.Threshold(gray,binary,100,255,ThresholdTypes.Binary);// 3. 修修补补Cv2.MorphologyEx(binary,binary,MorphTypes.Open,kernel);// 4. 色块变线Cv2.FindContours(binary,outvarcontours,out_,RetrievalModes.External,ContourApproximationModes.ApproxSimple);// 5. 给形状套框varrect=Cv2.MinAreaRect(contours[0]);// 6. 量大小doublearea=Cv2.ContourArea(contours[0]);doubleradius=Math.Sqrt(area/Math.PI);// 7. 判定boolisOk=Math.Abs(radius-5.0)<=0.1;每一个模块都在做一件简单的事,组合起来就完成了复杂的检测任务。理解这些“人话比喻”,比记住 API 名字更重要。