opencv源码学习漫水填充

来源:互联网 发布:客户特殊要求矩阵图 编辑:程序博客网 时间:2024/05/21 07:04

漫水填充就是一种用特定颜色填充连通区域,通过设置可连通像素的上下限以及连通方式达到不同的填充效果的方法。简单来说就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,漫谁填充也可以用来从输入图像中获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点。

代码:

#include"stdafx.h"#include <opencv2/core/utility.hpp>#include "opencv2/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"#include"opencv2/core/core.hpp"#include <iostream>using namespace cv;using namespace std;//描述:全局变量声明//定义原始图,目标图,灰度图,掩码图Mat image, g_srcImage, g_dstImage, g_grayImage, g_maskImage;//漫水填充的模式int g_nFillMode = 1;//负差最大值,正差最大值int g_nLowDifference = 20;int g_nUpDifference = 20;//函数floodFill标识符低八位的连通图int g_nConnectivity = 4;//是否为彩色图的标识符int bIsColor = true;//是否为掩码窗口bool g_bUseMask = false;//重新绘制的像素值int g_nNewMaskVal = 255;void onMouse(int, int, int, int, void*);//-----------------------------------【main( )函数】--------------------------------------------//描述:控制台应用程序的入口函数,我们的程序从这里开始//-----------------------------------------------------------------------------------------------int main(){//改变console字体颜色system("color 4F");//载入原图image = imread("E:\\pictures\\For_Project\\Opencv_Test\\哈尔施特塔\\shufan.jpeg",1);if (!image.data) { printf("Oh,no,读取srcImage错误~! \n"); return false; }//显示原始图namedWindow("【原始图】");imshow("【原始图】", image);g_srcImage = image.clone();//复制原图到目标图g_srcImage.copyTo(g_dstImage);//转换三通道的原图到灰度图cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);//初始化掩码mask大小尺寸g_maskImage.create(g_srcImage.rows + 2, g_srcImage.cols + 2, CV_8UC1);namedWindow("【效果图】", WINDOW_AUTOSIZE);//创建滑动条createTrackbar("负差最大值", "【效果图】", &g_nLowDifference, 255, 0);createTrackbar("正差最大值", "【效果图】", &g_nUpDifference, 255, 0);//鼠标回调函数setMouseCallback("【效果图】", onMouse, 0);//循环按键查询while (1) {//显示效果图imshow("【效果图】", bIsColor ? g_dstImage : g_grayImage);//获取键盘按键值int c = waitKey(0);//判断ESC按键是否按下,是退出if ((c & 255) == 27) {cout << "程序退出!" << endl;break;}//根据按键的不同,进行各种操作switch ((char)c) {case '1':if (bIsColor) {cout << "键盘按下1,切换彩色/灰度模式,当前操作为将【彩色模式】切换为【灰度模式】" << endl;cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);//将mask所有元素设置为0g_maskImage = Scalar::all(0);//标识符设置为false,表示当前图为灰度bIsColor = false;}else {cout << "键盘按下1,切换彩色/灰度模式,当前操作为将【彩色模式】切换为【灰度模式】" << endl;//将mask所有元素设置为0g_srcImage.copyTo(g_dstImage);g_maskImage = Scalar::all(0);//标识符设置为true,表示当前图为彩色bIsColor = true;}break;case '2':if (g_bUseMask) {destroyWindow("mask");g_bUseMask = false;}else {namedWindow("mask", 0);g_maskImage = Scalar::all(0);imshow("mask", g_maskImage);g_bUseMask = true;}break;case '3':cout << "按键3按下,恢复原始图像" << endl;g_srcImage.copyTo(g_dstImage);cvtColor(g_dstImage, g_grayImage, COLOR_BGR2GRAY);g_maskImage = Scalar::all(0);break;case '4':cout << "按键4按下,使用空范围的浸水填充" << endl;g_nFillMode = 0;break;case '5':cout << "按键5按下,使用渐变,固定范围的浸水填充" << endl;g_nFillMode = 1;break;case '6':cout << "按键6按下,使用渐变,固定范围的浸水填充" << endl;g_nFillMode = 2;break;case '7':cout << "按键7按下,操作标识符的低八位使用4位的连接模式" << endl;g_nConnectivity = 4;break;case '8':cout << "按键8按下,操作标识符的低八位使用8位的连接模式" << endl;g_nConnectivity = 8;break;}}//等待键盘按键‘q’退出  while (char(waitKey(1)) != 'q') {}return 0;}void onMouse(int event, int x, int y, int, void*) {if (event != EVENT_LBUTTONDOWN) {return;}Point seed = Point(x, y);int LovDifference = g_nFillMode == 0 ? 0 : g_nLowDifference;int UpDifference = g_nFillMode == 0 ? 0 : g_nUpDifference;int flags = g_nConnectivity + (g_nNewMaskVal << 8) + (g_nFillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);int b = (unsigned)theRNG() & 255;int g = (unsigned)theRNG() & 255;int r = (unsigned)theRNG() & 255;Rect ccomp;Scalar newVal = bIsColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);Mat dst = bIsColor ? g_dstImage : g_grayImage;int area;if (g_bUseMask) {threshold(g_maskImage, g_maskImage, 1, 128, THRESH_BINARY);area = floodFill(dst, g_maskImage, seed, newVal, &ccomp, Scalar(LovDifference, LovDifference,LovDifference), Scalar(UpDifference, UpDifference, UpDifference), flags);imshow("mask", g_maskImage);}else {   area=floodFill(dst,seed,newVal,&ccomp, Scalar(LovDifference, LovDifference, LovDifference),   Scalar(UpDifference, UpDifference, UpDifference), flags);}imshow("【效果图】", dst);cout << area << " 个像素被重绘" << endl;}
效果图:



0 0