这种填充算法首先要选择一个种子点,然后把邻近区域所有相似点填充上同样颜色,大多数的填充算法都与cvFloodFill()类似。
cvFloodFill(img,CvPoint seedPoint,CvScalar newVal,CvScalar loDiff,CvScalar upDiff,
CvConnectedComp *comp,int flags,CvArr *mask);
img为输入图像;seedPoint为种子点;newVal是像素点被染色的值;
lo_diff , up_diff 的解释就是 如果一个像素点的值不低于被染色的相邻点减去lo_diff 且不高于其加上up_diff,那么该像素点就会被染色。这个解释很是纠结搞得我有点混乱,只能在程序中直观的去观察这两个参数的作用了;
comp ,指向部件结构体的指针,该结构体的内容由函数用重绘区域的信息填充。opencv中的默认设置为NULL。
flags 参数比较复杂,包含3部分,低8位部分(0—7位)可以设置为4或8,这个参数控制填充算法的连通性,就是说填充时是采用4连通还是8连通的方式;
高8位(16-23)可以是 0 或下面的开关选项的组合:
CV_FLOODFILL_FIXED_RANGE - 如果设置,则考虑当前象素与种子象素之间的差在指定范围内才填充,否则考虑当前象素与其相邻象素的差是否落在指定范围内;
CV_FLOODFILL_MASK_ONLY - 如果设置,函数不填充原始图像 (忽略 new_val), 但填充掩码图像 (这种情况下 MASK 必须是非空的). 此时必须输入符合要求的掩码。
flags中间比特位(8-15位)的值指定填充掩码图像的值。
所有flags可以通过or操作连接起来,比如,用4领域填充,并填充固定像素值范围,是填充掩码而不是填充源图像,以及填充值为58,则flags在opencv中的输入参数可以设置为:
flags=4|CV_FLOODFILL_FIXED_RANGE|CV_FLOODFILL_MASK_ONLY|(58<<8);
mask 为运算掩码,比输入图像大2个像素点,既可以作填充函数的输入值也可以做输出。如果mask,那么它必须是一个单通道、8位、像素宽度和高度均比源图大2个像素的图像。
IplImage *src; //源图像
IplImage *mask; //掩码图像
IplImage *src1;
int lodiff = 20, updiff = 20;
int connectivity = 4;
int new_mask_val = 255;
void onmouse(int event, int x, int y, int flags, void *param)
{
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
{
CvPoint seed = cvPoint(x, y);
int b = rand() & 255, g = rand() & 255, r = rand() & 255;//随机找到一个颜色
CvConnectedComp comp;
CvScalar color = CV_RGB(r, g, b);
int flags = connectivity | CV_FLOODFILL_FIXED_RANGE | (new_mask_val<< 8);
cvFloodFill(src, seed, color, CV_RGB(lodiff, lodiff, lodiff), CV_RGB(updiff, updiff, updiff), &comp, flags, mask);
cvShowImage("image", src);
printf("%g pixels were repainted\n", comp.area);
}
break;
case CV_EVENT_RBUTTONDOWN:
cvShowImage("image", src1);
break;
}
}
int main(int argc, char ** argv)
{
src = cvLoadImage("G:/Learning/Machine_version/Photo/11.jpg", 1);
src1 = cvCloneImage(src);
/*********************************创建掩码图像****************************/
IplImage *mask = cvCreateImage(cvSize(src->width + 2, src->height + 2), 8, 1);
cvNamedWindow("image", CV_WINDOW_AUTOSIZE);
/******************创建滑动条**********************************/
cvCreateTrackbar("loDiff", "image", &lodiff, 255, NULL);
cvCreateTrackbar("upDiff", "image", &updiff, 255, NULL);
/********************定义鼠标响应函数****************************/
cvSetMouseCallback("image", onmouse, NULL);
cvShowImage("image", src);
cvWaitKey(0);
cvReleaseImage(&mask);
cvReleaseImage(&src);
cvDestroyWindow("image");
return 1;
}
cvFloodFill漫水填充算法
最新推荐文章于 2024-07-11 17:01:08 发布