一天从网上下了20个vc的hough代码,没有一个代码是成功的。令人郁闷,我参考matlab代码写出了hough检测单个直线的程序
Hough变换:
本程序是我花费时间最长的程序;参考matlab算法;首先求出原图上的每一个像素在变换域上的对应曲线,即原图上每一点(i,j)对应变换域曲线(p,k);p=(int)(i*cos(pi*k/180)+j*sin(pi*k/180))(0
然后遍历(i,j),累加变换域重复出现的位置,即曲线的交点
然后遍历累加器,寻找交点最大的数据,找出对应的原图坐标,即为所求直线
主要代码
for(i=0;i
{
for(j=0,n=0;n
{ //gray 变量存储rgb转灰度的数据
gray= ((float)(img.image[lineBytes*i+n+2])+(float)(*(img.image+lineBytes*i+n+1))+(float)(*(img.image+lineBytes*i+n)))/3; //lineBytes 原图每行实际字节数
grayPic[i*img.width+j]=(byte)gray;//转换成的灰度图像放在grayPic中
}
}
int logNum; //边缘检测
memset(lpDIBBits,(byte)0,sizeof(byte)*img.height*img.width);
for(i=3;i
for(j=3;j
{
//logNum 变量 记录每次运算的值
logNum=16*grayPic[i*img.width+j]-grayPic[(i-2)*img.width+j]-grayPic[(i-1)*img.width+j-1]-2*grayPic[(i-1)*img.width+j]-grayPic[(i-1)*img.width+j+1]-grayPic[i*img.width+j-2]-2*grayPic[i*img.width+j-1]-2*grayPic[i*img.width+j+1]-grayPic[i*img.width+j+2]-grayPic[(i+1)*img.width+j-1]-2*grayPic[(i+1)*img.width+j]-grayPic[(i+1)*img.width+j+1]-grayPic[(i+2)*img.width+j];//log算子
if(logNum > 0)
lpDIBBits[i*img.width+j]=255;//边缘检测后的数据存放在lpDIBBits中
else
lpDIBBits[i*img.width+j]=0;
}
for(i=1;i
for(j=1;j
{
if(lpDIBBits[i*img.width+j]==255) //对边缘检测后的数据(存在lpDIBBits中)进行hough变化
{
for(k=1;k
{
p=(int)(i*cos(pi*k/180)+j*sin(pi*k/180));//p hough变换中距离参数
p=(int)(p/2+mp/2); //对p值优化防止为负
npp[k][p]=npp[k][p]++; //npp对变换域中对应重复出现的点累加
}
}
}
kmax=0; //最长直线的角度
pmax=0; //最长直线的距离
n=0; //这一部分为寻找最长直线
for(i=1;i
for(j=1;j
{
if(npp[i][j]>yuzhi) //找出最长直线yuzhi为中间变量用于比较
{
yuzhi=npp[i][j];
kmax=i; //记录最长直线的角度
pmax=j; //记录最长直线的距离
}
}
memset(temp,(byte)255,sizeof(byte)*img.width*img.height);//原图中坐标符合kmax和pmax的值
for(i=1;i
for(j=1;j
{
if(lpDIBBits[i*img.width+j]==255)
{
p=(int)(i*cos(pi*kmax/180)+j*sin(pi*kmax/180));//pi=3.1415926
p=(int)(p/2+mp/2); //mp为原图对角线距离
if(p==pmax)
*(temp+i*img.width+j)=0; //存储图像数据 放在temp数组中
}
}
右边是原图,里面有圆和直线,左边是经过hough变换检测出的直线(版权所有 欢迎交流)