C#Halcon差异分类模型

缺陷检测抛开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");
        //显示ROI
        HOperatorSet.DispObj(ho_SelectedRegions, HW);

        ticps3.ForeColor = Color.Red;
        ticps3.Text = "NG";
    }
    else
    {
        ticps3.ForeColor = Color.Green;
        ticps3.Text = "OK";

    }


}

### 构建任务失败解决方案 当遇到 `Execution failed for task ':app:shrinkReleaseRes'` 错误时,这通常意味着资源压缩过程中出现了问题。此错误可能由多种原因引起,包括但不限于配置不正确、依赖冲突或特定于项目的其他因素。 #### 可能的原因分析 1. **ProGuard 或 R8 配置不当** ProGuard 和 R8 是用于优化和混淆代码以及减少 APK 大小的工具。如果这些工具的配置存在问题,可能会导致资源无法正常处理[^1]。 2. **重复资源** 如果项目中有多个模块定义了相同的资源名称,可能导致冲突并引发该错误。检查是否存在重名的 drawable、string 等资源文件[^2]。 3. **第三方库兼容性** 某些第三方库可能与当前使用的 Gradle 插件版本或其他库存在兼容性问题,从而影响到资源打包过程中的行为[^3]。 4. **Gradle 缓存问题** 有时旧缓存数据会干扰新编译的结果,尝试清理本地仓库和重新同步项目可以帮助排除此类潜在障碍[^4]。 #### 推荐的操作方法 为了有效解决问题,建议按照以下步骤逐一排查: ```bash # 清理项目构建目录 ./gradlew clean # 删除 .gradle 文件夹下的所有内容以清除缓存 rm -rf ~/.gradle/caches/ ``` 调整 `build.gradle` 中的相关设置也是一个重要环节: ```groovy android { ... buildTypes { release { minifyEnabled true // 是否启用代码缩减 shrinkResources true // 是否开启资源压缩 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 尝试禁用 shrinkResources 来测试是否为资源压缩引起的错误 // shrinkResources false } } } ``` 此外,在 `proguard-rules.pro` 文件内添加必要的保留规则,防止关键类被意外移除: ```text -keep class com.example.yourpackage.** { *; } # 替换为你自己的包路径 -dontwarn androidx.**,com.google.** # 忽略警告信息 ``` 最后,确保所使用的 Android Studio 版本是最新的稳定版,并且已经应用了所有的补丁更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值