//该点可能是边界点
if(dTmp=dTmp1dTmp=dTmp2)
{
pNSRst[nPos] = 128;
}
else
{
//不可能是边界点
pNSRst[nPos] = 0;
}
}
}
}
}
}
// 统计pMag的直方图,判定阈值
void EstimateThreshold(int *pMag, SIZE sz, int *pThrHigh, int *pThrLow, LPBYTE pGray,
double dRatHigh, double dRatLow)
{
LONG y,x,k;
//该数组的大小和梯度值的范围有关,如果采用本程序的算法
//那么梯度的范围不会超过pow(2,10)
int nHist[256];
//可能边界数
int nEdgeNum;
//最大梯度数
int nMaxMag;
int nHighCount;
nMaxMag = 0;
//初始化
for(k=0;k256;k++)
{
nHist[k] = 0;
}
//统计直方图,利用直方图计算阈值
for(y=0;ysz.cy;y++)
{
for(x=0;xsz.cx;x++)
{
if(pGray[y*sz.cx+x]==128)
{
nHist[pMag[y*sz.cx+x]]++;
}
}
}
nEdgeNum = nHist[0];
nMaxMag = 0;
//统计经过“非最大值抑制”后有多少像素
for(k=1;k256;k++)
{
if(nHist[k] != 0)
{
nMaxMag = k;
}
//梯度为0的点是不可能为边界点的
//经过non-maximum suppression后有多少像素
nEdgeNum += nHist[k];
}
//梯度比高阈值*pThrHigh 小的像素点总书目
nHighCount = (int)(dRatHigh * nEdgeNum + 0.5);
k=1;
nEdgeNum = nHist[1];
//计算高阈值
while((k(nMaxMag-1))(nEdgeNumnHighCount))
{
k++;
nEdgeNum += nHist[k];
}
*pThrHigh = k;
//低阈值
*pThrLow = (int)((*pThrHigh) * dRatLow + 0.5);
}
//利用函数寻找边界起点
void Hysteresis(int *pMag, SIZE sz, double dRatLow, double dRatHigh, LPBYTE pResult)
{
LONG y,x;
int nThrHigh,nThrLow;
int nPos;
//估计TraceEdge 函数需要的低阈值,以及Hysteresis函数使用的高阈值
EstimateThreshold(pMag, sz,nThrHigh,nThrLow,pResult,dRatHigh,dRatLow);
//寻找大于dThrHigh的点,这些点用来当作边界点,
//然后用TraceEdge函数跟踪该点对应的边界
for(y=0;ysz.cy;y++)
{
for(x=0;xsz.cx;x++)
{
nPos = y*sz.cx + x;
//如果该像素是可能的边界点,并且梯度大于高阈值 ,
//该像素作为一个边界的起点
if((pResult[nPos]==128)(pMag[nPos] = nThrHigh))
{
//设置该点为边界点
pResult[nPos] = 255;
TraceEdge(y,x,nThrLow,pResult,pMag,sz);
}
}
}
//其他点已经不可能为边界点
for(y=0;ysz.cy;y++)
{
for(x=0;xsz.cx;x++)
{
nPos = y*sz.cx + x;
if(pResult[nPos] != 255)
{
pResult[nPos] = 0;
}
}
}
}
//根据Hysteresis 执行的结果,从一个像素点开始搜索,搜索以该像素点为边界起点的一条边界的
//一条边界的所有边界点 , 函数采用C语言canny算子函数了递归算法
//从(x,y)坐标出发 , 进行边界点的跟踪 , 跟踪只考虑pResult中没有处理并且可能是边界
//点的像素(=128),像素值为0表明该点不可能是边界点,像素值为255表明该点已经是边界点
void TraceEdge(int y, int x, int nThrLow, LPBYTE pResult, int *pMag, SIZE sz)
{
//对8邻域像素进行查询
int xNum[8] = {1,1,0,-1,-1,-1,0,1};
int yNum[8] = {0,1,1,1,0,-1,-1,-1};
LONG yy,xx,k;
for(k=0;k8;k++)
{
yy = y+yNum[k];
xx = x+xNum[k];
if(pResult[yy*sz.cx+xx]==128pMag[yy*sz.cx+xx]=nThrLow )
{
//该点设为边界点
pResult[yy*sz.cx+xx] = 255;
//以该点为中心再进行跟踪
TraceEdge(yy,xx,nThrLow,pResult,pMag,sz);
推荐阅读
- 小米wifi接小米路由器怎么设置,连接小米无线路由器
- gis应用支撑方案,gis技术支持是做什么的
- 区块链健康码互扫,区块链健康码互扫怎么操作
- 中班体育公开课竞赛游戏,中班体育公开课竞赛游戏有哪些
- go语言从入门到精通06 go语言入门指南
- mac软件下载网站,mac软件下载网站推荐2022
- 关于妈妈为什么要吃饭看电视的信息
- 我的世界游戏单机,我的世界单机小游戏
- java代码单元测试 java单元测试工具有哪些