HOUGH变换的VC代码.docx
《HOUGH变换的VC代码.docx》由会员分享,可在线阅读,更多相关《HOUGH变换的VC代码.docx(8页珍藏版)》请在冰豆网上搜索。
HOUGH变换的VC代码
HOUGH变换的VC代码
BOOLWINAPIHoughDIB(LPSTRlpDIBBits,LONGlWidth,LONGlHeight)
{
//指向源图像的指针
LPSTRlpSrc;
//指向缓存图像的指针
LPSTRlpDst;
//指向变换域的指针
LPSTRlpTrans;
//图像每行的字节数
LONGlLineBytes;
//指向缓存DIB图像的指针
LPSTRlpNewDIBBits;
HLOCALhNewDIBBits;
//指向变换域的指针
LPSTRlpTransArea;
HLOCALhTransArea;
//变换域的尺寸
intiMaxDist;
intiMaxAngleNumber;
//变换域的坐标
intiDist;
intiAngleNumber;
//循环变量
longi;
longj;
//像素值
unsignedcharpixel;
//存储变换域中的两个最大值
MaxValueMaxValue1;
MaxValueMaxValue2;
//暂时分配内存,以保存新图像
hNewDIBBits=LocalAlloc(LHND,lWidth*lHeight);
if(hNewDIBBits==NULL)
{
//分配内存失败
returnFALSE;
}
//锁定内存
lpNewDIBBits=(char*)LocalLock(hNewDIBBits);
//初始化新分配的内存,设定初始值为255
lpDst=(char*)lpNewDIBBits;
memset(lpDst,(BYTE)255,lWidth*lHeight);
//计算变换域的尺寸
//最大距离
iMaxDist=(int)sqrt(lWidth*lWidth+lHeight*lHeight);
//角度从0-180,每格2度
iMaxAngleNumber=90;
//为变换域分配内存
hTransArea=LocalAlloc(LHND,lWidth*lHeight*sizeof(int));
if(hNewDIBBits==NULL)
{
//分配内存失败
returnFALSE;
}
//锁定内存
lpTransArea=(char*)LocalLock(hTransArea);
//初始化新分配的内存,设定初始值为0
lpTrans=(char*)lpTransArea;
memset(lpTrans,0,lWidth*lHeight*sizeof(int));
//计算图像每行的字节数
lLineBytes=WIDTHBYTES(lWidth*8);
for(j=0;j{
for(i=0;i{
//指向源图像倒数第j行,第i个象素的指针
lpSrc=(char*)lpDIBBits+lLineBytes*j+i;
//取得当前指针处的像素值,注意要转换为unsignedchar型
pixel=(unsignedchar)*lpSrc;
//目标图像中含有0和255外的其它灰度值
if(pixel!
=255&&*lpSrc!
=0)
returnFALSE;
//如果是黑点,则在变换域的对应各点上加1
if(pixel==0)
{
//注意步长是2度
for(iAngleNumber=0;iAngleNumber{
iDist=(int)fabs(i*cos(iAngleNumber*2*pi/180.0)+\
j*sin(iAngleNumber*2*pi/180.0));
//变换域的对应点上加1
*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)=\
*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)+1;
}
}
}
}
//找到变换域中的两个最大值点
MaxValue1.Value=0;
MaxValue2.Value=0;
//找到第一个最大值点
for(iDist=0;iDistMaxValue1.Value)
{
MaxValue1.Value=(int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);
MaxValue1.Dist=iDist;
MaxValue1.AngleNumber=iAngleNumber;
}
}
}
//将第一个最大值点附近清零
for(iDist=-9;iDist=0&&iDist+MaxValue1.Dist=0&&iAngleNumber+MaxValue1.AngleNumber<=iMaxAngleNumber)
{
*(lpTransArea+(iDist+MaxValue1.Dist)*iMaxAngleNumber+\
(iAngleNumber+MaxValue1.AngleNumber))=0;
}
}
}
//找到第二个最大值点
for(iDist=0;iDistMaxValue2.Value)
{
MaxValue2.Value=(int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);
MaxValue2.Dist=iDist;
MaxValue2.AngleNumber=iAngleNumber;
}
}
}//判断两直线是否平行
if(abs(MaxValue1.AngleNumber-MaxValue2.AngleNumber)<=2)
{
//两直线平行,在缓存图像中重绘这两条直线
for(j=0;j{
for(i=0;i{
//指向缓存图像倒数第j行,第i个象素的指针
lpDst=(char*)lpNewDIBBits+lLineBytes*j+i;
//如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑
//在第一条直线上
iDist=(int)fabs(i*cos(MaxValue1.AngleNumber*2*pi/180.0)+\
j*sin(MaxValue1.AngleNumber*2*pi/180.0));
if(iDist==MaxValue1.Dist)
*lpDst=(unsignedchar)0;
//在第二条直线上
iDist=(int)fabs(i*cos(MaxValue2.AngleNumber*2*pi/180.0)+\
j*sin(MaxValue2.AngleNumber*2*pi/180.0));
if(iDist==MaxValue2.Dist)
*lpDst=(unsignedchar)0;
}
}
}
//复制腐蚀后的图像
memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
//释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
//释放内存
LocalUnlock(hTransArea);
LocalFree(hTransArea);
//返回
returnTRUE;
}