在我们截取的感兴趣区域里,我们让找圆工具运行起来:
1, mg_CircleCaliper gaugeCir;//增加变量声明
2, gaugeCir = new mg_CircleCaliper();//form()中初始化
gaugeCir.m_cirRoi.m_RoiCircle.Init(100, 100, 50);
3,在图像控件mousemove事件响应中添加
PointF point = new PointF(e.X, e.Y);
bool status = false;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
status = true;
}
gaugeCir.m_cirRoi.DrawRectFrame(status, point);
this.Cursor = gaugeCir.m_cirRoi.m_cur;
pictureBoxRoiImg.Invalidate(false);
4,在图像控件Paint事件响应中添加
gaugeCir.m_cirRoi.m_RoiCircle.Draw(g, p, gb_dirCirle);
if (m_bclonebuf8 == true)//克隆图像不为空
for (int i = 0; i < gaugeCir.SPLITNUM; i++)
{
PointF[] BackResult = new PointF[9];
PointF[] fnback0 = new PointF[gaugeCir.SPLITNUM];
PointF[] inback = new PointF[gaugeCir.SPLITNUM];
if (i % 2 == 0)//0246区域找穿越点
{
fnback0 = gaugeCir.SPlitPassThroughPointsimprove(ref clonetempbuffer8,
ref BackResult, Convert.ToInt32(tbThresforCirle.Text), gb_dirCirle, new Size(_RoiW, _RoiH),
ref gaugeCir.m_cirRoi.m_RoiCircle.onRadpointOut[i],
ref gaugeCir.m_cirRoi.m_RoiCircle.onRadpointIn[i], ref inback);
//显示出线图像0246区域
for (int iii = 0; iii < 8; iii++)
{
g.DrawLine(new Pen(Color.Pink), inback[iii], fnback0[iii]);
}
}
else//1357区域找穿越点
{
fnback0 = gaugeCir.SPlitPassThroughPointsimprove1357(ref clonetempbuffer8,
ref BackResult, Convert.ToInt32(tbThresforCirle.Text), gb_dirCirle, new Size(_RoiW, _RoiH),
ref gaugeCir.m_cirRoi.m_RoiCircle.onRadpointOut[i],
ref gaugeCir.m_cirRoi.m_RoiCircle.onRadpointIn[i], ref inback);
//显示出线图像1357区域
for (int iii = 0; iii < 8; iii++)
{
g.DrawLine(new Pen(Color.Pink), inback[iii], fnback0[iii]);
}
}
for (int ii = 0; ii < 9; ii++)
{
g.DrawLine(new Pen(Color.Red), BackResult[ii].X, BackResult[ii].Y - 3, BackResult[ii].X, BackResult[ii].Y + 3);
g.DrawLine(new Pen(Color.Red), BackResult[ii].X - 3, BackResult[ii].Y, BackResult[ii].X + 3, BackResult[ii].Y); }
搞定!拖动试试看,有没有发现,他很像我们的眼睛?!调整,在有圆形的地方,样本穿越点(红色的叉叉示意)出来了没?是的,有圆,我们应该把它拟合出来。以下是拟合圆函数:siglecontour样本点,num样本点数,(aa,bb),r是返回圆心,半径
private void fitCircle(List<PointF> siglecontour, int num, ref double aa, ref double bb, ref double r)
{//值大过了银河系,怎么办?
double X1, X2, X3, Y1, Y2, Y3, X1Y1, X1Y2, X2Y1;
double C, D, E, G, H, N;
double a, b, c;
if (num < 3)
{ return; }
X1 = X2 = X3 = Y1 = Y2 = Y3 = X1Y1 = X1Y2 = X2Y1 = 0;
for (int i = 0; i < num; i++)
{
X1 += (siglecontour[i].X - siglecontour[0].X);
X2 += (siglecontour[i].X - siglecontour[0].X) * (siglecontour[i].X - siglecontour[0].X);
X3 += (siglecontour[i].X - siglecontour[0].X) * (siglecontour[i].X - siglecontour[0].X) * (siglecontour[i].X - siglecontour[0].X);
Y1 += (siglecontour[i].Y - siglecontour[0].Y);
Y2 += (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].Y - siglecontour[0].Y);
Y3 += (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].Y - siglecontour[0].Y);
X1Y1 += (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].X - siglecontour[0].X);
X1Y2 += (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].Y - siglecontour[0].Y) * (siglecontour[i].X - siglecontour[0].X);
X2Y1 += (siglecontour[i].X - siglecontour[0].X) * (siglecontour[i].X - siglecontour[0].X) * (siglecontour[i].Y - siglecontour[0].Y);
}
N = num;
C = N * X2 - X1 * X1;
D = N * X1Y1 - X1 * Y1;
E = N * X3 + N * X1Y2 - (X2 + Y2) * X1;
G = N * Y2 - Y1 * Y1;
H = N * X2Y1 + N * Y3 - (X2 + Y2) * Y1;
a = (H * D - E * G) / (1.0 * (C * G - D * D));
b = (H * C - E * D) / (1.0 * (D * D - G * C));
c = -(a * X1 + b * Y1 + X2 + Y2) / (N * 1.0);
aa = -a / 2.0 + siglecontour[0].X;
bb = -b / 2.0 + siglecontour[0].Y;
r = Math.Sqrt(a * a + b * b - 4 * c) / 2.0;
}
找圆工具完成,早期的iphone手机上有个menubutton(home键),他就是圆形的,我们就是通过这种技术给他贴上去的(开玩笑呐!别当真)。
(待续...............)最后看一下效果图: