基于数字图像的矩形芯片定位方法研究与实现
4.4.3 边缘扫描
在最优K获取的情况下对位图进行横向和纵向扫描,多次实验找出最合适的阈值,分别得出矩形边缘所在直线在纵坐标上的截距点。此算法同于求最优K时的扫描算法。由于矩形的横向边和纵向边是互相垂直的,所以在最优K求出之后,横向扫描和纵向扫描时的直线斜率也已经确定,纵向扫描的斜率即为最优K,横向扫描的斜率根据垂直定律和坐标平移原理得出即为-K,此时横向和纵向扫描时的直线斜率均已求出。
1)BH和BW的确定:BW为纵向扫描时需要检测的高度,BH为横向扫描时需要检测高度的起点。
下图为求BW的过程,纵向扫描时,横坐标i为位图高度所在的方向,纵坐标j为位图宽度所在的方向。当一定斜率的纵向扫描线平移到某一高度BW时,这条直线恰好经过位图图像的右上角,此后扫描直线就不用再继续扫描下去。
由直线y=k*i+j经过点(m_height,m_width)可以求出此时在纵坐标上的截距:
BW=abs(m_width-int(k*m_height));如图4.6所示。
同理也可以求出横向扫描时的BH:BH=abs(int(k*m_width));
j 扫描直线 BW m_width i m_height 图4.6 边缘扫描算法图示
2)阈值确定所做的试验:不断尝试赋值给阈值,设断点查看运行结果,直到阈值满足所需的边缘时确定出此时的阈值。
3)最后当扫描的直线恰好经过矩形芯片的边缘时,此时灰度和突然增大,与所设定的阈值比较,得出此时在纵坐标上的截距,并返回此时的截距。 4)简要代码实现:纵向扫描时:(最优K已确定) for(j=1;j 17 基于数字图像的矩形芯片定位方法研究与实现 { for(i=1;i x=float(k*i+j); //纵向扫描时的直线方程 x1=int(x); x2=int(x)+1; m_check1[j]=0.0f; { float x,r; r=x-x1;//r为lameda p=m_buffer+((m_height-i)*m_width+x1)*bytes;//灰度值 if(x1>=0 && x1< m_width) //保证x1在0和m_width之间 T1=0; T1 +=(1-r)*(*p); if(x2>=0 && x2< m_width) m_check1[j]+=T1; p=m_buffer+((m_height-i)*m_width+x2)*bytes;//灰度值 T1 +=r*(*p);//直线上的灰度值之和 } } YU1=m_check1[15];//阈值一 { } if(m_check1[j]>YU1) f2=j; for(j=1;j return (f2);//截距点 横向扫描时:最优K一定后,横向扫描的斜率根据垂直定律和坐标平移原理得出即为-K。 所以此时扫描时的直线设为y=-k*i+j; for(j=BH;j for(i=1;i y=float(j-k*i); //纵向扫描时的直线方程 y1=int(y); y2=int(y)+1; m_check2[j]=0.0f; { float y,s; s=y-y1;//s为lameda p=m_buffer+((m_height-y1)*m_width+i)*bytes;//灰度值 if(y1>0 && y1< m_height) 18 T2=0; 基于数字图像的矩形芯片定位方法研究与实现 } } T2 +=(1-s)*(*p); if(y2>0 && y2< m_height) T2 +=s*(*p);//直线上的灰度值之和 m_check2[j] +=T2; p=m_buffer+((m_height-y2)*m_width+i)*bytes;//灰度值 YU2=m_check2[BH];//阈值二 for(j=BH;j if(m_check2[j]>YU2) f3=j; return (f3);//截距点 说明:当然阈值的确定是个很难的过程,在横向扫描和纵向扫描的算法弄明白以后,需要一步步的进行实验来确定阈值,在这个过程中,我尝试过很多方法,为了避免过大的误差,只能一步步的代入接近边缘的灰度值,对不同的图像进行试验,最终会得到一个比较适合的阈值。 4.4.4边界提取方案 1)在得到矩形边缘所在直线在纵坐标上的截距点后,根据已知的斜率,由点斜式公式在OnDraw函数中画出矩形的边。 m_top=LSUM(); m_left=HSUM(); 2)简单代码如下: OnDraw() { pDC->MoveTo(m_top,0); //画出已知的一条纵向直线,为矩形的一条边 pDC->LineTo(int(k*m_height+m_top),m_height); pDC->MoveTo(m_top-238,0);//在离已知纵向直线固定距离处画平行的另外一条边 pDC->LineTo(int(k*m_height+m_top-238),m_height); pDC->MoveTo(0,m_left); 画出已知的一条横向直线,为矩形的一条边 pDC->LineTo(m_width,int(m_left-(k*m_width))); pDC->MoveTo(0,m_left-380); 在离已知纵向直线固定距离处画平行的另外一条边 pDC->LineTo(m_width,int(m_left-380-(k*m_width))); } 说明: 此时固定数值238与380为矩形芯片图像的宽度和长度。通过平行原理,根据其中一条 19 基于数字图像的矩形芯片定位方法研究与实现 边已确定求出平行于矩形芯片的另一条边,这是矩形芯片的形状优势所在。3)边界直线如图4.6所示: 图4.7边缘检测后的图像显示 4.5 矩形芯片偏角的计算 1)最优K求出以后,根据斜率与角度的数学关系求出该位图的偏角: 偏角= atan(斜率)*180/3.14 并通过MessageBox输出结果 2)伪代码如下: degree=int(atan(k)*180/3.14);//偏角 str2.Format(\该矩形芯片的偏角为 %d 度.\MessageBox(str2); 3)边缘检测后,点击偏角即得如图4.7所示的对话框,输出该位图的偏角。 图4.8 偏角对话框 20 基于数字图像的矩形芯片定位方法研究与实现 4.6 矩形芯片中心坐标的计算 1)在已知斜率和截距点的前提下,求出平行于矩形两长边并且截距等于两长边在纵坐标上的截距之差的1/2时的直线,同理,再求出平行于矩形两短边并且截距等于两短边在纵坐标上的截距之差的1/2时的直线,两条直线的方程形成方程组,求出两直线的交点,即为矩形芯片的中心坐标。 由方程组1.y=k*x+ H_ju 2.x=k*y+ L_ju 得出的(x,y)即为中心坐标即(H_center,L_center) 2)伪代码如下 int H_ju,L_ju,H_center,L_center; Get_top_left(); H_ju=m_top-238/2; L_ju=m_left-380/2; k_no = OptimalK(m_check); k=float(-0.2f+k_no*float(DELTA_K)); H_center=int((k/(k*k+1))*L_ju+(1/(k*k+1))*H_ju); L_center=int((-k)*H_center+L_ju); str1.Format(\该矩形芯片的中心坐标 ( %d , %d ).\ MessageBox(str1); 3)边缘检测后,点击中心坐标即得如图4.8所示的对话框,输出该位图的中心坐标。 图4.9 中心坐标对话框 4.7 功能总结 本课题的算法是通过扫描位图信息,得到矩形芯片边缘的四条直线,由这四条规则的 直线可以得出中心坐标和夹角,是一个方便而又有效的算法。当然其中也不乏有阈值确定时的误差,需要大量的实验验证才能精确,同时阈值设定的算法很简单,仍需改进。总的来说,本算法实现了任务预期的结果,达到了最终的目的。 21