霍夫变换检测连续共点直线问题,求各位大神帮助!

时间:2021-06-15 15:17:20
本人用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();
}

7 个解决方案

#1


太长了,不高兴看,你看一下hough变换的原理。你检测出来的直线应该能够统计出一共经过了多少个点,如果你想找一条直线的话,那么就是经过点的数量最多的那条直线了,可以一次统计出来。或者你可以设置一个阈值T,当经过直线的点的数量大于T的时候就画出来。

#2


恩,我知道是这个原理,就是不知道代码如何写,这个hough变换的代码变量有点多,我都不知道那个直线的数据存储在哪个变量里的

#3


"C:\Program Files\OpenCV\samples\cpp\houghlines.cpp"

#4


楼上这位大哥是啥意思?

#5


引用 4 楼 chendieric 的回复:
楼上这位大哥是啥意思?

让你看opencv自带的例程,是吧  赵老师 霍夫变换检测连续共点直线问题,求各位大神帮助!

#6


可以用matlab试试看

#7


引用 5 楼 baidu_16676407 的回复:
Quote: 引用 4 楼 chendieric 的回复:

楼上这位大哥是啥意思?

让你看opencv自带的例程,是吧  赵老师 霍夫变换检测连续共点直线问题,求各位大神帮助!

霍夫变换检测连续共点直线问题,求各位大神帮助!

#1


太长了,不高兴看,你看一下hough变换的原理。你检测出来的直线应该能够统计出一共经过了多少个点,如果你想找一条直线的话,那么就是经过点的数量最多的那条直线了,可以一次统计出来。或者你可以设置一个阈值T,当经过直线的点的数量大于T的时候就画出来。

#2


恩,我知道是这个原理,就是不知道代码如何写,这个hough变换的代码变量有点多,我都不知道那个直线的数据存储在哪个变量里的

#3


"C:\Program Files\OpenCV\samples\cpp\houghlines.cpp"

#4


楼上这位大哥是啥意思?

#5


引用 4 楼 chendieric 的回复:
楼上这位大哥是啥意思?

让你看opencv自带的例程,是吧  赵老师 霍夫变换检测连续共点直线问题,求各位大神帮助!

#6


可以用matlab试试看

#7


引用 5 楼 baidu_16676407 的回复:
Quote: 引用 4 楼 chendieric 的回复:

楼上这位大哥是啥意思?

让你看opencv自带的例程,是吧  赵老师 霍夫变换检测连续共点直线问题,求各位大神帮助!

霍夫变换检测连续共点直线问题,求各位大神帮助!