/* ********Hough变化***************
* 该函数实现霍夫变换,按照直线在变换
* 空间的代数关系 r = x cos(p) + y sin(p),
* 将直线变换成变换域的点(r,p)
* 本函数找出图像中两条平行线
**********************************/
void CImageProcess::bmp_HoughTransform(CDib *pB)
{
//循环变量
int i,j;
//象素取值
int pixel;
//变换域的尺寸
int MaxDist;
int MaxAngleNumber ;
//获取原图像的大小和保存大小
CSize Dimensions,SaveSize;
Dimensions = pB->GetDimensions();
SaveSize = pB->GetDibSaveDim();
//变换域最大值,坐标取值范围
MaxDist = (int) sqrt(SaveSize.cx *SaveSize.cx +
SaveSize.cy * SaveSize.cy);
MaxAngleNumber = 90;
//变换域的坐标
int Dist;
int AngleNumber;
//存储变换域中的两个最大值
MaxValue MaxValue1 ;
MaxValue MaxValue2 ;
BYTE *pSrc,*pDest;
if(pNewData)
delete pNewData;
pNewData = new byte[SaveSize.cx * SaveSize.cy];
memset( pNewData,0,SaveSize.cx * SaveSize.cy);
if(pData)
delete pData;
pData = new byte[SaveSize.cx * SaveSize.cy];
// memset( pData,255,SaveSize.cx * SaveSize.cy);
memcpy( pData,pB->m_lpImage,SaveSize.cx * SaveSize.cy);
for(i = 0;i <Dimensions.cy ;i++)
for(j = 0;j <Dimensions.cx; j++)
{
//处理256彩色图像
if(pB->m_lpBMIH->biBitCount ==8)
/////////////////////////////////
pSrc = pB->m_lpImage + i*SaveSize.cx + j;
//24位真彩色图像
else pSrc = pB->m_lpImage + i*SaveSize.cx + 3*j;
pixel = *pSrc;
//如果是黑点,则在变换域的对应各点上加1
if(pixel == 0)
{
//注意步长是2度
for(AngleNumber=0; AngleNumber<MaxAngleNumber; AngleNumber++)
{
Dist = (int) fabs(j*cos(AngleNumber*2*pi/180.0) + \
i*sin(AngleNumber*2*pi/180.0));
//变换域的对应点上加1
pDest = pNewData + Dist*MaxAngleNumber+AngleNumber;
*pDest =*pDest + 1;
}
}
}
//找到变换域中的两个最大值点
MaxValue1.Value=0;
MaxValue2.Value=0;
//找到第一个最大值点
for (Dist=0; Dist<MaxDist;Dist++)
{
for(AngleNumber=0; AngleNumber<MaxAngleNumber; AngleNumber++)
{
if((int)*(pNewData+Dist*MaxAngleNumber+AngleNumber)>MaxValue1.Value)
{
MaxValue1.Value = (int)*(pNewData+Dist*MaxAngleNumber+AngleNumber);
MaxValue1.Dist = Dist;
MaxValue1.AngleNumber = AngleNumber;
}
}
}
//将第一个最大值点附近清零,为寻找第二个最大值点做准备
for (Dist = -9;Dist < 10;Dist++)
{
for(AngleNumber=-1; AngleNumber<2; AngleNumber++)
{
if(Dist+MaxValue1.Dist>=0 && Dist+MaxValue1.Dist<MaxDist
&& AngleNumber+MaxValue1.AngleNumber>=0 && AngleNumber
+MaxValue1.AngleNumber<=MaxAngleNumber)
{
*(pNewData+(Dist+MaxValue1.Dist)*MaxAngleNumber+
(AngleNumber+MaxValue1.AngleNumber))=0;
}
}
}
//找到第二个最大值点
for (Dist=0; Dist<MaxDist;Dist++)
{
for(AngleNumber=0; AngleNumber<MaxAngleNumber; AngleNumber++)
{
if((int)*(pNewData+Dist*MaxAngleNumber+AngleNumber)>MaxValue2.Value)
{
MaxValue2.Value = (int)*(pNewData+Dist*MaxAngleNumber+AngleNumber);
MaxValue2.Dist = Dist;
MaxValue2.AngleNumber = AngleNumber;
}
}
}
//判断两直线是否平行
if(abs(MaxValue1.AngleNumber-MaxValue2.AngleNumber)<=2)
{
//两直线平行,在缓存图像中重绘这两条直线
for(i = 0;i <Dimensions.cy ;i++)
{
for(j = 0;j <Dimensions.cx; j++)
{
//对256彩色图像进行处理
if(pB->m_lpBMIH->biBitCount ==8)
{
// 指向缓存图像倒数第j行,第i个象素的指针
pDest = pData + SaveSize.cx * i + j;
pSrc = pB->m_lpImage + i*SaveSize.cx + j;
//如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑
//在第一条直线上
Dist = (int) fabs(j*cos(MaxValue1.AngleNumber*2*pi/180.0) + \
i*sin(MaxValue1.AngleNumber*2*pi/180.0));
if ((Dist == MaxValue1.Dist) && (*pSrc==0))
*pDest = (unsigned char)50;
//在第二条直线上
Dist = (int) fabs(j*cos(MaxValue2.AngleNumber*2*pi/180.0) + \
i*sin(MaxValue2.AngleNumber*2*pi/180.0));
if ((Dist == MaxValue2.Dist) && (*pSrc==0))
*pDest = (unsigned char)50;
}
//对24位真彩色图像进行处理
else
{
pDest = pData + SaveSize.cx * i + 3*j;
pSrc = pB->m_lpImage + i*SaveSize.cx +3*j;
//如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑
//在第一条直线上
Dist = (int) fabs(j*cos(MaxValue1.AngleNumber*2*pi/180.0) + \
i*sin(MaxValue1.AngleNumber*2*pi/180.0));
if (Dist == MaxValue1.Dist&& (*pSrc==0))
{
*pDest = (unsigned char)0;
*(pDest +1) = (unsigned char)0;
*(pDest +2) = (unsigned char)255;
}
//在第二条直线上
Dist = (int) fabs(j*cos(MaxValue2.AngleNumber*2*pi/180.0) + \
i*sin(MaxValue2.AngleNumber*2*pi/180.0));
if (Dist == MaxValue2.Dist && (*pSrc==0))
{ *pDest = (unsigned char)0;
*(pDest +1) = (unsigned char)0;
*(pDest +2) = (unsigned char)255;
}
}
}
}
}
memcpy ( pB->m_lpImage,pData,SaveSize.cx * SaveSize.cy);
}