实验项目1甲骨文字形特征点提取方法
一 实验目的
1了解甲骨文字形的特征。
2利用平面上两矢量夹角公式提取甲骨文字形特征点。
二 实验要求
1实验前,配置好Visual C++ 6.0开发环境。
2准备好测试用的BMP格式甲骨文字形图片。
三 实验内容
1使用反余弦函数计算出当前点与左右相邻点的夹角大小,其夹角不大于某个给定的值α的点就被认为是特征点。我们注意到,通过计算轮廓线上当前点与左右相邻点的夹角大小可以判断轮廓线在该点的弯曲程度。对于一个曲线序列Cn上相邻的三个点Pi-1,Pi,Pi+1,设线段Pi-1 Pi和Pi Pi+1之间的夹角,则平面上两矢量Pi-1 Pi和Pi Pi+1夹角的计算公式为:
(1)
然后使用反余弦函数求出的大小,这里求出的是弧度制的角,为了比较的方便,将它们转换为角度制的角。
2夹角等于0(当夹角等于180度时,也是如此)或者接近于0时,那么就可以认为Pi-1,Pi和Pi+1三点在一条直线上或者近似于在一条直线上,那么Pi就不可能是特征点,可以把它给过滤掉;当它们的夹角是一个锐角、直角或者是一个角度稍小一点的钝角时,则轮廓线在Pi处弯曲得就比较厉害,那么该点就有可能认为是一个特征点;当它们的夹角是一个较大的钝角时,轮廓线在Pi处看起来就比较平缓,那么该点很有可能不是一个特征点。通过以上分析,通过判断轮廓线上每个点角的大小来确定轮廓线的弯曲程度,进而可以求出特征点。
3从当前点开始,顺序探测当前点和左右相邻点夹角的大小,然后对这些角度求平均值的方法,求出当前点的角度值。例如对于曲线上的点序列Cn,设当前点为Pi,它左边序列上的点分别设为Pi-1,Pi-2,Pi-3,…,右边序列上的点设为Pi+1,Pi+2,Pi+3,…,需要求的角度分别是直线段PiPi-1与Pi Pi+1,Pi Pi-2与Pi Pi+2,…,的夹角的大小,然后再对这些夹角求平均值作为当前点Pi所在曲线上的角度值。
4从起始点开始,设置一个变量记录曲线点的个数,判断变量的值,如果等于给定的某个值,即使没有新的特征点出现,也要增加一个新的特征点,以适应缓慢弯曲的较长曲线,同时将变量清0。当遇到一个新的特征点时,将该变量清0,然后继续进行上述判断。
设曲线上任意的三个点为:A(x0,y0),B(x1,y1),C(x2,y2),设线段AB和线段BC之间的夹角为,根据公式(1)得到求
角的坐标公式:
(2)
再利用函数acos求出的值。
算法:计算曲线上各个点角的大小
对于一条闭合轮廓线,设变量number,将该轮廓线上的点的个数存放在number中,创建数组angle[number],并对其进行初始化,该数组用来存放曲线上每个点角的度数。定义变量:V1,V2,V3,Angle。
for(j=0;j<10;j++)
{
for(i = 0; i < number; i++)
{V1 = (i + number - j) % number;
V2 = i;
V3 = (i + j) % number;
Angle= getVectorAngle(&V1, &V2,& V3);
if(Angle == 0)
Angle = 180.0;
angle[i] += Angle;
}
}
for(i = 0; i < number; i++)
{angle[i]/= 10; }
//计算角度
getVectorAngle(Point *iv1, Point *iv2, Point *iv3)
{
Point v1, v2;
v1.x = iv2.x - iv1->x;
v1.y = iv2.y - iv1->y;
v3.x = iv2.x – iv3->x;
v3.y = iv2.y – iv3->y;
double l_ct,l_nt,dot;
doublealpha;
l_ct=sqrt(v1.x * v1.x + v1.y * v1.y);
l_nt=sqrt(v2.x * v2.x + v2.y * v2.y);
dot=v1.x * v2.x + v1.y * v2.y;
alpha=acos(dot/(l_ct*l_nt));
alpha=alpha*180.0/3.14159;
return alpha;
}
//判断是否为特征点
BOOL Control[number];//用来标记曲线上各个点是否为特征点
for(i = 0; i < number; i++)
{Control [i]= FALSE;}
for(i = 0; i < number; i++)
{
if(angle[i]< SMALLANGLE)
{ Control [i]=TRUE; }
}
//在一段缓慢弯曲得较长曲线上增加一个额外的特征点
intaa;
aa=0;
for(i = 0; i < number; i++)
{if(Control [i]= =TRUE)
aa=0;
else
{aa++;
if(aa = = 40)
{ Control [i] = TRUE; aa=0; }
}
}
图1 使用特征点提取算法得到的图形
四 课后思考
1 请写出平面上两矢量夹角公式。
2如何利用夹角公式判定特征点?