缺陷检测抛开blob分析,尺寸判定与深度学习之外还有一种常用的方式,个人称之为差异分类模型,简称差分模型
个人对其应用过程为:
准备阶段:图像预处理,创建模型,查找模型定位,创建差分模型
应用阶段:查找模型定位,差分模型分类
Demo效果(由于限制5M动图,图像压缩的有些失真,下面进行详细介绍时会以单图呈现)
一,图像预处理
1,加载图像
2,绘制目标区域大致ROI
鉴于图像情况个人建议可以采用
create_drawing_object_rectangle2 || draw_rectangle2 || draw_rectangle2_mod
进行封装
3,锁定抠出目标区域
二值化提取区域然后进行区域膨胀(这一步主要是扣取模板图像,个人采用 threshold 算子提取,shape_trans生成多边形,dilation_circle进行区域膨胀)
二,创建create_shape_model用以定位
num_levels # 金字塔的层数
angle_start # 模板旋转的起始角度
angle_extent # 模板旋转角度范围
angle_step # 旋转角度的步长
optimization # 模板优化和模板创建方法
metric # 匹配方法设置
contrast # 设置对比度
min_contrast # 设置最小对比度
三,验证find_shape_model定位效果
四,创建差分模型
1,选择图像文件夹路径
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
2,创建差分模型(CreateVariationModel参数最好是开放,小编Demo案例直接写死)
private void btn_create_variation_model_Click(object sender, EventArgs e){try{hv_VarModelID.Dispose();HOperatorSet.CreateVariationModel(imageWidth, imageHeight, "byte", "standard",out hv_VarModelID);laTicps2.ForeColor = Color.Green;laTicps2.Text = "创建差异模型成功";}catch{laTicps2.ForeColor = Color.Red;laTicps2.Text = "创建差异模型失败";}}
3,训练差分模型(养成良好的内存管理习惯很重要)
private void btn_train_variation_model_Click(object sender, EventArgs e){try{DirectoryInfo TheFolder = new DirectoryInfo(fileName);//文件路径for (int i = 0; i < TheFolder.GetFiles().Length; i++)//遍历文件夹{if (TheFolder.GetFiles()[i].Length > 0 && (TheFolder.GetFiles()[i].Extension == ".png" || TheFolder.GetFiles()[i].Extension == ".bmp"))//或者jpg,png 文件大小要大于0且是图片文件{Application.DoEvents();HOperatorSet.ReadImage(out HIMage, fileName + "\\" + tifNames[i]);FitImage(HIMage, hWC);HTuple angle_start2, angle_extent2, MinScore, matchNum, MaxOverlap, SubPixel, numLeave, greediness;angle_start2 = (new HTuple(Convert.ToDouble(tbx_angle_start2.Text))).TupleRad();angle_extent2 = (new HTuple(Convert.ToDouble(tbx_angle_extent2.Text))).TupleRad();MinScore = Convert.ToDouble(tbx_MinScore.Text);matchNum = Convert.ToDouble(tbx_matchNum.Text);MaxOverlap = Convert.ToDouble(tbx_MaxOverlap.Text);SubPixel = cbx_SubPixel.Text;numLeave = Convert.ToDouble(tbx_numLeave.Text);greediness = Convert.ToDouble(tbx_greediness.Text);HTuple hv_Column = new HTuple(), hv_Angle = new HTuple();HTuple hv_Score = new HTuple(), hv_Row = new HTuple();hv_Row.Dispose(); hv_Column.Dispose(); hv_Angle.Dispose(); hv_Score.Dispose();HOperatorSet.FindShapeModel(HIMage, hv_ModelID, angle_start2, angle_extent2, MinScore, matchNum, MaxOverlap, SubPixel, numLeave, greediness, out hv_Row, out hv_Column, out hv_Angle, out hv_Score);HTuple hv_HomMat2D = new HTuple();HObject ho_TraingImage = null, ho_ImageAffineTrans = null;HOperatorSet.GenEmptyObj(out ho_ImageAffineTrans);HOperatorSet.GenEmptyObj(out ho_TraingImage);//创建一个矩阵将当前图像变换到模板位置hv_HomMat2D.Dispose();HOperatorSet.VectorAngleToRigid(hv_Row, hv_Column, hv_Angle, hv_SRow, hv_SColumn,0, out hv_HomMat2D);//把当前图像变换到参照位置ho_ImageAffineTrans.Dispose();HOperatorSet.AffineTransImage(HIMage, out ho_ImageAffineTrans, hv_HomMat2D,"constant", "false");//把训练模型图像锁定出来ho_TraingImage.Dispose();HOperatorSet.ReduceDomain(ho_ImageAffineTrans, ho_RegionDilation, out ho_TraingImage);//训练模板HOperatorSet.TrainVariationModel(ho_TraingImage, hv_VarModelID);//操作提示laTicps.Text = "当前正在训练" + (i + 1) + "/" + (TheFolder.GetFiles().Length) + "张图像";Thread.Sleep(1000);}}laTicps2.ForeColor = Color.Green;laTicps2.Text = "训练模型成功";}catch{laTicps2.ForeColor = Color.Red;laTicps2.Text = "训练模型失败";}}
4,确定最终差分模型
PrepareVariationModel
5,查看差分模型效果区域图像
五,应用验证
private void btn_getResult_Click(object sender, EventArgs e)
{HTuple angle_start2, angle_extent2, MinScore, matchNum, MaxOverlap, SubPixel, numLeave, greediness;angle_start2 = (new HTuple(Convert.ToDouble(tbx_angle_start2.Text))).TupleRad();angle_extent2 = (new HTuple(Convert.ToDouble(tbx_angle_extent2.Text))).TupleRad();MinScore = Convert.ToDouble(tbx_MinScore.Text);matchNum = Convert.ToDouble(tbx_matchNum.Text);MaxOverlap = Convert.ToDouble(tbx_MaxOverlap.Text);SubPixel = cbx_SubPixel.Text;numLeave = Convert.ToDouble(tbx_numLeave.Text);greediness = Convert.ToDouble(tbx_greediness.Text);HTuple hv_Column = new HTuple(), hv_Angle = new HTuple();HTuple hv_Score = new HTuple(), hv_Row = new HTuple();hv_Row.Dispose(); hv_Column.Dispose(); hv_Angle.Dispose(); hv_Score.Dispose();HOperatorSet.FindShapeModel(HIMage, hv_ModelID, angle_start2, angle_extent2, MinScore, matchNum, MaxOverlap, SubPixel, numLeave, greediness, out hv_Row, out hv_Column, out hv_Angle, out hv_Score);//创建一个矩阵将当前图像变换到模板位置HTuple hv_HomMat2D = new HTuple();HTuple hv_Number = new HTuple();HObject ho_ImageAffineTrans = null, ho_CheckImage = null;HObject ho_CheckRegion = null, ho_ConnectedRegions = null, ho_SelectedRegions = null;HOperatorSet.GenEmptyObj(out ho_ImageAffineTrans);HOperatorSet.GenEmptyObj(out ho_CheckImage);HOperatorSet.GenEmptyObj(out ho_CheckRegion);HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);HOperatorSet.GenEmptyObj(out ho_SelectedRegions);hv_HomMat2D.Dispose();HOperatorSet.VectorAngleToRigid(hv_Row, hv_Column, hv_Angle, hv_SRow, hv_SColumn,0, out hv_HomMat2D);//把当前图像变换到参照位置ho_ImageAffineTrans.Dispose();HOperatorSet.AffineTransImage(HIMage, out ho_ImageAffineTrans, hv_HomMat2D,"constant", "false");//把训练模型图像锁定出来ho_CheckImage.Dispose();HOperatorSet.ReduceDomain(ho_ImageAffineTrans, ho_RegionDilation, out ho_CheckImage);//获取模板图像与差异化图像的差分区域ho_CheckRegion.Dispose();HOperatorSet.CompareVariationModel(ho_CheckImage, out ho_CheckRegion, hv_VarModelID);//联通区域断开ho_ConnectedRegions.Dispose();HOperatorSet.Connection(ho_CheckRegion, out ho_ConnectedRegions);//根据要求筛选区域ho_SelectedRegions.Dispose();HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area","and", 100, 99999);//判断及输出缺陷区域hv_Number.Dispose();HOperatorSet.CountObj(ho_SelectedRegions, out hv_Number);HOperatorSet.DispObj(ho_ImageAffineTrans, HW);HObject ho_ModelContours;HOperatorSet.GenEmptyObj(out ho_ModelContours);ho_ModelContours.Dispose();HOperatorSet.GetShapeModelContours(out ho_ModelContours, hv_ModelID, 1);HOperatorSet.VectorAngleToRigid(0, 0, 0, hv_SRow, hv_SColumn,0, out HTuple homMat2D);HOperatorSet.AffineTransContourXld(ho_ModelContours, out HObject ho_ModelContours1, homMat2D);HW.SetColor("green");HW.DispObj(ho_ModelContours1);if (hv_Number>0){HW.SetDraw("fill");HW.SetLineWidth(2);HW.SetColor("red");//显示ROIHOperatorSet.DispObj(ho_SelectedRegions, HW);ticps3.ForeColor = Color.Red;ticps3.Text = "NG";}else{ticps3.ForeColor = Color.Green;ticps3.Text = "OK";}}