FloodFill和掩码
来源:互联网 发布:华为软件商店 编辑:程序博客网 时间:2024/05/23 18:28
原文地址:http://blog.csdn.net/u011630458/article/details/44260119
简介
本篇主要是介绍opencv的FloodFill(漫水填充)和基于它实现的物体选取。
FloodFill使用
FloodFill函数
C++: int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 );
InputOutputArray:输入和输出图像。 mask: 输入的掩码图像。 seedPoint: 算法开始处理的开始位置。 newVal: 图像中所有被算法选中的点,都用这个数值来填充。 rect: 最小包围矩阵。 loDiff: 最大的低亮度之间的差异。 upDiff: 最大的高亮度之间的差异。 flag: 选择算法连接方式。
简单的说,就是选中点seedPoint,然后选取出它周围和它色彩差异不大的点,并将它们的值改为newVal。如果被选取的点,遇到mask掩码,则放弃对该方向的蔓延填充。
具体代码
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <iostream>
- using namespace cv;
- using namespace std;
- int loDiff = 20, upDiff = 20;
- Mat image0, image, mask;
- int newMaskVal = 255;
- static void onMouse( int event, int x, int y, int, void* ){
- Mat dst = image;
- Point seed = Point(x,y);
- Scalar newVal = Scalar(0, 0, 0);
- Rect ccomp;
- int lo = loDiff;
- int up = upDiff;
- int flags = 8 + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE;
- floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo), Scalar(up, up, up), flags);
- imshow("11", dst);
- }
- int main( int argc, char** argv ){
- char* filename = argv[1];
- image0 = imread(filename, 1);
- image0.copyTo(image);
- mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
- cv::rectangle(mask,cvPoint(0, 0),cvPoint(100, 100),cvScalar(255,255,255), 8);
- namedWindow( "image", 0);
- createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
- createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
- imshow("11", image);
- imshow("22", mask);
- setMouseCallback("11", onMouse, 0 );
- waitKey(0);
- return 0;
- }
代码讲解
1、装载需要被处理的图片到image0,接着复制图片信息到image。
- char* filename = argv[1];
- image0 = imread(filename, 1);
- image0.copyTo(image);
2、设置掩码,注意掩码大小需要是图片长宽+2。接着框选了一个矩形的掩码区域。
- mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
- tangle(mask,cvPoint(0, 0),cvPoint(100, 100),cvScalar(255,255,255), 8);
3、设置了两个Trackbar,用来可以动态设置loDiff和upDiff的大小。
- namedWindow( "image", 0);
- createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
- createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
4、显示原图像和掩码图像,同时注册了mouse处理函数。
- imshow("11", image);
- imshow("22", mask);
- setMouseCallback("11", onMouse, 0 );
5、鼠标选取参考点,设置floodFill使用动态蔓延的8连通算法,显示出被floodFill处理后图片。
- static void onMouse( int event, int x, int y, int, void* ){
- Mat dst = image;
- Point seed = Point(x,y);
- Scalar newVal = Scalar(0, 0, 0);
- Rect ccomp;
- int lo = loDiff;
- int up = upDiff;
- int flags = 8 + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE;
- floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo), Scalar(up, up, up), flags);
- imshow("11", dst);
- }
效果演示
1、原图像:
2、掩码图像:
3、选择天空之后的生成图像:
物体选取
所谓的物体选取,就是首先探测出图像的边沿,然后用边沿作为掩码,接着用FloodFill来处理选择选取的点。
具体代码
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <opencv2/core/core.hpp>
- #include <opencv2/core/mat.hpp>
- #include <math.h>
- #include <string.h>
- #include <opencv/cv.h>
- #include <stdio.h>
- #include "xihua_2.h"
- #include <iostream>
- using namespace cv;
- using namespace std;
- int loDiff = 20, upDiff = 20;
- Mat image0, image, mask;
- int newMaskVal = 255;
- int ratio = 3;
- int kernel_size = 3;
- int lowThreshold = 43;
- class MorphoFeatures{
- private:
- cv::Mat cross;
- cv::Mat diamond;
- cv::Mat square;
- cv::Mat x;
- public:
- cv::Mat getEdges(const cv::Mat &image){
- cv::Mat result;
- cv::morphologyEx(image,result,cv::MORPH_GRADIENT,cv::Mat());
- applyThreshold(result);
- return result;
- }
- void applyThreshold(cv::Mat & result){
- cv::threshold(result,result, 40,255,cv::THRESH_BINARY);
- }
- };
- MorphoFeatures morpho;
- void MyResize(Mat& mat1, Mat& mat2, int width, int height){
- IplImage pI_1 = mat1, pI_2;
- mat2 = cv::Mat(width, height, CV_8UC1, 1);
- pI_2 = mat2;
- cvResize(&pI_1, &pI_2, 1);
- }
- static void onMouse( int event, int x, int y, int, void* ){
- Mat dst = image;
- Point seed = Point(x,y);
- Scalar newVal = Scalar(0, 0, 0);
- Rect ccomp;
- int lo = loDiff;
- int up = upDiff;
- int flags = 8 + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE;
- if(event == CV_EVENT_LBUTTONDOWN){
- floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo), Scalar(up, up, up), flags);
- imshow("22", dst);
- }
- }
- int main( int argc, char** argv ){
- char* filename = argv[1];
- image0 = imread(filename, 1);
- if( image0.empty() ){
- cout << "Image empty. Usage: ffilldemo <image_name>\n";
- return 0;
- }
- image0.copyTo(image);
- mask.create(image0.rows, image0.cols, CV_8UC1);
- mask = morpho.getEdges(image);
- cvtColor(mask, mask, COLOR_BGR2GRAY);
- MyResize(mask, mask, image0.rows+2, image0.cols+2);
- namedWindow( "image", 0);
- createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
- createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
- imshow("00", mask);
- imshow("11", image);
- setMouseCallback("11", onMouse, 0 );
- waitKey(0);
- return 0;
- }
代码讲解
很多都和前面FloodFill使用例子的代码一样,这里只讲下mask掩码相关部分。首先创造掩码图像,接着使用morpho.getEdges获取到原图像image的边沿,并保存到掩码图像中,然后更具函数FloofFill的要求,将mask图像大小调整为原图像长宽+2。
- mask.create(image0.rows, image0.cols, CV_8UC1);
- mask = morpho.getEdges(image);
- cvtColor(mask, mask, COLOR_BGR2GRAY);
- MyResize(mask, mask, image0.rows+2, image0.cols+2);
效果演示
1、原图像:
2、掩码图像:
3、选择花盆之后的生成图像:
0 0
- FloodFill和掩码
- 掩码、反掩码和通配符
- floodfill
- floodfill
- floodfill
- 32种掩码和反掩码
- 掩码
- 掩码
- 掩码
- 掩码
- 关于add和Floodfill的记录
- bzoj1102 [POI2007]山峰和山谷Grz floodfill
- [C#] MaskedTextBox掩码元素说明和常用掩码组合
- MaskedTextBox 掩码元素说明和常用掩码组合
- cocos2dx 3.x 物理引擎接触检测掩码、碰撞掩码和类别掩码问题解析
- 说说一些少见的IP和掩码
- 布尔运算和应用掩码运算
- Linux信号掩码和信号处理函数
- Glide加载圆形图片第一次只显示默认图片
- 安卓沉浸式状态栏
- Java 数组初始化
- ORACLE 查看表和表字段注释
- java编程思想学习(1)
- FloodFill和掩码
- 通过降级提高系统的可用性
- java-rmi(060701)
- oracle数据库表解锁
- 利用PHPMailer 来完成PHP的邮件发送
- Linux下安装ROracle包
- 大数据最清楚王宝强离婚事件到底有多热!
- Hibernate关联关系配置(一对多、一对一和多对多)
- μC/OS-Ⅲ系统中的任务种类及基本状态