2025-11-25 halcon 多通道操作c#halcon联合编程

区域生长

晶棒生长

分水岭

像素值高的高山 低的是丘陵

halcon算子使用

  • 导入图片


    效果如图
  • halcon代码
read_image (Image, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-01-17.png')
mean_image (Image, ImageMean, 3, 3)
*区域增长
median_image (ImageMean, ImageMedian, 'circle', 1, 'mirrored')
regiongrowing (ImageMean, Regions, 3, 3, 6, 100)
read_image (Image1, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-12-27.png')
*高斯滤波柔化
gauss_filter (Image1, ImageGauss, 9)
invert_image (ImageGauss, ImageInvert)
*分水岭
watersheds (ImageInvert, Basins, Watersheds)

彩色图通道拆分

  • 导入图片

    效果图
  • halcon代码
*-----------------------------------------------------------------

*拆分彩色图
read_image (Image2, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-15-08.png')
*灰度
rgb1_to_gray (Image2, GrayImage)


*计算通道数
count_channels (Image2, Channels)
decompose3 (Image2, R, G, B)
access_channel (Image2,Image44, 1)
*饱和度hsv

trans_from_rgb (R, G, B, h, s, v, 'hsv')

正常我们拿到彩色图的拆分流程

  • halcon代码
*正常流程拿到彩色图的流程
*-------------------------------------------------------------------------------------
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-19.11-Progress/examples/images/cable2.png')

rgb1_to_gray (Image, GrayImage)

count_channels (Image, Channels)

decompose3 (Image, R, G, B)

trans_from_rgb (R, G, B, h, s, v, 'hsv')

access_channel (Image, Image1, 3)

compose3 (R, G, B, MultiChannelImage)

案例 通过多通道色差 找到我们想要的那根线

*通过多通道色差 找到我们想要的那根线
*-------------------------------------------------------------------------------------------------------
* read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-19.11-Progress/examples/images/cable1.png')

* decompose3 (Image, R, G, B)
* trans_from_rgb (R, G, B, h, s, v, 'hsv')
*通过阈值选出我们想要的线
* threshold (s, Regions, 156, 232)
*裁剪h三条线
* reduce_domain (h, Regions, ImageReduced)
*筛选我们想要的那一条
* threshold (ImageReduced, Regions1, 20, 54)
*打散
* connection (Regions1, ConnectedRegions)
*面积筛选
* select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 3453.83, 5000)
*闭运算膨胀

* closing_circle (SelectedRegions, RegionClosing, 35)
*在原图上裁剪
* reduce_domain (Image, RegionClosing, ImageReduced1)

目标找最下面黄线

效果图
  • halcon代码
*通过多通道色差 找到我们想要的那根线
*-------------------------------------------------------------------------------------------------------
read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-19.11-Progress/examples/images/cable1.png')

decompose3 (Image, R, G, B)
trans_from_rgb (R, G, B, h, s, v, 'hsv')
*通过阈值选出我们想要的线
threshold (s, Regions, 156, 232)
*裁剪h三条线
reduce_domain (h, Regions, ImageReduced)
*筛选我们想要的那一条
threshold (ImageReduced, Regions1, 20, 54)
*打散
connection (Regions1, ConnectedRegions)
*面积筛选
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 3453.83, 5000)
*闭运算膨胀

closing_circle (SelectedRegions, RegionClosing, 35)
*在原图上裁剪
reduce_domain (Image, RegionClosing, ImageReduced1)

折痕案例练习

  • 导入图片
  • 执行界面
  • halcon代码
*折痕练习
*-------------------------------------------------------------------------------------
read_image (Image, 'C:/Users/12613/Desktop/图片/微信图片_20251125103232_486_151.png')
decompose3 (Image, R, G, B)
trans_from_rgb (R, G, B, h, s, v, 'hsv')

texture_laws (s, ImageTexture, 'ls', 2, 5)
*阈值分割
threshold (s, Regions, 41, 54)
closing_circle (Regions, RegionClosing, 5.5)
*打散
connection (RegionClosing, ConnectedRegions)
*面积筛选
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20547.3, 22680.9)
  • 效果图

综合代码备份

