生活随笔
收集整理的這篇文章主要介紹了
floodFill函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
floodFill函數
函數作用:
用指定顏色填充一個連接域
void cv
FloodFill( CvArr* image, CvPoint seed_point, CvScalar new_val,CvScalar lo_diff=cvScalarAll(0), CvScalar up_diff=cvScalarAll(0),CvConnectedComp* comp=NULL, int flags=4, CvArr* mask=NULL );
#define CV_
FLOODFILL_FIXED_RANGE (1 << 16)
#define CV_
FLOODFILL_MASK_ONLY (1 << 17)
image
輸入的 1- 或 3-通道, 8-比特或浮點數圖像。輸入的圖像將被函數的操作所改變,除非你選擇 CV_FLOODFILL_MASK_ONLY 選項 (見下面).seed_point
開始的種子點.new_val
新的重新繪制的象素值lo_diff
當前觀察象素值與其部件領域象素或者待加入該部件的種子象素之負差(Lower difference)的最大值。對 8-比特 彩色圖像,它是一個 packed value.up_diff
當前觀察象素值與其部件領域象素或者待加入該部件的種子象素之正差(upper difference)的最大值。 對 8-比特 彩色圖像,它是一個 packed value.comp
指向部件結構體的指針,該結構體的內容由函數用重繪區域的信息填充。flags
操作選項. 低位比特包含連通值, 4 (缺省) 或 8, 在函數執行連通過程中確定使用哪種鄰域方式。高位比特可以是 0 或下面的開關選項的組合: - CV_FLOODFILL_FIXED_RANGE - 如果設置,則考慮當前象素與種子象素之間的差,否則考慮當前象素與其相鄰象素的差。(范圍是浮點數).
- CV_FLOODFILL_MASK_ONLY - 如果設置,函數不填充原始圖像 (忽略 new_val), 但填充掩模圖像 (這種情況下 MASK 必須是非空的).
mask
運算掩模, 應該是單通道、8-比特圖像, 長和寬上都比輸入圖像 image 大兩個象素點。若非空,則函數使用且更新掩模, 所以使用者需對 mask 內容的初始化負責。填充不會經過 MASK 的非零象素, 例如,一個邊緣檢測子的輸出可以用來作為 MASK 來阻止填充邊緣。或者有可能在多次的函數調用中使用同一個 MASK,以保證填充的區域不會重疊。注意: 因為 MASK 比欲填充圖像大,所以 mask 中與輸入圖像(x,y)像素點相對應的點具有(x+1,y+1)坐標。
函數 cvFloodFill?用指定顏色,從種子點開始填充一個連通域。連通性由象素值的接近程度來衡量。在點 (x, y) 的象素被認為是屬于重新繪制的區域,如果:
src(x',y')-lo_diff<=src(x,y)<=src(x',y')+up_diff, 灰度圖像,浮動范圍src(seed.x,seed.y)-lo<=src(x,y)<=src(seed.x,seed.y)+up_diff, 灰度圖像,固定范圍
src(x',y')r-lo_diffr<=src(x,y)r<=src(x',y')r+up_diffr 和src(x',y')g-lo_diffg<=src(x,y)g<=src(x',y')g+up_diffg 和src(x',y')b-lo_diffb<=src(x,y)b<=src(x',y')b+up_diffb, 彩色圖像,浮動范圍
src(seed.x,seed.y)r-lo_diffr<=src(x,y)r<=src(seed.x,seed.y)r+up_diffr 和src(seed.x,seed.y)g-lo_diffg<=src(x,y)g<=src(seed.x,seed.y)g+up_diffg 和src(seed.x,seed.y)b-lo_diffb<=src(x,y)b<=src(seed.x,seed.y)b+up_diffb, 彩色圖像,固定范圍
其中 src(x',y') 是象素鄰域點的值。也就是說,為了被加入到連通域中,一個象素的彩色/亮度應該足夠接近于:
- 它的鄰域象素的彩色/亮度值,當該鄰域點已經被認為屬于浮動范圍情況下的連通域。
- 固定范圍情況下的種子點的彩色/亮度值
opencv代碼:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"#include <iostream>using namespace cv;
using namespace std;//floodfill()
//Fills a connected component with the given color.static void help()
{cout << "\nThis program demonstrated the floodFill() function\n""Call:\n""./ffilldemo [image_name -- Default: fruits.jpg]\n" << endl;cout << "Hot keys: \n""\tESC - quit the program\n""\tc - switch color/grayscale mode\n""\tm - switch mask mode\n""\tr - restore the original image\n""\ts - use null-range floodfill\n""\tf - use gradient floodfill with fixed(absolute) range\n""\tg - use gradient floodfill with floating(relative) range\n""\t4 - use 4-connectivity mode\n""\t8 - use 8-connectivity mode\n" << endl;
}Mat image0, image, gray, mask;
int ffillMode = 1;
int loDiff = 20, upDiff = 20;
int connectivity = 4;
int isColor = true;
bool useMask = false;
int newMaskVal = 255;static void onMouse( int event, int x, int y, int, void* )
{if( event != CV_EVENT_LBUTTONDOWN )return;Point seed = Point(x,y);int lo = ffillMode == 0 ? 0 : loDiff;int up = ffillMode == 0 ? 0 : upDiff;int flags = connectivity + (newMaskVal << 8) +(ffillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);int b = (unsigned)theRNG() & 255;int g = (unsigned)theRNG() & 255;int r = (unsigned)theRNG() & 255;Rect ccomp;Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);Mat dst = isColor ? image : gray;int area;if( useMask ){threshold(mask, mask, 1, 128, CV_THRESH_BINARY);area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),Scalar(up, up, up), flags);imshow( "mask", mask );}else{area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),Scalar(up, up, up), flags);}imshow("image", dst);cout << area << " pixels were repainted\n";
}int main( )
{char* filename="0.png";image0 = imread(filename, 1);if( image0.empty() ){cout << "Image empty. Usage: ffilldemo <image_name>\n";return 0;}help();image0.copyTo(image);cvtColor(image0, gray, CV_BGR2GRAY);mask.create(image0.rows+2, image0.cols+2, CV_8UC1);namedWindow( "image", 0 );createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );createTrackbar( "up_diff", "image", &upDiff, 255, 0 );setMouseCallback( "image", onMouse, 0 );for(;;){imshow("image", isColor ? image : gray);int c = waitKey(0);if( (c & 255) == 27 ){cout << "Exiting ...\n";break;}switch( (char)c ){case 'c':if( isColor ){cout << "Grayscale mode is set\n";cvtColor(image0, gray, CV_BGR2GRAY);mask = Scalar::all(0);isColor = false;}else{cout << "Color mode is set\n";image0.copyTo(image);mask = Scalar::all(0);isColor = true;}break;case 'm':if( useMask ){destroyWindow( "mask" );useMask = false;}else{namedWindow( "mask", 0 );mask = Scalar::all(0);imshow("mask", mask);useMask = true;}break;case 'r':cout << "Original image is restored\n";image0.copyTo(image);cvtColor(image, gray, CV_BGR2GRAY);mask = Scalar::all(0);break;case 's':cout << "Simple floodfill mode is set\n";ffillMode = 0;break;case 'f':cout << "Fixed Range floodfill mode is set\n";ffillMode = 1;break;case 'g':cout << "Gradient (floating range) floodfill mode is set\n";ffillMode = 2;break;case '4':cout << "4-connectivity mode is set\n";connectivity = 4;break;case '8':cout << "8-connectivity mode is set\n";connectivity = 8;break;}}return 0;
}
總結
以上是生活随笔為你收集整理的floodFill函数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。