目录
一、前言
二、识别圆,并进行圆拟合的方法
三、程序代码
四、结果显示
一、前言
在边缘检查1.0中使用了MIL中自动边缘检查,将没有形成闭环和圆环内的边缘剔除,只剩下圆环外完整的边缘。
二、识别圆,并进行圆拟合的方法
目标是获取该圆的特征,并使用圆拟合,最终使得图像显示该圆拟合结果。
想要实现拟合结果,首先需要使用Edge Finder 将相关参数进行添加,添加完成后进行计算,计算完成后找到需要显示的圆拟合后的圆,并将它与其他圆拟合出的圆的参数进行对比,找出不同。通过找出相关的不同参数,最后使得程序运行后只显示需要显示的圆拟合后的圆。
本次使用的是M_CIRCLE_FIT_RADIUS,这个是圆拟合后圆的半径像素,通过在Edge Finder中找到需要显示的圆拟合后的圆的半径像素在170至180之间,并且在次区间并没有其他圆拟合后的圆符合,于是使用M_CIRCLE_FIT_RADIUS进行判断。
与边缘检测1.0不同的是本次 MedgeControl() 的第二个参数设置为了M_CIRCLE_FIT,这个参数是圆拟合设置,通过设置圆拟合后,在计算时才会使用圆拟合计算。
MIL.MedgeControl(MilEdgeContext, MIL.M_CIRCLE_FIT, MIL.M_ENABLE);
圆拟合设置后,需要设置M_CIRCLE_FIT_RADIUS,通过设置MedgeControl() 的第二个参数设置为了M_CIRCLE_FIT_RADIUS,在最后才能剔除不需要的圆拟合后的圆。
MIL.MedgeControl(MilEdgeContext, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_ENABLE);
将图像上所有的特征都进行圆拟合计算后,使用 MedgeSelect() 剔除不需要的圆。
M_EXCLUDE是排除满足指定条件的边
M_CIRCLE_FIT_RADIUS是选择对应的参数
M_LESS是小于
M_GREATER是大于
最后两个参数就是设置对应参数的值
MIL.MedgeSelect(MilEdgeResult, MIL.M_EXCLUDE, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_LESS, 170,MIL.M_NULL);
MIL.MedgeSelect(MilEdgeResult, MIL.M_EXCLUDE, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_GREATER, 180, MIL.M_NULL);
将圆拟合后的结果显示在图像上使用 MedgeDraw() 将显示的边缘设置为M_DRAW_CIRCLE_FIT
MIL.MedgeDraw(MIL.M_DEFAULT, MilEdgeResult, GraphicList, MIL.M_DRAW_CIRCLE_FIT, MIL.M_DEFAULT, MIL.M_DEFAULT);
三、程序代码
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;
using Matrox.MatroxImagingLibrary;
namespace EdgeFindEasyNew
{
public partial class Form1 : Form
{
private const string CONTOUR_IMAGE = "D:/Pic/EdgeFind/Easy.bmp";
private static readonly int CONTOUR_DRAW_COLOR = MIL.M_COLOR_GREEN;
private static readonly int CONTOUR_LABEL_COLOR = MIL.M_COLOR_RED;
MIL_ID MilApplication = MIL.M_NULL; //程序标识符
MIL_ID MilSystem = MIL.M_NULL; //系统标识符
MIL_ID MilDisplay = MIL.M_NULL; //显示标识符
MIL_ID MilImage = MIL.M_NULL; //图像缓存区标识符
MIL_ID GraphicList = MIL.M_NULL; //图形列表标识符
MIL_ID MilEdgeContext = MIL.M_NULL; //上下文标识符
MIL_ID MilEdgeResult = MIL.M_NULL; //边缘缓冲区标识符
double EdgeDrawColor = CONTOUR_DRAW_COLOR; //边缘颜色标识符
double LabelDrawColor = CONTOUR_LABEL_COLOR; //标签颜色标识符
double MeanFeretDiameter ;//平均直径数组
double CircleC;
int ox = 760;
int oy = 385;
int x = 400;
int y = 375;
public Form1()
{
InitializeComponent();
MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);
}
public void EdgeFind()
{
MIL.MbufRestore(CONTOUR_IMAGE, MilSystem, ref MilImage);
MIL.MdispSelectWindow(MilDisplay, MilImage, this.panel1.Handle);
MIL.MdispControl(MilDisplay, MIL.M_SCALE_DISPLAY, MIL.M_ENABLE);
MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref GraphicList);
MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList);
MIL.MedgeAlloc(MilSystem, MIL.M_CONTOUR, MIL.M_DEFAULT, ref MilEdgeContext);
MIL.MedgeAllocResult(MilSystem, MIL.M_DEFAULT, ref MilEdgeResult);
MIL.MedgeControl(MilEdgeContext, MIL.M_CIRCLE_FIT, MIL.M_ENABLE);
MIL.MedgeControl(MilEdgeContext, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_ENABLE);
MIL.MedgeControl(MilEdgeContext, MIL.M_FERET_MEAN_DIAMETER + MIL.M_SORT1_DOWN, MIL.M_ENABLE);
MIL.MedgeCalculate(MilEdgeContext, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MilEdgeResult, MIL.M_DEFAULT);
//删除不需要的圆拟合
MIL.MedgeSelect(MilEdgeResult, MIL.M_EXCLUDE, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_LESS, 170,MIL.M_NULL);
MIL.MedgeSelect(MilEdgeResult, MIL.M_EXCLUDE, MIL.M_CIRCLE_FIT_RADIUS, MIL.M_GREATER, 180, MIL.M_NULL);
MIL.MgraColor(MIL.M_DEFAULT, EdgeDrawColor);
MIL.MedgeDraw(MIL.M_DEFAULT, MilEdgeResult, GraphicList, MIL.M_DRAW_CIRCLE_FIT, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.MedgeGetResult(MilEdgeResult, MIL.M_DEFAULT, MIL.M_FERET_MEAN_DIAMETER, ref MeanFeretDiameter);
MIL.MedgeGetResult(MilEdgeResult, MIL.M_DEFAULT, MIL.M_CIRCLE_FIT_RADIUS, ref CircleC);
textBox1.AppendText(" FeretD:" + MeanFeretDiameter + "\r\n");
textBox1.AppendText(" CircleD:" + CircleC * 2 + "\r\n");
}
public void ClearBuffer()
{
//释放资源
MIL.MgraFree(GraphicList);
MIL.MedgeFree(MilEdgeContext);
MIL.MedgeFree(MilEdgeResult);
MIL.MbufFree(MilImage);
MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
}
public void Form_Close(object sender, EventArgs e)
{
ClearBuffer();
}
private void button1_Click(object sender, EventArgs e)
{
EdgeFind();
button1.Enabled = false;
}
}
}
四、结果显示
参考MIL Help