项目记录-处理两个相交圆方法探索3

来源:互联网 发布:e盾网络验证价格 编辑:程序博客网 时间:2024/04/29 13:57

问题:
原图中存在两个部分重叠的圆,多余的圆会影响边缘提取的正确度,所以需要从边缘中去掉另一个交叠圆上的点。
方法:
使用之前的方法删除错误的边缘点之后,余下的点中还存在偏离的点需要进一步修正。
由于边界的起点不一定正确,所以先遍历边界点,找出离中心最近的点,从该点出发来查找待
修正的点。
判断是否需要修正的条件:
1)如果当前点和前面一个点相距太大,则当前点需要向中心点平移一段距离才行
2)如果当前点和前一个点相距偏大,且当前点、前一点、中心点三点形成的角度是钝角,则认为
当前点严重偏离中心点,需要作进一步修正。

修正的方法也依照上述两种情况分开处理:
1)如果当前点和前面点的距离太大,则前一点无法作为当前点的参考点,
考虑从中心点出发,向当前点方 向移动,找到最后一个掩膜标记的点作为替换点;

2)否则,直接参考前面点和中心点的距离dis,将当前点向中心点方向移动,
当距离中心点小于等于dis 时,则认为可以停止移动了。

为了加快修正的速度,对于需要修正的一段圆弧,弧上的每个点的移动步数都参考圆弧起点的
移动步数,而不用每个点都使用上面的两个判断来结束移动。

最终的实践效果较好。


