影象中提取邊緣線
阿新 • • 發佈:2018-12-03
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 2425 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 }