图像处理(二)霍夫变换的改善
原理:
代码:
void HoughLine(QImage *origin,const int nLineRet, int (*pInfoRet)[3])
{
QColor color;
int ji_count = 0;
//pInfoRet[][0]代表Angle pInfoRet[][1]代表Dist pInfoRet[][2]代表Pixel数;
//极坐标域中最大的Rho和Theta
int nMaxDist = sqrt((double)(origin->height()*origin->height()+origin->width()*origin->width()));
int nMaxAngle = 180;
//分配空间(累加器)
int nAreaNum = nMaxAngle * nMaxDist * 2;
int *pTransArea = new int[nAreaNum];
memset(pTransArea,0,nAreaNum * sizeof(int));
//转化到极坐标域
BYTE bt;
int nAngle,nDist;
double fRadian;
for(int i = 15;i<origin->height();i++)
{
for(int j = 15;j<origin->width();j++)
{
color = QColor(origin->pixel(j, i));
bt = color.red();
if(bt==255)
{
for(nAngle = 0; nAngle<nMaxAngle; nAngle++){
//弧度(0-PI)
fRadian = nAngle*PI/ 180.0;
//计算极径方程
nDist = (j*cos(fRadian) + i*sin(fRadian));
if(nDist>=0)
{
pTransArea[nDist * nMaxAngle + nAngle]++;
}
else
{
nDist = fabs(nDist);
pTransArea[nMaxDist*nMaxAngle + nDist*nMaxAngle + nAngle]++;
}
}
}
}
}
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<<"Max_Value:::"<<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;
}
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;
}
//cout<<"Max_Dist"<<Max_Angle<<endl;
// cout<<"Max_Dist"<<Max_Dist<<endl;
//将结果保存到pInfoRet
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 = 5;
int nMaxAngleAll = 5;
for(int i = 15;i<origin->height();i++)
{
for(int j = 15;j<origin->width();j++)
{
color = QColor(origin->pixel(j, i));
bt = color.red();
if(bt==255)
{
nDist = (int) (j*cos(pInfoRet[nLine][0]*PI/180.0)+i*sin(pInfoRet[nLine][0]*PI/180.0));
if(nDist ==pInfoRet[nLine][1])
{
ji_count++;
}
}
}
}
if(ji_count<200)
{
ji_count = 0;
pInfoRet[nLine][0] = 0;
pInfoRet[nLine][1] = 0;
pInfoRet[nLine][2] = 0;
}else {
ji_count = 0;
}
//将附近点清零。为寻找下一个峰值做准备
for(int Dist = (-1)*nMaxDisAll; Dist <= nMaxDisAll; Dist++ )
{
for(int Angle = (-1)*nMaxAngleAll; Angle <= nMaxAngleAll; Angle++)
{
int nThisDist = Max_Dist + Dist;
int nThisAngle = Max_Angle + Angle;
//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);
//nThisAngle = abs(nThisAngle);
pTransArea[nMaxDist*nMaxAngle + nThisDist*nMaxAngle + nThisAngle] = 0;
}
}
}
}
}
delete []pTransArea;
}