鏈碼錶轉換為線段表

來源:互聯網
上載者:User
鏈碼錶轉換為線段表

 

 

 鏈碼錶和線段表都可以描述輪廓,通過輪廓跟蹤得到鏈碼錶,鏈碼錶可以很容易計算出輪廓長度,但輪廓填充,計算面積、重心等使用線段表會更加容易。為了後續處理的方便,往往需要將鏈碼錶轉換為線段表。線段表只需要記錄每條線段的兩個端點座標,中間點全部捨棄。鏈碼錶上的點如果位於線段的中間則捨棄,如果位於線段的某一個端點則保留,如果位於線段的兩個端點(即線段長度為1)則需要插入一個端點,最後按照垂直方向和水平方向排序。
  在程式中判斷鏈碼錶上的點線上段上的位置關係比較麻煩,且位置關係只有64種,因此採用查表法簡單高效,不失為極佳方案。同樣,事先無法確定線段數量,可以使用vector來動態管理記憶體。

 

#include <vector><br />#include <algorithm><br />typedef std::vector<int> ivChainCode;<br />typedef std::vector<POINT> pvLineTable;<br />struct CPointCompare<br />{<br /> BOOL operator() (const POINT& p1, const POINT& p2)<br /> {<br /> return (p1.y < p2.y || (p1.y == p2.y && p1.x < p2.x));<br /> }<br />};<br />// 轉換為線段表<br />// 1. ptStart 起始點<br />// 2. ChainCode 鏈碼錶<br />// 3. pLineTable 線段表<br />bool ToLineTable(POINT ptStart, ivChainCode ChainCode, pvLineTable *pLineTable)<br />{<br /> ivChainCode::iterator i, j;<br /> POINT ptCurrent = { 0, 0 };<br /> const POINT ptOffset[8] =<br /> {<br /> { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 },<br /> { -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 }<br /> };<br /> int nTable[8][8] =<br /> {<br /> { 0, 2, 2, 2, 2, 0, 0, 0 },<br /> { 0, 2, 2, 2, 2, 3, 0, 0 },<br /> { 0, 2, 2, 2, 2, 3, 3, 0 },<br /> { 0, 2, 2, 2, 2, 3, 3, 3 },<br /> { 1, 0, 0, 0, 0, 1, 1, 1 },<br /> { 1, 3, 0, 0, 0, 1, 1, 1 },<br /> { 1, 3, 3, 0, 0, 1, 1, 1 },<br /> { 1, 3, 3, 3, 0, 1, 1, 1 }<br /> };<br /> // 清空線段表<br /> pLineTable->clear();<br /> ptCurrent.x = ptStart.x;<br /> ptCurrent.y = ptStart.y;<br /> if (ChainCode.empty())<br /> {<br /> // 獨立點<br /> pLineTable->push_back(ptCurrent);<br /> pLineTable->push_back(ptCurrent);<br /> }<br /> else<br /> {<br /> // 查表法轉換<br /> for (i = ChainCode.begin(), j = i + 1; i != ChainCode.end(); i++, j++)<br /> {<br /> if (j == ChainCode.end())<br /> {<br /> j = ChainCode.begin();<br /> }<br /> ptCurrent.x += ptOffset[*i].x;<br /> ptCurrent.y += ptOffset[*i].y;<br /> switch (nTable[*i][*j])<br /> {<br /> case 0:<br /> break;<br /> case 1:<br /> case 2:<br /> pLineTable->push_back(ptCurrent);<br /> break;<br /> case 3:<br /> pLineTable->push_back(ptCurrent);<br /> pLineTable->push_back(ptCurrent);<br /> break;<br /> }<br /> }<br /> // 排序<br /> sort(pLineTable->begin(), pLineTable->end(), CPointCompare());<br /> }<br /> return true;<br />}<br />// 輪廓填充<br />// 1. pImageData 映像資料<br />// 2. nWidth 映像寬度<br />// 3. nHeight 映像高度<br />// 4. nWidthStep 映像行大小<br />// 5. LineTable 線段表<br />bool FillContour(unsigned char *pImageData, int nWidth, int nHeight, int nWidthStep, pvLineTable LineTable)<br />{<br /> for (pvLineTable::iterator i = LineTable.begin(); i != LineTable.end(); i += 2)<br /> {<br /> for (long x = i->x; x <= (i + 1)->x; x++)<br /> {<br /> pImageData[nWidthStep * i->y + x] = 0xFF;<br /> }<br /> }<br /> return true;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.