代码如下:

    int beginid=0;    vector<int>centerdis;    int cx=centerx-vecResult[0].x;    int cy=centery-vecResult[0].y;    int cdis=cx*cx+cy*cy;    centerdis.push_back(cdis);    int dx,dy,dis;    for(int i=1;i<size;i++)    {        cx=centerx-vecResult[i].x;        cy=centery-vecResult[i].y;        cdis=cx*cx+cy*cy;        centerdis.push_back(cdis);        if(cdis<centerdis[beginid])            beginid=i;    }    //最后一个点和起始点求距离    if(beginid==0){        centerdis.push_back(centerdis[0]);       vecResult.push_back(vecResult[0]);    }    else{        centerdis.insert(centerdis.begin()+beginid,centerdis[beginid]);       vecResult.insert(vecResult.begin()+beginid, vecResult[beginid]);    }    beginid++;    queue<int>changeid;    int newsize=size+1;    for (int i = 1; i <= size; i++)    {        int cur=(beginid+i)%newsize;        int prev=(cur+size)%newsize;        //计算前后两点的距离        dx=vecResult[cur].x-vecResult[prev].x;        dy=vecResult[cur].y-vecResult[prev].y;        dis=dx*dx+dy*dy;        //如果前后距离大于等于100,认为需要进行平移        if(dis>=200)         {            changeid.push(cur);        }        else if(dis>=100)        {           //再次判断前后两点与中心点的距离是否接近,如果相差不大,则认为可以接受           cx=vecResult[cur].x-centerx;           cy=vecResult[cur].y-centery;           cdis=cx*cx+cy*cy;           cx=vecResult[prev].x-centerx;           cy=vecResult[prev].y-centery;           int cdis1=cx*cx+cy*cy;           //如果前后两点与中心点的距离相差大于100,则需要进行平移           int abscdis=abs(cdis-cdis1);           if(abscdis>=200)           {               changeid.push(cur);           }           else if(abscdis>100)           {               //以前一点为锚点,计算角度是否为钝角               int x1,y1;               if(cur==beginid-1)               {                   cx=centerx-vecResult[cur].x;                   cy=centery-vecResult[cur].y;                   x1=vecResult[prev].x-vecResult[cur].x;                   y1=vecResult[prev].y-vecResult[cur].y;               }               else               {                  cx=centerx-vecResult[prev].x;                  cy=centery-vecResult[prev].y;                  x1=vecResult[cur].x-vecResult[prev].x;                  y1=vecResult[cur].y-vecResult[prev].y;               }               float cos=(cx*x1+cy*y1)/sqrt(1.0*(cx*cx+cy*cy)*(x1*x1+y1*y1));              if(cos<0.01)//为钝角              {                 changeid.push(cur);              }           }        }    }    int step=MOVELEN;    int changesize=changeid.size();    if(changesize==1)    {        int icur=changeid.front();        //反着,中心尝试向该点移动,第一次碰到                    int i=1;        int sx=centerx-vecResult[icur].x;        int sy=centery-vecResult[icur].y;        int maxmove=max(abs(sx),abs(sy));        if(sx!=0)sx=sx/abs(sx);        if(sy!=0)sy=sy/abs(sy);        int newx=centerx-sx;        int newy=centery-sy;        int pos=newy*sWidth+newx;        while(pMaskBuf[pos] && i<=maxmove)        {            newx-=sx;            newy-=sy;            pos=newy*sWidth+newx;            i++;        }        vecResult[icur].x=newx;        vecResult[icur].y=newy;    }    else    {    while(!changeid.empty())    {        int ibegin=changeid.front();        changeid.pop();        int iend=ibegin+1;        if(!changeid.empty())        {            int inext=changeid.front();            if((inext-ibegin)<size/2)            {                iend=inext;            }        }        else            break;        step=MOVELEN;        //要把<=换成!=,因为有可能起点的Id大于终点的id        for(int icur=ibegin;icur!=iend;icur=(icur+1)%newsize)        {                   //向中心点平移的单位位移stepx,stepy            int sx=centerx-vecResult[icur].x;            int sy=centery-vecResult[icur].y;            int maxmove=max(abs(sx),abs(sy));            if(sx!=0)sx=sx/abs(sx);            if(sy!=0)sy=sy/abs(sy);            //计算前一个点距离中心点的距离            int iprev=(icur+size)%newsize;            int dis1=centerdis[iprev];            //计算前后两点的初始距离            dx=vecResult[icur].x-vecResult[iprev].x;            dy=vecResult[icur].y-vecResult[iprev].y;            int dis0=dx*dx+dy*dy;            bool isFar=false;            if(dis0>=200) isFar=true;            int newx,newy;            if(step==MOVELEN)            {                //如果最开始的距离就大于200,认为相距太远,不做判断依据                //反着,中心尝试向该点移动,第一次碰到                            if(isFar)                {                    int i=1;                    newx=centerx-sx;                    newy=centery-sy;                    int pos=newy*sWidth+newx;                    //                    while(pMaskBuf[pos] && i<=maxmove)                    {                        newx-=sx;                        newy-=sy;                        pos=newy*sWidth+newx;                        i++;                    }                    step=maxmove-i;                    vecResult[icur].x=newx;                    vecResult[icur].y=newy;                }                else                {                    newx=vecResult[icur].x + sx;                    newy=vecResult[icur].y + sy;                    while(step)                    {                       newx += sx;                       newy += sy;                       //重新计算和前一个点的距离,如果变得小于100了,则停止移动                       dx=newx-vecResult[iprev].x;                       dy=newy-vecResult[iprev].y;                       dis=dx*dx+dy*dy;                       //计算到中心点的距离                       cx=newx-centerx;                       cy=newy-centery;                       cdis=cx*cx+cy*cy;                       //如果最开始的距离就大于200,认为相距太远,不做判断依据                       if((isFar && (centerdis[iprev]-cdis)<=100) || (!isFar && dis<=100 && (centerdis[iprev]-cdis)<=100))                       {                           vecResult[icur].x = newx;                           vecResult[icur].y = newy;                           step=MOVELEN-step;                           break;                       }                       step--;                    }                }            }            else            {                int i=step;                newx=vecResult[icur].x + sx;                newy=vecResult[icur].y + sy;                while(i--)                {                   newx += sx;                   newy += sy;                }                vecResult[icur].x = newx;                vecResult[icur].y = newy;            }        }      }    }    vecResult.erase(vecResult.begin()+beginid);    out.close();    //再做一次凸包修正    vecResult = grahamScan(vecResult);
0 0