1.引入Halcon组件
2.项目配置文件
3.页面配置
4.halcon接口调用
public partial class HDevelopExport
{
public int ResultN;
public double usedTime;
public double[] Px;
public double[] Py;
public double Fx, Fy;
public double Cr = 9;
public double Cx, Cy;
public bool IsStart = false;
HTuple hv_R;
List Aa = new List();
HTuple hv_Angle, hv_Score, hv_Runtime;
HTuple hv_ModelID, hv_Row, hv_Column;
HObject ho_Mask;
HTuple hv_S1, hv_S2;
HObject ho_Image, ho_Rectangle, ho_ImageReduced;
public HTuple hv_ExpDefaultWinHandle;
HWindowControl HWindowControl;
///
/// 打开相机
///
public void OpenCamera()
{
//hv_ExpDefaultWinHandle = Window;
HOperatorSet.GenEmptyObj(out ho_Image); // 生ho_Image数据区
// Grabbing images from a Daheng USB 2.0 camera
HOperatorSet.CloseAllFramegrabbers();
HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
-1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_Angle);
HOperatorSet.SetFramegrabberParam(hv_Angle, "tilt", -3);
HOperatorSet.GrabImageStart(hv_Angle, -1);
//open camera with default settings
}
///
/// 关闭相机
///
public void CloseCamera()
{
HOperatorSet.CloseAllFramegrabbers();
}
///
/// 实时播放
///
public void RealTimePlayback()
{
IsStart = true;
//HObject ho_Image = null;
//HTuple hv_AcqHandle = new HTuple();
Initialize local and output iconic variables
//HOperatorSet.GenEmptyObj(out ho_Image);
Image Acquisition 01: Code generated by Image Acquisition 01
//HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
// -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
//HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
Task task = new Task(() =>
{
while (IsStart)
{
ho_Image.Dispose();
HOperatorSet.GrabImageAsync(out ho_Image, hv_Angle, -1);
HTuple hv_Width, hv_Height;
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸
double ratioWidth = (1.0) * hv_Width[0].I / HWindowControl.Width;
double ratioHeight = (1.0) * hv_Height[0].I / HWindowControl.Height;
HTuple row1, column1, row2, column2;
if (ratioWidth >= ratioHeight)
{
row1 = -(1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
column1 = 0;
row2 = row1 + HWindowControl.Height * ratioWidth;
column2 = column1 + HWindowControl.Width * ratioWidth;
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
}
}
});
task.Start();
}
///
/// 拍照
///
public void Photograph()
{
IsStart = true;
HTuple hv_Width, hv_Height;
ho_Image.Dispose(); // 清除ho_Image中的数据
HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle); // 采集图像
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height); // 获取图片的尺寸
double ratioWidth = (1.0) * hv_Width[0].I / HWindowControl.Width;
double ratioHeight = (1.0) * hv_Height[0].I / HWindowControl.Height;
HTuple row1, column1, row2, column2;
if (ratioWidth >= ratioHeight)
{
row1 = -(1.0) * ((HWindowControl.Height * ratioWidth) - hv_Height) / 2;
column1 = 0;
row2 = row1 + HWindowControl.Height * ratioWidth;
column2 = column1 + HWindowControl.Width * ratioWidth;
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
// 显示ho_Image中的图片
HOperatorSet.SetDraw(hv_ExpDefaultWinHandle, "margin"); // 填充模式为只画框
HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 画线颜色红
HOperatorSet.DispRectangle1(hv_ExpDefaultWinHandle, row1, column1, row2, column2);
}
}
///
/// 初始化相机
///
public void InitHalcon()
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("width", 512);
HOperatorSet.SetSystem("height", 512);
}
///
/// 初始化Halcon
///
///
public void RunHalcon(HWindowControl Window)
{
HWindowControl = Window;
hv_ExpDefaultWinHandle = Window.HalconWindow;
}
///
/// 设置模板
///
public void SetTemplate()
{
HTuple hv_Row1, hv_Column1, hv_Row2, hv_Column2;
MessageBox.Show("在红框中按下鼠标左键画方框选模板,按右键结束");
HOperatorSet.DrawRectangle1(hv_ExpDefaultWinHandle,
out hv_Row1, out hv_Column1, out hv_Row2, out hv_Column2);
HOperatorSet.GenRectangle1(out ho_Rectangle, hv_Row1, hv_Column1, hv_Row2, hv_Column2);
HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_ImageReduced);
HOperatorSet.WriteImage(ho_ImageReduced, "png", 0, "E:/test.png");
MessageBox.Show("模板已保存");
}
///
/// 从文件中读取模板
///
public void ReadTemplate()
{
HOperatorSet.GenEmptyObj(out ho_ImageReduced);
ho_ImageReduced.Dispose();
HOperatorSet.ReadImage(out ho_ImageReduced, "E:/test.png");
}
///
/// 模板匹配
///
public void MatchTemplate()
{
int i, j;
double temp;
HOperatorSet.GenRectangle1(out ho_Rectangle, 320, 250, 630, 750);
HOperatorSet.ReduceDomain(ho_Image, ho_Rectangle, out ho_Mask);
//Reduce image range
HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(-45)).TupleRad(), (new HTuple(90)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto", out hv_ModelID);
HOperatorSet.CountSeconds(out hv_S1); // Match start
HOperatorSet.FindShapeModel(ho_Mask, hv_ModelID, (new HTuple(-45)).TupleRad(), (new HTuple(90)).TupleRad(), 0.5, 3, 0.0, "least_squares", 0, 0.5, out hv_Row, out hv_Column, out hv_Angle, out hv_Score);
HOperatorSet.CountSeconds(out hv_S2); // Match stop
hv_Runtime = (hv_S2 - hv_S1) * 1000;
usedTime = hv_Runtime;
ResultN = new HTuple(hv_Row.TupleLength());
// 获取匹配结果个数
if (ResultN > 0)
{
Px = new double[ResultN];
Py = new double[ResultN];
hv_R = new HTuple(); //HTuple变量初始化
for (i = 0; i < ResultN; i++)
{
Py[i] = hv_Row[i]; // 将搜索结果的中心坐标读出
Px[i] = hv_Column[i];
Aa.Add(hv_Angle[i]);
hv_R[i] = 8; //设置圆半径
}
for (i = 0; i < ResultN; i++) // 从大到小排序
{
for (j = i + 1; j < ResultN; j++)
{
if (Px[i] < Px[j])
{
temp = Px[i];
Px[i] = Px[j];
Px[j] = temp;
temp = Py[i];
Py[i] = Py[j];
Py[j] = temp;
temp = Aa[i];
Aa[i] = Aa[j];
Aa[j] = temp;
}
}
}
HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red"); // 显示匹配结果位置
HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
HOperatorSet.ClearShapeModel(hv_ModelID);
Cy = Py[0] + 10; // offset的初始值
Cx = Px[0] + 60;
}
else
{
MessageBox.Show("匹配失败!?");
}
}
///
/// 显示偏移点位置
///
public void DisplayOffset()
{
HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red");
HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, hv_Row, hv_Column, hv_R);
HOperatorSet.DispLine(hv_ExpDefaultWinHandle, hv_Row[0], hv_Column[0], hv_Row[1], hv_Column[1]);
HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
HOperatorSet.DispCircle(hv_ExpDefaultWinHandle, Cy, Cx, Cr);
}
///
/// /显示计算角度,划线
///
public void DisplayLine()
{
HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "yellow");
HOperatorSet.DispLine(hv_ExpDefaultWinHandle, Cy, Cx, Fy, Fx);
}
}
5.form1cs页面
public Form1()
{
InitializeComponent();
timer1.Tick += Timer1_Tick;
timer1.Interval = 5000;
this.Controls.Add(hWindowControl1);
hWindowControl1.Location = new System.Drawing.Point(20, 20);
hWindowControl1.Width = 500;
hWindowControl1.Height = 500;
hd.InitHalcon();
}
private void Form1_Load(object sender, EventArgs e)
{
hd.RunHalcon(hWindowControl1); // 摄像头初始化
}
///
/// 打开相机
///
///
///
private void btnOpenCamera_Click(object sender, EventArgs e)
{
hd.OpenCamera();
textBox1.Text = "";
textBox1.Refresh();
}
///
///关闭相机
///
///
///
private void btnCloseCamera_Click(object sender, EventArgs e)
{
hd.CloseCamera();
}
///
/// 匹配
///
///
///
private void btnMatch_Click(object sender, EventArgs e)
{
int j, m;
double d;
double[] x;
double[] y;
hd.MatchTemplate(); // 图像匹配
m = hd.ResultN;
x = new double[m];
y = new double[m];
for (j = 0; j < m; j++) // 获取匹配坐标
{
x[j] = hd.Px[j];
y[j] = hd.Py[j];
}
textBox1.Text = "匹配时间:" + hd.usedTime.ToString("#####.##") + " ms" + "\r\n" + "\r\n";
for (j = 0; j < m; j++)
{
if (j < m - 1) // 计算2点距离
{
d = (y[j + 1] - y[j]) * (y[j + 1] - y[j]) + (x[j + 1] - x[j]) * (x[j + 1] - x[j]);
d = Math.Sqrt(d);
d = 0.0485 * d;
textBox1.Text = textBox1.Text + "d(" + Convert.ToString(j + 1) + ") = " + d.ToString("#####.##")+ "mm" + "\r\n";
}
textBox1.Text = textBox1.Text + "x(" + Convert.ToString(j + 1) + ") = " + Convert.ToString(x[j]) + " y(" + Convert.ToString(j + 1) + ") = " + Convert.ToString(y[j]) + "\r\n" + "\r\n";
}
}
///
/// 设置模板
///
///
///
private void btnTemplate_Click(object sender, EventArgs e)
{
hd.SetTemplate();
}
///
/// 加载模板
///
///
///
private void btnLoadTemplate_Click(object sender, EventArgs e)
{
hd.ReadTemplate();
}
///
/// 实时播放
///
///
///
private void btnPlayback_Click(object sender, EventArgs e)
{
hd.RealTimePlayback();
}
///
/// 显示结果
///
///
///
private void btnDisplayResults_Click(object sender, EventArgs e)
{
double a, b, c, d, m, n;
double alpha, beta;
a = hd.Px[0];
b = hd.Py[0];
c = hd.Px[0];
d = hd.Py[0];
alpha = Math.Atan((d - b) / (c - a));
beta = theta + alpha;
m = a + Lam * Math.Cos(beta);
n = b + Lam * Math.Sin(beta);
textBox1.Text = textBox1.Text + " m = " + Convert.ToString(m) + "\r\n" + "n = " + Convert.ToString(n) + "\r\n" + "alpha = " + Convert.ToString(alpha) + "\r\n" + " theta = " + Convert.ToString(theta) + "\r\n" + " beta = " + Convert.ToString(beta);
hd.Cx = m;
hd.Cy = n;
hd.Fx = m - 600 * Math.Cos(alpha); // 计算夹角斜线的终点坐标
hd.Fy = n - 600 * Math.Sin(alpha);
hd.DisplayOffset(); // 显示插针位置
hd.DisplayLine(); // 显示工件夹角
}
///
/// 拍照
///
///
///
private void btnPhotograph_Click(object sender, EventArgs e)
{
hd.Photograph();
}