霍夫变换检测直线问题,本人C++菜鸟,求各位大神帮助!

chendieric 2012-05-01 04:30:37
本人用VC++编程实现霍夫变换检测直线的问题,但是检测出来的图形一直不清楚,还有很多细小的直线被检测出来,不知道为何,问了指导老师,老师说要要检测连续的共线点,或者设置一个阈值,如果在某条直线上的点的数目大于这个阈值那么就把这条直线画出来,但是本人不知道要将这些代码添加在何处。求各位大神帮帮忙,帮小弟看看这个程序。
以下是代码:
bool CDIB::Hough(SLineInfo *pInfoRet, int nLineRet)
{
int i, j;


// 极坐标域中的最大Rho和Theta
int nMaxDist = sqrt(bih.biHeight*bih.biHeight + bih.biWidth*bih.biWidth);
int nMaxAngle = 90;

// 为极坐标域分配空间
int nAreaNum = nMaxAngle * nMaxDist * 2;
int *pTransArea = new int[nAreaNum];
memset(pTransArea, 0, nAreaNum * sizeof(int));

// 转化到极坐标域
int nAngle, nDist; //极坐标下的角度和极径
double fRadian; //弧度
for(i = 0; i < bih.biHeight; i ++)
{
for(j=0; j<bih.biWidth; j++)
{
if(m_pdata[bih.biWidth*i+j] == 255)
{
for(nAngle = 0; nAngle < nMaxAngle; nAngle ++)
{
fRadian = nAngle*2*PI/180.0; //转化为弧度
nDist = (j*cos(fRadian) + i*sin(fRadian)); //计算极径

if(nDist >= 0)//正半周
{
pTransArea[nDist*nMaxAngle + nAngle] ++;
}
else//负半周
{
nDist = fabs(nDist);
pTransArea[nMaxAngle * nMaxDist + nDist*nMaxAngle + nAngle] ++;
}
}//for nAngle
}//if
}//for j
}//for i


SMaxValue MaxValue1;

//清零时角度和极径的范围
int nMaxDisAllow = 20;
int nMaxAngleAllow = 5;

for(int nLine=0; nLine<nLineRet; nLine++) //寻找前nLineRet个峰值点
{
// 寻找最大点
MaxValue1.nValue = 0;
for(i=0; i<nAreaNum; i++)
{
if(pTransArea[i] > MaxValue1.nValue)
{
MaxValue1.nValue = pTransArea[i];
MaxValue1.nAngle = i;
}
}

if(MaxValue1.nValue == 0) //找不到可能的共线点
{
return FALSE;
}

if(MaxValue1.nAngle < nMaxAngle * nMaxDist)
{
MaxValue1.nDist = MaxValue1.nAngle/nMaxAngle;
MaxValue1.nAngle = MaxValue1.nAngle%nMaxAngle;
}
else
{
MaxValue1.nAngle -= nMaxAngle * nMaxDist;

MaxValue1.nDist = MaxValue1.nAngle/nMaxAngle;
MaxValue1.nDist *= -1;


MaxValue1.nAngle = MaxValue1.nAngle%nMaxAngle;
}

// 将结果保存至pInfoRet结构指针
pInfoRet[nLine].nAngle = MaxValue1.nAngle*2;
pInfoRet[nLine].nDist = MaxValue1.nDist;
pInfoRet[nLine].nPixels = MaxValue1.nValue;

if(pInfoRet[nLine].nDist < 0)
{
pInfoRet[nLine].nAngle = pInfoRet[nLine].nAngle - 180;
pInfoRet[nLine].nDist = pInfoRet[nLine].nDist*(-1);

}

// 将附近点清零,为寻找下一个峰值做准备
for(nDist = (-1)*nMaxDisAllow; nDist <= nMaxDisAllow; nDist ++)
{
for(nAngle = (-1)*nMaxAngleAllow; nAngle <= nMaxAngleAllow; nAngle ++)
{
int nThisDist = MaxValue1.nDist + nDist;
int nThisAngle = MaxValue1.nAngle + 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;
}
}
}//for nAngle
}//for nDist
}//for nLine


delete []pTransArea; //释放极坐标域空间


return TRUE;
}



void CIMAGEPROCESSINGView::OnHough()
{
// TODO: Add your command handler code here

int wide,height;
wide=m_dib.GetDIBWidth();
height=m_dib.GetDIBHeight();
int nLineCount=5;
SLineInfo * pLines = new SLineInfo[nLineCount];


// Hough变换
m_dib.Hough(pLines, nLineCount);

// 输出结果
for (int k = 0; k<nLineCount; k++)//处理第k条直线
{
//扫描图像绘制直线
for(int i = 0; i <height; i++)
{
for(int j = 0;j <wide; j++)
{
int nDist;

//根据theta计算rho
nDist = (int) (j*cos(pLines[k].nAngle*PI/180.0) + i*sin(pLines[k].nAngle*PI/180.0));

if((fabs(nDist - pLines[k].nDist)<=3) && (m_dib.m_pdata[wide*i+j]==255)) //如果点(j, i)在直线上
m_dib.m_pdata[wide*i+j]=100;

}//for j
}//for i
}//for k
for(int i = 0; i <height; i++)
{
for(int j = 0;j <wide; j++)
{
if(m_dib.m_pdata[wide*i+j]!=100)
m_dib.m_pdata[wide*i+j]=0;
else
m_dib.m_pdata[wide*i+j]=255;

}//for j
}//for i

// 将结果返回给文档类
m_dib.UpdateData();
Invalidate();
}

...全文
198 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