* read_image (Image, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-01-17.png')
* mean_image (Image, ImageMean, 3, 3)
*区域增长
* median_image (ImageMean, ImageMedian, 'circle', 1, 'mirrored')
* regiongrowing (ImageMean, Regions, 3, 3, 6, 100)
* read_image (Image1, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-12-27.png')
*高斯滤波柔化
* gauss_filter (Image1, ImageGauss, 9)
* invert_image (ImageGauss, ImageInvert)
*分水岭
* watersheds (ImageInvert, Basins, Watersheds)



*-----------------------------------------------------------------

*拆分彩色图
* read_image (Image2, 'C:/Users/12613/Desktop/图片/Snipaste_2025-11-25_10-15-08.png')
*灰度
* rgb1_to_gray (Image2, GrayImage)


*计算通道数
* count_channels (Image2, Channels)
* decompose3 (Image2, R, G, B)
* access_channel (Image2,Image44, 1)
*饱和度hsv

* trans_from_rgb (R, G, B, h, s, v, 'hsv')



*正常流程拿到彩色图的流程
*-------------------------------------------------------------------------------------
* dev_close_window ()
* dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
* read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-19.11-Progress/examples/images/cable2.png')

* rgb1_to_gray (Image, GrayImage)

* count_channels (Image, Channels)

* decompose3 (Image, R, G, B)

* trans_from_rgb (R, G, B, h, s, v, 'hsv')

* access_channel (Image, Image1, 3)

* compose3 (R, G, B, MultiChannelImage)
*通过多通道色差 找到我们想要的那根线
*-------------------------------------------------------------------------------------------------------
* read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-19.11-Progress/examples/images/cable1.png')

* decompose3 (Image, R, G, B)
* trans_from_rgb (R, G, B, h, s, v, 'hsv')
*通过阈值选出我们想要的线
* threshold (s, Regions, 156, 232)
*裁剪h三条线
* reduce_domain (h, Regions, ImageReduced)
*筛选我们想要的那一条
* threshold (ImageReduced, Regions1, 20, 54)
*打散
* connection (Regions1, ConnectedRegions)
*面积筛选
* select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 3453.83, 5000)
*闭运算膨胀

* closing_circle (SelectedRegions, RegionClosing, 35)
*在原图上裁剪
* reduce_domain (Image, RegionClosing, ImageReduced1)




*折痕练习
*-------------------------------------------------------------------------------------
read_image (Image, 'C:/Users/12613/Desktop/图片/微信图片_20251125103232_486_151.png')
decompose3 (Image, R, G, B)
trans_from_rgb (R, G, B, h, s, v, 'hsv')

texture_laws (s, ImageTexture, 'ls', 2, 5)
*阈值分割
threshold (s, Regions, 41, 54)
closing_circle (Regions, RegionClosing, 5.5)
*打散
connection (RegionClosing, ConnectedRegions)
*面积筛选
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20547.3, 22680.9)
*最小外接矩形
smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Length1, Length2)
*根据矩形生成边缘
gen_rectangle2_contour_xld (Rectangle, Row, Column, Phi, Length1, Length2)
*显示
dev_display (Image)
stop ()
dev_display (Rectangle)

形态学分析

  • 腐蚀 无法容纳结构元素就会被完全腐蚀

halcon c# 联合编程


添加引用

在工具箱 选择项浏览
添加halcondonet

把halcondll放到debug下


一共四步保证我们把项目考到没有halcon的环境依然可以使用

  • halcon代码
dev_close_window()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)

read_image (Image, 'printer_chip/printer_chip_01')
* HALCON 中图像的坐标体系是「行 × 列」(和窗口的「x×y」不同)
*因为图像的行 / 列从 0 开始计数
get_image_size (Image, Width, Height)
dev_set_part (0, 0, Height-1, Width-1)
dev_display (Image)

threshold (Image, Regions, 74, 255)
connection (Regions, ConnectedRegions)
*面积分割
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 28781.1, 33051.6)
*计数
count_obj (SelectedRegions, Number)
dev_display (Image)

disp_message (WindowHandle, Number, 'window', 12, 12, 'black', 'true')
  • 文件 导出 donet格式
  • 参照导出的c#代码 写静态读取图片的方法


    技巧是定位到action方法
把名字改成控件的名字

