我想模擬一個用於填充二進制圖像(二維矩陣爲1和零)的matlab函數「imfill」。用於填充二進制圖像的C++算法
我想指定矩陣中的起點,洪水填補像imfill的4相連接的版本會做。
這是否已經在C++世界上存在有某處?如果不是,那麼實施這個最有效的方法是什麼?
我想模擬一個用於填充二進制圖像(二維矩陣爲1和零)的matlab函數「imfill」。用於填充二進制圖像的C++算法
我想指定矩陣中的起點,洪水填補像imfill的4相連接的版本會做。
這是否已經在C++世界上存在有某處?如果不是,那麼實施這個最有效的方法是什麼?
如果您的圖片只是1和0的二維數組,那麼我不認爲你需要一個實際的圖形庫。
當我填寫簡單的網格,在過去,我只是用STL隊列存儲點的列表,然後通過這些工作。隊列將從初始點開始,然後測試相鄰點。如果需要將相鄰點包含在「洪水」中,則將其添加到隊列中。有點像這樣:
// using this data structure
struct Point {
int x;
int y;
};
//
void fillGrid(Point orig, byte** grid, int width, int height) {
std::queue<Point> q;
q.push(orig);
// the main flood loop
while(!q.empty()) {
Point pnt = q.front();
q.pop();
// grab adjacent points
Point adj[4];
adj[0].x = pnt.x; adj[0].y = pnt.y-1; // up
adj[1].x = pnt.x+1; adj[1].y = pnt.y; // right
adj[2].x = pnt.x; adj[2].y = pnt.y+1; // down
adj[3].x = pnt.x-1; adj[3].y = pnt.y; // left
for(int i = 0; i < 4; i++) {
// don't forget boundaries!
if(adj[i].x < 0 || adj[i].x >= width ||
adj[i].y < 0 || adj[i].y >= height)
continue;
// if adjacent point meets some criteria, then set
// its value and include it in the queue
if(includePoint(adj[i], grid)) {
setPoint(adj[i], grid);
q.push(adj[i]);
}
}
}
}
結束了沿着這些線使用的東西。認爲其他的東西會過度殺傷。感謝您的提示! – Derek 2011-05-10 17:49:35
注意:如果你正在爲速度進行優化,for循環內的邊界檢查可能是一個相當兇手。在沒有檢查的情況下處理圖像內部會更快(並且會有更多的代碼)(因爲它總是在內部評估爲「false」),然後在外部執行檢查。有很多方法可以避免它,但它們都涉及更多的代碼。 – 2011-05-23 12:30:04
查看this page ('QuickFill: An efficient flood fill algorithm')
的代碼示例在最初的幾個代碼示例,像素檢查是否有填充(或邊框)顏色和功能遞歸調用自己所有四個(或八個)相鄰像素(實際上,我聲稱前幾個例子有點不對,因爲第一次遞歸調用應該是對設置新像素的函數的調用,而不是使用相同的參數再次調用函數本身)。
接下來的幾個實施例描述了一個遞歸掃描線方法,它首先填充一個(水平)線儘可能纔去相鄰的線(上方和下方的線),從而訪問每個像素較少。
最後,提出了QuickFill
這對我看起來像掃描線方法的最優化變異體。
偉大的鏈接,但總結會很好,尤其是如果它給出了一些關鍵術語來搜索鏈接是否斷裂。 – 2011-05-09 19:59:52
Aforge庫具有以下功能
AForge.Imaging.Filters.FillHoles(...)
它做同樣的事情imfill在Matlab。
調查「廣度優先搜索」:http://stackoverflow.com/questions/2505431/breadth-first-search-and-depth-first-search – Pablo 2011-05-09 19:31:31