区域生长
晶棒生长
分水岭
像素值高的高山 低的是丘陵
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;



















