1. 程式人生 > 其它 >OpenCV之漫水填充與floodFill函式(C++實現)

OpenCV之漫水填充與floodFill函式(C++實現)

技術標籤:C++opencv影象處理opencv計算機視覺c++

漫水填充的定義

漫水填充是一種用特定的顏色填充連通區域,通常設定可連通畫素的上下限以及連通方式來得到不同的填充效果的方法。漫水填充經常被用來標記或分離影象的一部分,以便對其進行進一步非處理或分析,也可以用來對輸入影象獲取掩膜區域,掩膜會加速處理過程,獲只處理掩膜指定的畫素點,操作的結果總是某個連續區域。

漫水填充的基本思想

漫水填充,就是自動的選中與種子點相連的區域,然後將該區域替換成指定的顏色,這個功能經常被用來標記或分離影象的一部分進行處理或分析。漫水填充也可以用來輸入影象獲取掩膜區域,掩膜會加速處理過程,或者只處理掩膜指定的畫素點。

OpenCV中有兩個版本的漫水填充函式:一個不帶mask的版本,和一個帶mask的版本。這個掩膜mask,就是用於進一步控制哪些區域被填充顏色(比如對同一影象進行多次填充時)。這兩個版本的相同點是:都必須在影象中選擇一個種子點,然後把鄰近區域所有相似點填充上同樣的顏色。不同的是,不一定將所有的臨近畫素點都染上同一顏色。漫水填充操作的結果總是某個連續的區域。當臨近畫素點位於給定的範圍(從loDiff到uoDiff)內或者在原始種子點畫素值範圍內時,就會塗上顏色。

漫水填充:floodFill函式

OpenCV中漫水填充由floodFill函式實現,其作用時用指定的顏色從種子點開始填充一個連通區域。連通性由畫素值的接近程度來衡量。

第一個版本的floodFill:

int floodFill(InputArray image, Point seedPoint, Scalar newVal, Rect* rect=0,Scalar ioDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)

第二個版本的floodFill:

int floodFill(InputArray image, InputArray mask, Point seedPoint, Scalar newVal, Rect* rect=0,Scalar ioDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)

引數詳解(除了第二個引數外,其它引數都是公用的):

  • 第一個引數:輸入影象,1個或3個通道的8位或浮點影象。
  • 第二個引數:InputArray型別的mask,只有第二個版本才有該引數,表示作為掩膜。它應該是單通道,8位,長和寬都比輸入影象大兩個點的影象。因為漫水填充需要使用以及更細掩膜,所以對這個mask引數,我們一定要將其準本好並填在此處。需要注意的是,漫水填充不會填充mask的非零畫素區域。例如,一個邊緣檢測運算元的輸出可以用來作為掩膜,以防止填充到邊緣。同樣的,也可以在多次的函式呼叫中使用同一個掩膜,以保證填充的區域不會重疊。需要注意的是,mask會比需填充的影象大,所以mask與輸入影象(x, y)畫素點對應的座標為(x,+1 y+1)。
  • 第三個引數:Point型別的seedPoint,漫水填充演算法的起始點。
  • 第四個引數:Scalar型別的newVal,畫素被染色的值。
  • 第五個引數:Rect*型別的rect,預設值是0,可選引數,用於設定floodFill函式將要重繪區域的最小邊界矩形區域。
  • 第六個引數:Scalar型別loDiff,預設值是Scalar(),表示當前觀察畫素值與其部件鄰域畫素值或者待加入該部件的種子畫素之間的亮度或顏色之負差的最大值。
  • 第七個引數:Scalar型別upDiff,預設值是Scalar(),表示當前觀察畫素值與其部件鄰域畫素值或者待加入該部件的種子畫素之間的亮度或顏色之正差的最大值。
  • 第八個引數:int型別的flags,操作標誌符。

程式碼示例:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main() {
    Mat srcImage;
    srcImage = imread("/Users/dwz/Desktop/cpp/b.jpg");
    Rect ccomp;
    floodFill(srcImage,Point(150, 150), Scalar(0, 0, 255), &ccomp, Scalar(20, 20, 20),
            Scalar(20, 20, 20));
    imwrite("floodfill.jpg", srcImage);
    return 0;
}

輸入;

輸出: