第五篇 机器视觉案例 之 钟表时间识别
1.案例要求
2.实现思路
2.1 设定一个旋转起点,根据每一个指针的旋转角度算出当前的时间
时针每小时旋转30°,分针每分钟旋转6°,秒针每秒钟旋转6°
假设12刻度是旋转起点,时针旋转了90°那么90/30=3,即当前时针指在3点
2.2 可以使用测量线线夹角的工具CogAngleLineLineTool或者点点角工具CogAnglePointPointTool来测量角度
如果使用前者需要获得每一个指针所在的直线,与过钟表圆心的一条线
如果使用后者需要获得每一个指针上的一点,与钟表的原点
2.3 由于控件之间输入输出使用的是弧度,所以需要在代码中将弧度转为角度
3.使用控件
3.1 图像转换工具 —— CogImageConvertTool
3.2 模板匹配工具 —— CogPMAlignTool
模板匹配到分别匹配三个指针
时针:
3.3 找圆工具 —— CogFindCircleTool
找圆工具用来获取钟表的圆心坐标,先用模板匹配匹配到钟表大致位置,再将坐标输入给找圆工具,告诉大致位置
3.4 点点夹角工具 —— CogAnglePointPointTool
3.5 画线工具 —— CogCreateLineTool
画一条过圆心直线
3.6 线线夹角工具 —— CogAngleLineLineTool
图中黄色弧线即为测得角度
4.代码逻辑
4.1 方式一:点点夹角
```csharp
```csharp
CogAnglePointPointTool app1 = mToolBlock.Tools["CogAnglePointPointTool1-时针"]as CogAnglePointPointTool;
CogAnglePointPointTool app2 = mToolBlock.Tools["CogAnglePointPointTool2-分针"]as CogAnglePointPointTool;
CogAnglePointPointTool app3 = mToolBlock.Tools["CogAnglePointPointTool3-秒针"]as CogAnglePointPointTool;
double angleh = app1.Angle;
double angle1 = CogMisc.RadToDeg(angleh);
double anglem = app2.Angle;
double angle2 = CogMisc.RadToDeg(anglem);
double angled = app3.Angle;
double angle3 = CogMisc.RadToDeg(angled);
int hour;
angle1=Math.Ceiling(angle1);
int minute;
angle2 = Math.Ceiling(angle2);
int second;
angle3 = Math.Ceiling(angle3);
if(angle1 <= 180 && angle1 > 0)
{
hour = (int)(angle1 / 30) + 3;
}
else if(angle1<=0&&angle1>=-90)
{
hour = (int) (angle1 / 30) + 3;
if(hour == 0) hour = 12;
}
else
{
hour = (int) (angle1 / 30) + 3+12;
}
if(angle2 <= 180 && angle2 >= -90)
{
minute = (int) (angle2 / 6) + 15;
}
else
{
minute = (int) (angle2 / 6) + 15 + 60;
}
if(angle3 <= 180 && angle3 >=-90)
{
second = (int) (angle3 / 6) + 15;
}
else
{
second = (int) (angle3 / 6) + 15 + 60;
}
label.SetXYText(200,200,hour.ToString()+":"+minute.ToString()+":"+second.ToString());
label.Color = CogColorConstants.Black;
label.Font = new Font("楷体",30);
4.2 方式二:线线夹角
```csharp
CogAngleLineLineTool all1 = mToolBlock.Tools["CogAngleLineLineTool1-时针"] as CogAngleLineLineTool;
CogAngleLineLineTool all2 = mToolBlock.Tools["CogAngleLineLineTool2-分针"] as CogAngleLineLineTool;
CogAngleLineLineTool all3 = mToolBlock.Tools["CogAngleLineLineTool3-秒针"] as CogAngleLineLineTool;
double angle1 = all1.Angle*(180/Math.PI);
double angle2 = all2.Angle*(180/Math.PI);
double angle3 = all3.Angle*(180/Math.PI);
label1.SetXYText(100,50,angle1.ToString("F0") +" "+ angle2.ToString("F0") +" "+ angle3.ToString("F0"));
if(angle1 < 0)
{
angle1 = angle1 + 360;
}
if(angle2 < 0)
{
angle2 = angle2 + 360;
}
if(angle3 < 0)
{
angle3 = angle3 + 360;
}
int hour = (int) (angle1 / 30) % 12;
if (hour == 0) hour = 12;
int minute =(int) (angle2 / 6) % 60;
int second =(int) (angle3 / 6) % 60;
label.SetXYText(200,150,hour.ToString()+":"+minute.ToString()+":"+second.ToString());
label2.SetXYText(100,100,angle1.ToString("F0")+" " + angle2.ToString("F0")+" " + angle3.ToString("F0"));
label.Font = new Font("楷体",50);
label.Color = CogColorConstants.Black;
label1.Font = new Font("楷体", 50);
label1.Color = CogColorConstants.Red;
label2.Font = new Font("楷体", 50);
label2.Color = CogColorConstants.Green;
5.实现效果
5.1 方式一效果图
5.2 方式二效果图
6.知识点总结
6.1 角度转弧度方法
6.1.1 CogMisc.RadToDeg()
6.1.2 弧度*(180/Math.PI)
角度 = 弧度*(180/Π)
ps:C# 中 Π是一个常量 用Math.PI表示
6.2 线线夹角工具与点点夹角工具区别
点点夹角更便利,线线夹角可以更改0点位置
6.3 double类型的向上取整与向下取整
6.3.1 Math.Ceiling() 向上取整
6.3.2 Math.Floor() 向下取整