以上是通过静态方法读取固定地址图片

  • c#通过openfiledialog控件读取图片代码
   openFileDialog1.InitialDirectory = "c:\\";
   openFileDialog1.Filter = "JPG文件|*.jpg;*.jpeg|PNG文件|*.png|支持的图片文件|*.jpg;*.png";
   openFileDialog1.FilterIndex = 2;
   openFileDialog1.RestoreDirectory = true;

   if (openFileDialog1.ShowDialog() == DialogResult.OK)
   {
       HOperatorSet.ReadImage(out ho_Image, openFileDialog1.FileName);
   }
  • 结合一下 就是通过c#调用halcon窗口读到图片了
private void button1_Click(object sender, EventArgs e)
{

    openFileDialog1.InitialDirectory = "c:\\";
    openFileDialog1.Filter = "JPG文件|*.jpg;*.jpeg|PNG文件|*.png|支持的图片文件|*.jpg;*.png";
    openFileDialog1.FilterIndex = 2;
    openFileDialog1.RestoreDirectory = true;

    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        HOperatorSet.ReadImage(out ho_Image, openFileDialog1.FileName);
      //  HOperatorSet.ReadImage(out ho_Image, "printer_chip/printer_chip_01");
        HOperatorSet.GetImageSize(ho_Image, out HTuple hv_Width, out HTuple hv_Height);
        HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, hv_Height - 1, hv_Width - 1);
        HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
    }


  
}

处理图片

找到导出c#文件里 图片处理相应的代码


放到处理图片按钮的事件下
 private void button2_Click(object sender, EventArgs e)
 {
     HObject ho_ConnectedRegions;
     HOperatorSet.Threshold(ho_Image, out HObject ho_Regions, 74, 255);
     HOperatorSet.SelectShape(ho_Regions, out HObject ho_SelectedRegions, "area",
 "and", 28781.1, 33051.6);
     HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
     HOperatorSet.DispObj(ho_SelectedRegions, hWindowControl1.HalconWindow);
 }
