漫水填充法

  在OpenCV里有一个函数,为
void cvFloodFill(IplImage* src,CvPoint seedPoint,	//漫水法从点seedPoint开始实行算法
CvScalar newVal,	//像素点被染色的值CvScalar loDiff = cvScalarAll(0),	//下标记--被染色的相邻点减去
loDiffCvScalar upDiff = cvScalarAll(0),	//上标记--被染色的相邻点加上
upDiffCvConnectedComp* comp = NULL,	//如果comp不是NULL,那么该CvConnectedComp被设置为被填充区域的统计属性
int flags = 4,	
/*低八位可以被设置为4或者8,这个参数控制着填充算法的连通性,4表示在4个方向考虑连通性(上下左右),*8表示在8个方向考虑连通性(加上4个对角线方向),高八位可以设置CV_FLOODFILL_FIXED_RANGE,或者*CV_FLOODFILL_MASK_ONLY(如果设置只考虑填充MASK),flags的中间比特(8-15位)的值可以设置填充掩码的值*flags = 8 | CV_FLOODFILL_MASK_ONLY | CV_FLOODFILL_FIXED_RANGE | (43<<8)*/
CvArr* mask = NULL	
/*mask参数与其他有mask参数的使用方法一致,不同的是可以是作为该函数的输出值(指定应经被填充的区域)*如果mask非空,那么它必须是一个单通道,8位,像素宽度和高度均比源图像大两个像素的图像*(这是为使内部运算简单快速),cvFloodFill()不会覆盖mask中非0的区域*/);


  对于此函数所用的算法,并没有仔细去分析它的代码。而是认识了两种比较简单的算法。分别如下:
算法一:递归算法

void floodFill(int x, int y, int fill, int old)
{
  if ((x < 0) || (x >= width)) return;
  if ((y < 0) || (y >= height)) return;
  if (getPixel(x, y) == old)
  {
    setPixel(fill, x, y);
    floodFill(x+1, y, fill, old);
    floodFill(x, y+1, fill, old);
    floodFill(x-1, y, fill, old);
    floodFill(x, y-1, fill, old);
  }
}


8邻域的填充过种也是一样,此算法的过程简单易懂,效率也较高,但由于函数的反复调用会使操作系统的栈溢出。

算法二:基于行一致性的算法

(1)将种子点入栈;

while(栈非空)

{

(2)将种子点出栈;

(3)填充联通的此行;

(4)并将邻域内联通的上下行中的一行最右边的点作为种子点入栈;

}


此算法的缺点是会造成很多点的重复访问。
详细算法实现请参照维基百科:

http://en.wikipedia.org/wiki/Flood_fill


你可能感兴趣的:(算法,null)