基于数字图像的矩形芯片定位方法研究与实现
边缘检测 最优K的计算 纵向扫描 横向扫描 画出边缘直线 图4.2子模块 4.2 界面设计
本设计是在VC 6.0的编程环境下实现的,在MFC Appwizard[exe]中创建一个新的单文档实现图像的打开和读取。然后在编辑栏下添加边缘检测等菜单,并做相应的消息映射。界面如图4.3:
图4.3 界面显示
12
基于数字图像的矩形芯片定位方法研究与实现
4.3 矩形芯片图像的获取
4.3.1 灰度图简介
本文主要研究BMP灰度图, 灰度图(Grayscale)是指只含亮度信息,不含色彩信息的图像,就像我们平时看到亮度由暗到明的黑白照片,亮度变化是连续的,因此要表示灰度图,就需要把亮度值进行量化,通常划分为0-255共256个级别,0最暗,255最亮。 BMP格式的文件可以用256色的调色板来表示灰度图,只不过这个调色板有点特殊,每一个RGB值都是相同的,也就是RGB值从(0,0,0)一直到(255,255,255)。灰度图使用比较方便,首先RGB值都一样,其次图像数据即调色板索引值,也就是实际的RGB的亮度值。
4.3.2 矩形芯片的读取与显示
1)本矩形芯片的图像是典型的256色bmp文件格式,芯片图像的读取是在CBmp256Doc文件的Serialize函数中,通过ar.Write函数和ar.Read函数来读取图像的位图文件头、位图信息头、颜色表和位图数据本身。
ar.Write(m_buffer,m_InfoHeader->biWidth*m_InfoHeader->biHeight)为位图分配一定空间的缓冲区。
2)在CBmp256View文件中,如果缓冲区不为空,通过OnDraw函数调用ShowBuffer函数把缓冲区中的图像显示在内存设备环境中。 if(pDoc->m_buffer!=NULL)
{
}
m_height=pDoc->m_InfoHeader->biHeight; m_width=pDoc->m_InfoHeader->biWidth; m_buffer=pDoc->m_buffer
m_InfoHeader=pDoc->m_InfoHeader; ShowBuffer(0,0);//调用函数
3)图像信息显示出来后,在CBmp256View文件中设计一OnMouseMove函数,通过指针*p计算出任一点处的RGB值,并显示出任一点处的(x, y)坐标及对应的RGB值。 bytes=m_InfoHeader->biBitCount/8;
p=m_buffer+((m_height-point.y)*m_width+point.x)*bytes;//灰度值
13
基于数字图像的矩形芯片定位方法研究与实现
if(bytes==1)//如果是8位灰度图,就输出灰度值
sprintf(message,\位 if(bytes==3)//如果是24位灰度图,就输出RGB值
sprintf(message,\
point.x,point.y,*(p+2),*(p+1),*p);//24位
4)图像显示如图4.4
图4.4 读入图像显示
说明:因为实验的图像为24位bmp位图,图像下方的x, y, R, G, B值均根据鼠标的移动在不断变化,同时,当鼠标移动到位图外时,只显示(x, y)坐标信息。
4.4
矩形芯片边缘检测的设计
本课题的边缘检测分为以下几个部分:
(1)最优K的求取,根据最优K进行横向扫描和纵向扫描,得到边缘直线
14
基于数字图像的矩形芯片定位方法研究与实现
(2)根据直线斜率得出芯片与水平线的偏角
(3)根据四条边缘直线方程计算得出位图的中心坐标。 4.4.1 边缘检测算法的设计思路
考虑到本图像中芯片的形状是矩形,在图像任一点的灰度值已经求出的前提下,把对图像的扫描分为横向扫描和纵向扫描,横向扫描时,从原点开始做固定斜率且互相平行的直线,该直线在y轴上的截距是逐渐加1变化的,当直线恰好扫描到矩形芯片的边缘时,此时该直线上的所有像素点的灰度值的和变化最大,此时可以确定该直线,得到边缘所在直线在y轴上的截距,以便于后面的边缘提取。纵向扫描时的边缘检测原理同理于横向扫描。
1)在求直线上像素点之和的时候,需要注意有时候直线经过的点并不是像素点,此时需要求出该直线之上的像素点值和直线之下的像素点,并通过一定得比例(lameda)相加求出该点的灰度值。
即:p=m_buffer+((m_height-i)*m_width+x1)*bytes;//灰度值 T1 +=(1-r)*(*p);
p=m_buffer+((m_height-i)*m_width+x2)*bytes;//灰度值
T1 +=r*(*p);
check[m][j]+=T1; //直线上的灰度值之和
此时所求的才是直线式的灰度之和,r就为lameda,是通过r=fabs(x-x1)求得。 2)下面为对于不同斜率的直线在横向扫描时所得的直线上的灰度值之和:
for(m=1;m<=K_NUM;m++)
{
k=float(-0.2f+m*float(DELTA_K)); for(j=1;j for(i=1;i x=float(k*i+j); //扫描时的直线方程 x1=int(x); x2=int(x)+1; check[m][j]=0.0f; r=fabs(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 p=m_buffer+((m_height-i)*m_width+x2)*bytes;//灰度值 T1 +=r*(*p); check[m][j]+=T1; //直线上的灰度值之和 15 基于数字图像的矩形芯片定位方法研究与实现 } } } 最后得到的是不同斜率下,不同截距的直线上的灰度值的和。 4.4.2 边缘检测最优斜率K的计算 在边缘检测时最重要的工作是求出扫描时直线的斜率,最优斜率K的计算思路是: 首先设K在-0.2和0.2之间变动,每次移动0.01,同样是设不同截距的直线扫描,得到不同K值、不同截距下的直线上的灰度值的和。然后根据差分法求出灰度和变化最大的k值就是最优K。 1)不同斜率下,不同截距的直线上的灰度值的和求出之后,通过差分法(即前一像素和减去后一像素和)来比较,求出像素和变化最大的点,此时所返回的k_num就是最优k所需要的。 2)对于不同的k值都对应一系列的灰度和,如下图所示,当所有的K值对应的灰度和都求出来之后,用差分法求出灰度和变化最大的点,即为最优K值所对应的点。 灰度和的差d=check[m][j]- check[m][j-1],求d最大时的值。 j 变化最大的地方 灰度和的变化曲线 0 图4.5 灰度和的变化曲线 3)差分法求导过程如下: for(m=1;m<=K_NUM;m++) { } i for(j=3;j { d=float(fabs(fabs(check[m][j])-fabs(check[m][j-1])));//差分 if(max_grad < d) { max_grad = d;//所有灰度差的最大值 a=m;//存灰度值最大时的K_NUM b=j; } } return (a);//返回最优K所对应的m值,即K_NUM 16