逐步完善
  • 引入trackbar控件


  • 通过控件的滑动事件,实时更新处理图片的结果,并在halcon窗口显示
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace halconc_联合编程练习
{
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }
        HObject ho_Image;
        HObject ho_Regions;
        private void Form1_Load(object sender, EventArgs e)
        {       
            lblThresholdMin.Text = "阈值下限:" + tbThresholdMin.Value;
            lblThresholdMax.Text = "阈值上限:" + tbThresholdMax.Value;
            lblAreaMin.Text = "面积下限:" + tbAreaMin.Value;
            lblAreaMax.Text = "面积上限:" + tbAreaMax.Value;
        }

        private void button1_Click(object sender, EventArgs e)
        {

            openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = "JPG文件|*.jpg;*.jpeg|PNG文件|*.png|支持的图片文件|*.jpg;*.png";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                HOperatorSet.ReadImage(out ho_Image, openFileDialog1.FileName);
              //  HOperatorSet.ReadImage(out ho_Image, "printer_chip/printer_chip_01");
                HOperatorSet.GetImageSize(ho_Image, out HTuple hv_Width, out HTuple hv_Height);
                HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, hv_Height - 1, hv_Width - 1);
                HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
            }


          
        }

        private void button2_Click(object sender, EventArgs e)
        {
         //74-255
            HOperatorSet.Threshold(ho_Image, out  ho_Regions, 74, 255);
            HOperatorSet.Connection(ho_Regions, out HObject ho_ConnectedRegions);
            //28781.1, 33051.6
            HOperatorSet.SelectShape(ho_ConnectedRegions, out HObject ho_SelectedRegions, "area",
        "and", 28781.1, 33051.6);
            HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
            HOperatorSet.DispObj(ho_SelectedRegions, hWindowControl1.HalconWindow);
            HOperatorSet.CountObj(ho_SelectedRegions, out HTuple hv_NumObj);
            label1.Text = "识别结果:" + hv_NumObj.ToString();
        }

       
        // 通用识别函数:根据 TrackBar 当前值更新识别结果
        private void UpdateHalconRecognition()
        {
            // 1. 校验图像是否已读取
            if (ho_Image == null)
            {
                label1.Text = "识别结果:请先读取图像!";
                return;
            }

            try
            {
                // 2. 获取 TrackBar 当前值(转成 HALCON 支持的 HTuple 类型)
                int thresholdMin = tbThresholdMin.Value;
                int thresholdMax = tbThresholdMax.Value;
                int areaMin = tbAreaMin.Value;
                int areaMax = tbAreaMax.Value;

                // 3. HALCON 识别逻辑(和之前一致,参数替换为 TrackBar 值)
                HOperatorSet.Threshold(ho_Image, out HObject ho_Regions, thresholdMin, thresholdMax);
                HOperatorSet.Connection(ho_Regions, out HObject ho_ConnectedRegions); // 关键:补充区域连接
                HOperatorSet.SelectShape(ho_ConnectedRegions, out HObject ho_SelectedRegions, "area", "and", areaMin, areaMax);

                // 4. 显示结果
                HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow); // 显示原图
                HOperatorSet.DispObj(ho_SelectedRegions, hWindowControl1.HalconWindow); // 叠加显示目标区域

                // 5. 计数并更新 Label
                HOperatorSet.CountObj(ho_SelectedRegions, out HTuple hv_NumObj);
                label1.Text = "识别结果:" + hv_NumObj.ToString();
            }
            catch (Exception ex)
            {
                label1.Text = "识别失败:" + ex.Message;
            }
        }

      
        private void tbThresholdMin_Scroll(object sender, EventArgs e)
        {
            lblThresholdMin.Text = "阈值下限:" + tbThresholdMin.Value;
            UpdateHalconRecognition();
        }

        private void tbThresholdMax_Scroll(object sender, EventArgs e)
        {
            lblThresholdMax.Text = "阈值上限:" + tbThresholdMax.Value;
            UpdateHalconRecognition();
        }

        private void tbAreaMin_Scroll(object sender, EventArgs e)
        {
            lblAreaMin.Text = "面积下限:" + tbAreaMin.Value;
            UpdateHalconRecognition();
        }

      

      

        private void tbAreaMax_Scroll(object sender, EventArgs e)
        {
            lblAreaMax.Text = "面积上限:" + tbAreaMax.Value;
            UpdateHalconRecognition();
        }
    }
}
控件类型 名称(Name) 用途
TrackBar tbThresholdMin 阈值下限(0~255)
TrackBar tbThresholdMax 阈值上限(0~255)
TrackBar tbAreaMin 面积下限(0~50000)
TrackBar tbAreaMax 面积上限(0~50000)
Label lblThresholdMin 显示当前阈值下限数值
Label lblThresholdMax 显示当前阈值上限数值
Label lblAreaMin 显示当前面积下限数值
Label lblAreaMax 显示当前面积上限数值
HWindowControl hWindowControl1 HALCON 图像显示窗口
Label label1 显示识别计数结果
Button button2 识别按钮(或直接滑动实时识别)

属性设置 在设计窗口输进去

// 1. 初始化阈值 TrackBar
    tbThresholdMin.Minimum = 0;
    tbThresholdMin.Maximum = 255;
    tbThresholdMin.Value = 74; // 初始值(之前的阈值下限)
    tbThresholdMin.TickFrequency = 10;
    lblThresholdMin.Text = "阈值下限:" + tbThresholdMin.Value;

    tbThresholdMax.Minimum = 0;
    tbThresholdMax.Maximum = 255;
    tbThresholdMax.Value = 255; // 初始值(之前的阈值上限)
    tbThresholdMax.TickFrequency = 10;
    lblThresholdMax.Text = "阈值上限:" + tbThresholdMax.Value;

    // 2. 初始化面积 TrackBar(根据实际目标面积调整 Maximum)
    tbAreaMin.Minimum = 0;
    tbAreaMin.Maximum = 50000; // 假设目标面积不超过 50000
    tbAreaMin.Value = 28781; // 初始值(之前的面积下限)
    tbAreaMin.TickFrequency = 1000;
    lblAreaMin.Text = "面积下限:" + tbAreaMin.Value;

    tbAreaMax.Minimum = 0;
    tbAreaMax.Maximum = 50000;
    tbAreaMax.Value = 33051; // 初始值(之前的面积上限)
    tbAreaMax.TickFrequency = 1000;
    lblAreaMax.Text = "面积上限:" + tbAreaMax.Value;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容