在平面直角坐标系中,直线可以用y=k*x + b表示,在下图中,如果假设以O为原点,x轴为极坐标轴,并且OA与极坐标轴的夹角为,那么点A可由极坐标表示,经过一系列公式转换可得,任意一组可以确定一条直线,检测直线主要是以下几步:
1)建立一个二维数组houghbuf[360][p],其中p的长度为图像对角线长度(对应着),其中360°(对应着)
2)循环遍历图像的坐标(x,y)的时候,也同时由0-360取值遍历,并代入公式,根据来累加(1)中的二维数组,同一条线上的点,会被累加到一起
3)取阈值,有多少个点在一条线上,则认为这是一条线
//先用边缘检测生成图像,再hough变换
QImage* MainWindow:: HoughLine(QImage* image)
{
double sinValue[360];
double cosValue[360];
int k = 100;
double scale=1;
int p = (int)(sqrt(double(image->width()*image->width() + image->height()*image->height())+1));
QImage* newImage = new QImage(360,p,QImage::Format_ARGB32);
QColor color;
int houghbuf[360][p];
memset(houghbuf,0,sizeof(int)*360*p);//必须清0
for(int i = 0;i<360;i++)
{
sinValue[i] = sin(i*3.1415926/180);
cosValue[i] = cos(i*3.1415926/180);
}
int tp;
for(int y =0;yheight();y++)
{
for(int x =0;xwidth();x++)
{
color = QColor(image->pixel(x,y));
for(int i = 0;i<360;i++)
{
if(color.red() > k)
{
tp = (int)(x*sinValue[i] + y*cosValue[i]);
if(tp<0||houghbuf[i][tp]==255) continue;
houghbuf[i][tp]+=scale;
}
}
}
}
for(int i = 0;i<360;i++)
{
for(int j = 0;jsetPixel(i,j,qRgb(houghbuf[i][j],houghbuf[i][j],houghbuf[i][j]));
}
}
return newImage;
}
//先用边缘检测生成图像,接着hough变换,再滤波,最后画出直线 ,其中k1取值3000
QImage* MainWindow:: DrawLine(QImage* image,QImage* image1,int k1)
{
double sinValue[360];
double cosValue[360];
int k = 100;
double scale=1;
int p = (int)(sqrt(double(image->width()*image->width() + image->height()*image->height())+1));
QImage* newImage = new QImage(360,p,QImage::Format_ARGB32);
QColor color;
int houghbuf[360][p];
memset(houghbuf,0,sizeof(int)*360*p);//必须清0
for(int i = 0;i<360;i++)
{
sinValue[i] = sin(i*3.1415926/180);
cosValue[i] = cos(i*3.1415926/180);
}
int tp;
for(int y =0;yheight();y++)
{
for(int x =0;xwidth();x++)
{
color = QColor(image->pixel(x,y));
for(int i = 0;i<360;i++)
{
if(color.red() > k)
{
tp = (int)(x*sinValue[i] + y*cosValue[i]);
if(tp<0||houghbuf[i][tp]==255) continue;
houghbuf[i][tp]+=scale;
}
}
}
}
for(int i = 0;i<360;i++)
{
for(int j = 0;jsetPixel(i,j,qRgb(houghbuf[i][j],houghbuf[i][j],houghbuf[i][j]));
}
}
int tmplt[5][5]={
{-2,-2,-2,-2,-2},
{-2,0,4,0,-2},
{-2,4,16,4,-2},
{-2,0,4,0,-2},
{-2,-2,-2,-2,-2}
};
int templtsize = 5;
double kk,bb;
int xx,yy;
for(int x = 0;x<360;x++)
{
for(int y= 0;y
pixel(px1,py1));
r+=color.red()*tmplt[i][j];
g+=color.green()*tmplt[i][j];
b+=color.blue()*tmplt[i][j];
}
}
if(r>k1)
{
if(x!=90)
{
bb = y/cos(x*3.1415926535/180);
kk = -sin(x*3.1415926535/180)/cos(x*3.1415926535/180);
yy =0;
xx =0;
if(abs(kk)<=1)
{
for(xx =0;xxwidth();xx++)
{
yy=(int)(kk*xx+bb);
if(yy>=0 && yyheight())
{
r = 255;
g = 0;
b = 0;
image1->setPixel(xx,yy,qRgb( r,g,b));
}
}
}
else
{
for(yy =0;yyheight();yy++)
{
xx=(int)(yy/kk - bb/kk);
if(xx>=0 && xxwidth())
{
r = 255;
g = 0;
b = 0;
image1->setPixel(xx,yy,qRgb( r,g,b));
}
}
}
}
else
{
for(yy=0;yyheight();yy++)
{
r = 255;
g = 0;
b = 0;
image1->setPixel(x,yy,qRgb( r,g,b));
}
}
}
}
}
delete newImage;
return image1;
}
数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去