漫水填充演算法

2021-08-02 03:00:59 字數 3237 閱讀 5702

所謂漫水填充演算法,是給定乙個聯通域內的乙個點,以此為起點找到這個聯通域的其餘所有點並將其填充為指定顏色的一種演算法。 

之所以稱之為漫水填充,是因為這種演算法就是模擬了漲水的過程,從一點開始,水流慢慢加大,直到漫過了全部區域。 

這個演算法的詳細介紹可以參考下面的鏈結。 

這個演算法在我們尋找一片指定區域時非常有用。因此,我就花了點時間寫了個程式。我所實現的演算法類似於下面這張中的方法,不過我是每次填充一行。

下面這個 floodfill_gray 函式用於填充灰度影象,講乙個聯通域的灰度填充為 newval。

static

inline

bool fillpoint_gray( qimage &image, qpoint p, uchar val, uchar newval, qstack&stack)

line[x] = newval;

if( y > 0 )

}if( y < image.height() - 1 )

}return

true;

}bool floodfill_gray(qimage &image, qpoint seedpoint, uchar newval )

int width = image.width();

int height = image.height();

int x = seedpoint.rx();

int y = seedpoint.ry();

if(x < 0 || x >= width || y < 0 || y >= height)

int value = image.scanline(y)[x];

qstackstack;

stack.push(seedpoint);

while(!stack.isempty())

x = p.rx();

x ++;

while(x < width && ret2)

}return

true;

}

有時,由於有雜訊等影響,我們的待填充區域內的原始顏色並不完全一樣,這時可以採用模糊填充。所謂模糊填充就是我們設定乙個顏色範圍,將這個顏色範圍內的點都認為是區域的內點。 

下面的**就實現了這個功能。

static

inline

bool fillpoint_gray( qimage &image, qpoint p, uchar low, uchar high, uchar newval, qstack&stack)

line[x] = newval;

if( y > 0 )

}if( y < image.height() - 1 )

}return

true;

}bool floodfill_gray(qimage &image, qpoint seedpoint, int low, int high, uchar newval )

low = qbound(0, low, 255);

high = qbound(0, high, 255);

if(low > high)

qstackstack;

stack.push(seedpoint);

int width = image.width();

while(!stack.isempty())

x = p.rx();

x ++;

while(x < width && ret2)

}return

true;

}

我還寫了乙個用來填充彩色影象的。這個**還比較簡單,暫時還沒實現模糊顏色的判別。之所以沒有寫,主要還是在rgb顏色空間中,不太方便度量兩個顏色值之間的距離。如果簡單的採用歐氏距離,則與我們眼睛對色彩的感受會有些出入。可能我們覺得顏色差別很大的兩個顏色的距離並不遠,而看起來差不多的兩個顏色可能距離挺大的。

static

inline

bool fillpoint_rgb32( qimage &image, qpoint p, qrgb val, qrgb newval, qstack&stack)

line[x] = newval;

if( y > 0 )

}if( y < image.height() - 1 )

}return

true;

}bool floodfill_rgb32(qimage &image, qpoint seedpoint, qrgb newval )

int width = image.width();

int height = image.height();

int x = seedpoint.rx();

int y = seedpoint.ry();

if(x < 0 || x >= width || y < 0 || y >= height)

qrgb value = image.pixel(x, y);

qstackstack;

stack.push(seedpoint);

while(!stack.isempty())

x = p.rx();

x ++;

while(x < width && ret2)

}return

true;

}

下面是乙個測試影象。

我要將其中最大的紅色的聯通區域填充為藍色。下面是填充後的結果。 

但是這個演算法有乙個注意事項,就是它只將上下左右相鄰的畫素視為連同,斜向相鄰的畫素認為是不連通的。之所以這樣設計是為了處理下面這種情況。如果斜向也認為是連同的話那麼下圖中所有的白色區域就都是聯通的了,這和我們直觀的感覺是不相同的。

當然,這樣處理後,黑色區域中有兩個孤立點就被程式認為不與其他黑色區域聯通了。這個與我們直觀感覺也是有差異的。總之,這兩種情況無法兼顧。

本文**:

漫水填充演算法

漫水填充演算法是填充演算法中最通用的演算法。所謂漫水填充 演算法,是給定乙個聯通域內的乙個點,以此為起點找到這個聯通域的其餘所有點並將其填充為指定顏色的一種演算法。之所以稱之為漫水填充,是因為這種演算法就是模擬了漲水的過程,從一點開始,水流慢慢加大,直到漫過了全部區域。該填充演算法的原型如下所示 v...

漫水填充演算法

1 基於掃瞄線實現的泛洪填充演算法的主要思想是根據當前輸入的點p x,y 沿y方向分別向上與向下掃瞄填充,同時向左p x 1,y 與向右p x 1,y 遞迴尋找新的掃瞄線,直到遞迴結束。2 row height point.y col width point.x 3 這裡要注意image.at i,...

漫水填充演算法

漫水填充演算法 用一定顏色填充聯通區域,通過射著可連通畫素的上下限以及連通方式來達到不同的填充效果。漫水填充類似於連通域分析中種子填充法,區別在於漫水填充處理彩色或灰度影象,當鄰域畫素值和種子畫素值的差值在一定範圍內,則認為是同一連通區域。種子填充法 include opencv2 imgproc ...