霍夫直线检测算法
void MainWindow::Hough(QImage *origin,const int nLineRet, int (*pInfoRet)[3])
{
QColor color;
//pInfoRet[][0]代表Angle pInfoRet[][1]代表Dist pInfoRet[][2]代表Pixel数;
//int pInfoRet [nLineRet][3];
//极坐标域中最大的Rho和Theta
int nMaxDist = sqrt((double)(origin->height()*origin->height()+origin->width()*origin->width()));
int nMaxAngle = 90;
//分配空间(累加器)
int nAreaNum = nMaxAngle * nMaxDist * 2;
int *pTransArea = new int[nAreaNum];
memset(pTransArea,0,nAreaNum * sizeof(int));
//转化到极坐标域
BYTE bt;
int nAngle;
int nDist;
double fRadian;
for(int i = 0;i<origin->height();i++)
{
for(int j = 0;j<origin->width();j++)
{
color = QColor(origin->pixel(j, i));
bt = color.red();
if(bt>100)
{
for(nAngle = 0; nAngle<nMaxAngle; nAngle++){
//弧长(0-PI)
fRadian = nAngle*PI*2 / 180.0;
//计算极径方程
nDist = (j*cos(fRadian) + i*sin(fRadian))+0.5;
if(nDist>=0)
{
pTransArea[nDist * nMaxAngle + nAngle]++;
}
else
{
nDist = fabs(nDist);
pTransArea[nMaxDist*nMaxAngle + nDist*nMaxAngle + nAngle]++;
}
}
}
}
}
//
cout<<"pTransArea[0]"<<pTransArea[0]<<endl;
cout<<"pTransArea[45]"<<pTransArea[45]<<endl;
int Max_Angle = 0;
int Max_Dist = 0;
for(int nLine = 0; nLine < nLineRet; nLine++)
{
int Max_Value = 0;
//寻找最大点
for(int i = 0; i < nAreaNum; i++)
{
if(pTransArea[i]>Max_Value)
{
Max_Value = pTransArea[i];
Max_Angle = i;
cout<<"pTransArea[i]"<<Max_Value<<endl;
cout<<"Max_Angle"<<Max_Angle<<endl;
}
}
if(Max_Value == 0)
{
return ;
}
if(Max_Angle < nMaxAngle*nMaxDist)
{
// Max_Angle = nDist * nMaxAngle + nAngle
Max_Dist = Max_Angle / nMaxAngle;
Max_Angle = Max_Angle % nMaxAngle;
cout<<"Max_Dist Max_Angle"<<Max_Angle<<endl;
cout<<"Max_Dist"<<Max_Dist<<endl;
}
else {
//Max_Angle = nMaxDist*nMaxAngle + nDist*nMaxAngle + nAngle
Max_Angle -= nMaxAngle * nMaxDist;
Max_Dist = Max_Angle / nMaxAngle;
Max_Dist *= -1;
Max_Angle = Max_Angle % nMaxAngle;
}
//将结果保存到pInfoRet
cout<<"Max_Value"<<pInfoRet[nLine][1]<<endl;
pInfoRet[nLine][0] = Max_Angle;
pInfoRet[nLine][1] = Max_Dist;
pInfoRet[nLine][2] = Max_Value;
if(pInfoRet[nLine][1]<0)
{
pInfoRet[nLine][0] = pInfoRet[nLine][0] - 180;
pInfoRet[nLine][1] = pInfoRet[nLine][1] * (-1);
}
int nMaxDisAll = 20;
int nMaxAngleAll = 5;
//将附近点清零。为寻找下一个峰值做准备
for(nDist = (-1)*nMaxDisAll; nDist <= nMaxDisAll; nDist++ )
{
for(nAngle = (-1)*nMaxAngleAll; nAngle <= nMaxAngleAll; nAngle++)
{
int nThisDist = Max_Dist + nDist;
int nThisAngle = Max_Angle + nAngle;
nThisAngle *= 2;
if(nThisAngle < 0 && nThisAngle >= -180)
{
nThisAngle += 180;
nThisDist *= -1;
}
if(nThisAngle >= 180 && nThisAngle < 360)
{
nThisAngle -= 180;
nThisDist *= -1;
}
if(fabs(nThisDist) <= nMaxDist && nThisAngle >= 0 && nThisAngle <= nMaxAngle*2)
{
nThisAngle /= 2;
if(nThisDist >= 0)
{
pTransArea[nThisDist*nMaxAngle + nThisAngle] = 0;
}
else {
nThisDist = fabs(nThisDist);
pTransArea[nMaxDist*nMaxAngle + nThisDist*nMaxAngle + nThisAngle] = 0;
}
}
}
}
}
delete []pTransArea;
}
调用:
BYTE bt;
for(int k = 0; k < 12; k++)
{
if(abs(pInfoRet[k][1])<30)
{
continue;
}
if(abs(pInfoRet[k][1])>500 && pInfoRet[k][0] == 0) continue;
//cout<<"Dist"<<pInfoRet[k][1]<<""<<"Angle:"<<pInfoRet[k][0]<<endl;
for(int i = 5; i<SobelIma.height()-5; i++)
{
for(int j = 5; j<SobelIma.width()-5; j++)
{
int nDist;
oldColor = QColor(SobelIma.pixel(j,i));
bt = oldColor.red();
if(bt<10)
{
continue;
}
nDist = (int) (j*cos(pInfoRet[k][0]*PI/180.0)+i*sin(pInfoRet[k][0]*PI/180.0)+0.5);
if(nDist == pInfoRet[k][1])
{
for(int h = -1 ; h<1;h++){
for(int w = -1;w<1;w++){
houghline.setPixel(j+w,i+h, qRgb(255, 255, 255));
}
}
}
}
}
}