图像中提取边缘线

  1 //CSFeatureCls*    pfSrc,
  2 double CBufImage::GetContour2(CAnyLine*        lin,
  3                             CSFeatureCls*    pfDes, 
  4                             D_RECT&            frc,
  5                             RAD_STRU_SIDES*    rBuf,
  6                             long            bufLen,
  7                             double            traceR,
  8                             short            knobflg)
  9 {
 10     FreeBUFFERMem();
 11 
 12     TRAN_PAR        tp;
 13     double            r=MAX_DOUBLE;
 14     double            trecR,maxr=0;
 15     long            colN,rowN,pageN;
 16     double            colL,rowL;
 17     D_DOT            *lxy,*ptDot=NULL;
 18     long             ir,ir2, rtn=0;
 19     long            i,page,li,llen;
 20     unsigned char    *pt,*pt1,*tmpbuf=NULL;
 21     D_RECT            linBox1,linBox2;
 22     CAnyPolygon        anyPolygon;
 23 
 24 
 25     for( i=0; i<bufLen; i++ )
 26     {
 27         // 保证左右的半径大于0.0
 28         if( rBuf[i].lf_r<0.0 || rBuf[i].rg_r<0.0 )
 29             continue;
 30 
 31         // 保证左右的半径不同时==0
 32         if( rBuf[i].lf_r<=EPS && rBuf[i].rg_r<=EPS )
 33             continue;
 34 
 35         // 取半径的最大值
 36         if( maxr<rBuf[i].lf_r )
 37             maxr = rBuf[i].lf_r;
 38         if( maxr<rBuf[i].rg_r )
 39             maxr = rBuf[i].rg_r;
 40         
 41         // 取半径的最小值        
 42         if( rBuf[i].lf_r>0.0 && r>rBuf[i].lf_r )
 43             r = rBuf[i].lf_r;        
 44         if( rBuf[i].rg_r>0.0 && r>rBuf[i].rg_r )
 45             r = rBuf[i].rg_r;
 46     }
 47     maxr=0;
 48     //分配计算的缓冲内存
 49     rtn = AllocBUFMem( frc,r,maxr,&colN,&rowN,&colL,&rowL,&ir,&pageN );
 50     if( rtn<=0 )
 51         goto listLinBufferEND;
 52 
 53     //计算每个线的判别点
 54     ptDot = new D_DOT[bufLen];
 55     for(li = 0; li < bufLen; li++)
 56     {     
 57         //rtn = pfSrc->polygon_Get( rBuf[li].i,&anyPolygon);
 58         llen = lin->m_varLin.dotNum();
 59         lxy =  (D_DOT*)(lin->m_varLin.ptXY());
 60         
 61         if(rtn<=0)
 62         {
 63             ptDot[li].x = frc.xmin - maxr*2.;
 64             ptDot[li].y = frc.ymin - maxr*2.;
 65             continue;
 66         }
 67 
 68         // 如果是左或右buffer,则利用GetArcLabel计算相应的判别点
 69         if(llen > 2)
 70         {    // 取中间点在r范围内的一点作为判别点            
 71             GetArcLabel( lxy[llen/2-1], lxy[llen/2], lxy[llen/2+1], r/2, ptDot[li] ); //wlcheck 2006.9.5 r-->r/2
 72         }
 73         else
 74         {    // 取两点平均值在r范围内的一点作为判别点
 75             ptDot[li].x=(lxy[0].x + lxy[llen-1].x)/2.;
 76             ptDot[li].y=(lxy[0].y + lxy[llen-1].y)/2.;
 77                 
 78             GetArcLabel( lxy[0], ptDot[li], lxy[1], r/2, ptDot[li] ); //wlcheck 2006.9.5 r-->r/2
 79         }
 80     }
 81 
 82     tmpbuf = new unsigned char[colN/8+1];
 83 
 84     for( page=0; page<pageN; page++ )
 85     {
 86         //清缓存
 87         memset(m_PtMFileObj->m_ptr, 0, m_PtMFileObj->m_msize);
 88 
 89         //置偏移量
 90         m_BUFxy0   = m_ORGxy0;
 91         m_BUFxy0.x = m_BUFxy0.x - 1/m_BUFrt;
 92         m_BUFxy0.y = m_BUFxy0.y + (page*(rowN-1)-1)/m_BUFrt;
 93 
 94         linBox1.xmin = m_BUFxy0.x;
 95         linBox1.ymin = m_BUFxy0.y;
 96         linBox1.xmax = m_BUFxy0.x + (colN+1)/m_BUFrt;
 97         linBox1.ymax = m_BUFxy0.y + (rowN+1)/m_BUFrt;
 98 
 99         m_pDrawMem->SetDrawSwitch(m_PtBUFMem,colN,rowN);
100         for(li=0;li<bufLen;li++)
101         {
102             lin->CalRect(&linBox2);
103             //if( pfSrc->polygon_GetRect( rBuf[li].i, linBox2 )>0 )
104             {
105                 if(g_RectOverlapedDetect(&linBox1,&linBox2))
106                 {
107                     /*rtn = pfSrc->polygon_Get( rBuf[li].i,&anyPolygon);
108                     polygon=anyPolygon;*/
109                     llen = lin->m_varLin.dotNum();
110                     lxy =  (D_DOT*)(lin->m_varLin.ptXY());
111                     SetLinToMemBuf(lxy,llen,0,0,knobflg);
112 
113                     long ldotNum=llen;
114                     L_DOT* pxy;
115                     pxy = new L_DOT[ldotNum];
116                     GetRegEdge2Long(lxy,ldotNum,pxy,&m_BUFxy0,m_BUFrt);
117                     for(int jj=0;jj<ldotNum-1;jj++)
118                     {
119                         if(pxy[jj].y==pxy[jj+1].y)
120                         {
121                             m_pDrawMem->LineInMem(pxy[jj].x,pxy[jj+1].x,pxy[jj].y);
122                         }
123                         else 
124                         {
125                             m_pDrawMem->LineInMem1(pxy[jj].x,pxy[jj].y,pxy[jj+1].x,pxy[jj+1].y);
126                         }
127                     //m_pDrawMem->PixelInMem(pxy[jj].x,pxy[jj].y);
128                     /*m_pDrawMem->PixelInMem(pxy[jj].x-1,pxy[jj].y-1);
129                     m_pDrawMem->PixelInMem(pxy[jj].x-1,pxy[jj].y);
130                     m_pDrawMem->PixelInMem(pxy[jj].x-1,pxy[jj].y+1);
131                     m_pDrawMem->PixelInMem(pxy[jj].x,pxy[jj].y-1);
132                     m_pDrawMem->PixelInMem(pxy[jj].x,pxy[jj].y+1);
133                     m_pDrawMem->PixelInMem(pxy[jj].x+1,pxy[jj].y-1);
134                     m_pDrawMem->PixelInMem(pxy[jj].x+1,pxy[jj].y);
135                     m_pDrawMem->PixelInMem(pxy[jj].x+1,pxy[jj].y+1);*/
136                     }
137                     delete []pxy;
138 
139                 }
140             }
141         }
142         //将上页的顶行数据放到该页的底行中
143         if(page>0)
144         {
145             pt=tmpbuf;
146             pt1=m_PtMFileObj->m_ptr;
147             for(i=0;i<colN/8;i++,pt++,pt1++)
148             (*pt1)=(*pt);
149         }
150         //保存顶行数据
151         pt=tmpbuf;
152         pt1=m_PtMFileObj->m_ptr + (rowN-1)*colN/8;
153         for(i=0;i<colN/8;i++,pt++,pt1++)
154             (*pt)=(*pt1);
155 
156         //计算半径 wlcheck 2008.9.11
157         CalTraceR(traceR, r,&trecR);
158         m_pTrcMem->MyTraceBinDEMForBUF(colN,rowN,colL,rowL,m_PtBUFMem,trecR,pfDes);
159 
160         //图形平移
161         tp.type[0]=TRAN_MOVE;
162         tp.type[1]=TRAN_NULL;
163         tp.type[2]=TRAN_NULL;
164         tp.move.dx=m_BUFxy0.x;
165         tp.move.dy=m_BUFxy0.y;
166 
167         rtn = Transform( pfDes,&tp );
168     }
169 
170     /***************************************************************************
171     将追踪获得的点坐标不直接组织成折线要素,
172     而是沿着源折线的方向投影排序(以落在折线某段上最近的垂足为排序依据),
173     然后将该垂足点在折线上的归一化参数化坐标【0-1】为排序键
174     然后按各点在原折线上对应位序依次顺序组织成新折线。
175     并将点替换成垂足。
176     //lin
177     ****************************************************************************/
178     {
179         int                j;
180         D_DOT*            pt;
181         D_3DOT            tmppnt;
182         vector<D_3DOT>    lst;
183         long            fNum = pfDes->GetObjCount();
184         CAnyLine        tmpLin;
185         double            totalLen;
186         totalLen=_CalculateLength((D_DOT*)(lin->m_varLin.ptXY()),lin->m_varLin.dotNum());
187 
188         for(i=1;i<=fNum;i++)
189         {
190             pfDes->line_Get(i,&tmpLin);
191             pt=(D_DOT*)(tmpLin.m_varLin.ptXY());
192             
193             for(j=0;j<tmpLin.m_varLin.dotNum();j++)
194             {
195                 tmppnt.z=GetPos(lin,pt+j,totalLen);
196                 tmppnt.x=pt[j].x;
197                 tmppnt.y=pt[j].y;
198                 lst.push_back(tmppnt);
199             }
200         }
201 
202         long len=lst.size();
203 
204         D_3DOT* sortBuf = new D_3DOT[len];
205         D_DOT*    newDots = new D_DOT[len+2];
206         long    pnum=0;
207 
208         for(i=0;i<len;i++)
209         {
210             sortBuf[i].x=lst[i].x;
211             sortBuf[i].y=lst[i].y;
212             sortBuf[i].z=lst[i].z;
213         }
214 
215         newDots[0]=((D_DOT*)lin->m_varLin.ptXY())[0];
216         pnum++;
217         qsort(sortBuf,len,sizeof(D_3DOT),PD_3DOTCompare);
218         long prev=0;
219         if(sortBuf[prev].z>0&&sortBuf[prev].z<1)
220         {
221             newDots[pnum].x=sortBuf[prev].x;
222             newDots[pnum].y=sortBuf[prev].y;
223             pnum++;
224         }
225         for(i=1;i<len;i++)
226         {
227             if(sortBuf[i].z>sortBuf[prev].z)
228             {
229                 if(sortBuf[i].z>0&&sortBuf[i].z<1)
230                 {
231                     newDots[pnum].x=sortBuf[i].x;
232                     newDots[pnum].y=sortBuf[i].y;
233                     pnum++;
234                 }
235                 
236                 prev=i;
237             }
238         }
239 
240         newDots[pnum]=((D_DOT*)lin->m_varLin.ptXY())[lin->m_varLin.dotNum()-1];
241         pnum++;
242 
243 
244         delete [] sortBuf;
245 
246         //sort,去重复
247         //
248         tmpLin.m_varLin.Set(newDots,pnum,2);
249         //存储
250         pfDes->cls_Clear();
251         pfDes->line_Append(&tmpLin);
252         delete [] newDots;
253         lst.clear();
254     }
255     // 重新计算要素类的最大外包矩形框
256     rtn = sfcls_ReCalcRange(pfDes);
257     if( rtn<=0 )
258         goto listLinBufferEND;
259 
260 
261  
262     
263 listLinBufferEND:
264     
265     if(tmpbuf)     delete[] tmpbuf;
266     if(ptDot)     delete[] ptDot;
267 
268     return rtn;
269 }

猜你喜欢

转载自www.cnblogs.com/2008nmj/p/10060847.html