基于sobel和canny算法的水珠边缘检测 - 图文(3)

2019-04-16 15:20

if(abs(gy) > abs(gx)){ //计算插值比例

weight = fabs(gx)/fabs(gy); g2 = pMag[nPos-sz.cx]; g4 = pMag[nPos+sz.cx];

//如果x,y两个方向导数的符号相同,C 为当前像素,与g1-g4 的位置关系为:

// g1 g2 // C // g4 g3

if(gx*gy>0){

g1 = pMag[nPos-sz.cx-1]; g3 = pMag[nPos+sz.cx+1]; }

//如果x,y两个方向的方向导数方向相反,C是当前像素,与g1-g4的关系为:

// g2 g1 // C // g3 g4

else {

g1 = pMag[nPos-sz.cx+1]; g3 = pMag[nPos+sz.cx-1]; } }

//如果方向导数x分量比y分量大,说明导数的方向趋向于x分量

else{ //插值比例

weight = fabs(gy)/fabs(gx); g2 = pMag[nPos+1]; g4 = pMag[nPos-1];

//如果x,y两个方向的方向导数符号相同,当前像素C与 g1-g4的关系为 // g3 // g4 C g2 // g1

if(gx * gy > 0){

g1 = pMag[nPos+sz.cx+1]; g3 = pMag[nPos-sz.cx-1]; }

// 如果x,y两个方向导数的方向相反,C与g1-g4的关系为 // g1 // g4 C g2 // g3

else{

g1 = pMag[nPos-sz.cx+1]; g3 = pMag[nPos+sz.cx-1]; } }

{//利用 g1-g4 对梯度进行插值

dTmp1 = weight*g1 + (1-weight)*g2; dTmp2 = weight*g3 + (1-weight)*g4;

//当前像素的梯度是局部的最大值,该点可能是边界点

if(dTmp>=dTmp1 && dTmp>=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;k<256;k++){

nHist[k] = 0; }

//最大梯度数

//初始化

//统计直方图,利用直方图计算阈值

for(y=0;y

for(x=0;x

if(pGray[y*sz.cx+x]==128){

nHist[pMag[y*sz.cx+x]]++; } } }

nEdgeNum = nHist[0]; nMaxMag = 0;

//统计经过“非最大值抑制”后有多少像素

for(k=1;k<256;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)) && (nEdgeNum < nHighCount)){

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;y

for(x=0;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;y

//其他点已经不可能为边界点

for(x=0;x

nPos = y*sz.cx + x; if(pResult[nPos] != 255){

pResult[nPos] = 0; } } } }

/*根据Hysteresis 执行的结果,从一个像素点开始搜索,搜索以该像素点为边界起点的一条边界的一条边界的所有边界点,函数采用了递归算法。从(x,y)坐标出发,进行边界点的跟踪,跟踪只考虑pResult中没有处理并且可能是边界点的像素(=128),像素值为0表明该点不可能是边界点,像素值为255表明该点已经是边界点*/

void TraceEdge(int y, int x, int nThrLow, LPBYTE pResult,

int *pMag, SIZE sz)

{

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;k<8;k++){

yy = y+yNum[k]; xx = x+xNum[k];

if(pResult[yy*sz.cx+xx]==128 && pMag[yy*sz.cx+xx]>=nThrLow){

pResult[yy*sz.cx+xx]=255;//该点设为边界点,以该点为中心再进行跟踪 TraceEdge(yy,xx,nThrLow,pResult,pMag,sz); } }

//对8邻域像素进行查询


基于sobel和canny算法的水珠边缘检测 - 图文(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:安全责任书

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: