opencv学习之路(30)、分水岭算法及图像修补
一、简介


二、分水岭算法

#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat srcImg = imread("E://bird.jpg");
imshow("src", srcImg);
Mat dstImg = srcImg.clone();
//medianBlur(srcImg, srcImg, 5);
//GaussianBlur(srcImg, srcImg, Size(5, 5), 0, 0);
Mat imgMask(srcImg.size(), CV_8U, Scalar());//标记图像
//标示背景图像
rectangle(imgMask, Point(, ), Point(srcImg.cols - , srcImg.rows - ), Scalar(), );
//标示鸟
rectangle(imgMask, Point(srcImg.cols / - , srcImg.rows / - ), Point(srcImg.cols / + , srcImg.rows / + ), Scalar(), );
//标示岩石
rectangle(imgMask, Point(, ), Point(, ), Scalar(), );
imshow("mask", imgMask); imgMask.convertTo(imgMask, CV_32S);
watershed(srcImg, imgMask); //调用分水岭算法
Mat mark1, mark2;
imgMask.convertTo(mark1, CV_8U);
imshow("mark1", mark1); Mat mark3 = mark1.clone();
bitwise_not(mark1, mark2);//图像取反
imshow("mark2", mark2);
threshold(mark1, mark1, , , CV_THRESH_TOZERO_INV);//CV_THRESH_TOZERO_INV:大于阈值都为0,其余正常 找出岩石
threshold(mark2, mark2, , , CV_THRESH_TOZERO_INV);//因为取反后背景为0,所以筛选掉岩石后剩下的即为鸟
threshold(mark3, mark3, , , CV_THRESH_BINARY);//鸟为128,大于128才能为255,所以找出了背景 vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(mark1, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(dstImg, contours, -, Scalar(, , ), -, ); vector<vector<Point>> contours2;
vector<Vec4i> hierarcy2;
findContours(mark2, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(dstImg, contours2, -, Scalar(, , ), -, ); vector<vector<Point>> contours3;
vector<Vec4i> hierarcy3;
findContours(mark3, contours3, hierarcy3, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(dstImg, contours3, -, Scalar(, , ), -, ); Mat result = srcImg*0.5 + dstImg*0.5;
imshow("result", result);
waitKey();
}

三、图像修补

#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat srcImg = imread("E://snow.jpg"); Mat mask(srcImg.size(), CV_8U, Scalar());
rectangle(mask, Point(, ), Point(, srcImg.rows), Scalar(), -, ); Point org = Point(, );
putText(srcImg, "OpenCV", org, CV_FONT_HERSHEY_SIMPLEX, 2.2f, CV_RGB(, , ), );
imshow("src", srcImg); //putText( mask, "OpenCV", org, CV_FONT_HERSHEY_SIMPLEX, 2.2f, CV_RGB(255,255,255),2);
rectangle(mask, Point(, ), Point(srcImg.cols, srcImg.rows), Scalar(), -, );
imshow("mask", mask); Mat result;
inpaint(srcImg, mask, result, , CV_INPAINT_NS); //图像修复 imshow("result", result);
waitKey();
}

四、祛痘
#include "opencv2/opencv.hpp"
using namespace cv; #define WINDOW_NAME0 "【原始图参考】"
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【修补后的效果图】" Mat srcImage0, srcImage1, inpaintMask;
Point previousPoint(-, -);//原来的点坐标 static void ShowHelpText()
{
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
printf("\n\n ----------------------------------------------------------------------------\n"); printf("\n\t请在进行图像修复操作之前,在【原始图】窗口中进行适量的绘制"
"\n\n\t按键操作说明: \n\n"
"\t\t【鼠标左键】-在图像上绘制白色线条\n\n"
"\t\t键盘按键【ESC】- 退出程序\n\n"
"\t\t键盘按键【2】- 恢复原始图像\n\n"
"\t\t键盘按键【1】或【SPACE】-进行图像修复操作 \n\n");
} //-----------------------------------【On_Mouse( )函数】--------------------------------
// 描述:响应鼠标消息的回调函数
//----------------------------------------------------------------------------------------------
static void On_Mouse(int event, int x, int y, int flags, void*)
{
//鼠标左键弹起消息
if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))//提取flags的CV_EVENT_FLAG_LBUTTON的标志位,!()的意思是标志位无效,即鼠标左键不是拖拽动作
previousPoint = Point(-, -);
//鼠标左键按下消息
else if (event == CV_EVENT_LBUTTONDOWN)
previousPoint = Point(x, y);
//鼠标按下并移动,进行绘制
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
Point pt(x, y);
if (previousPoint.x < )
previousPoint = pt;
//绘制白色线条
line(inpaintMask, previousPoint, pt, Scalar::all(), , , );
line(srcImage1, previousPoint, pt, Scalar::all(), , , );
previousPoint = pt;
imshow(WINDOW_NAME1, srcImage1);
}
} void main()
{
system("color 2F");
ShowHelpText(); //载入原始图并进行掩膜的初始化
Mat srcImage = imread("face.jpg", -);
if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return; }
srcImage0 = srcImage.clone();
srcImage1 = srcImage.clone();
inpaintMask = Mat::zeros(srcImage1.size(), CV_8U); imshow(WINDOW_NAME0, srcImage0);
imshow(WINDOW_NAME1, srcImage1);
//设置鼠标回调消息
setMouseCallback(WINDOW_NAME1, On_Mouse, ); //轮询按键,根据不同的按键进行处理
while ()
{
//获取按键键值
char c = (char)waitKey();
//键值为ESC,程序退出
if (c == )
break;
//键值为2,恢复成原始图像
if (c == '')
{
inpaintMask = Scalar::all();
srcImage.copyTo(srcImage1);
imshow(WINDOW_NAME1, srcImage1);
}
//键值为1或者空格,进行图像修补操作
if (c == '' || c == ' ')
{
Mat inpaintedImage;
inpaint(srcImage1, inpaintMask, inpaintedImage, , CV_INPAINT_TELEA);
imshow(WINDOW_NAME2, inpaintedImage);
}
}
}


opencv学习之路(30)、分水岭算法及图像修补的更多相关文章
- opencv学习之路(11)、图像几何变换
一.图像缩放 #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat src=imread("E:// ...
- opencv学习之路(13)、图像阈值化threshold
一.图像阈值化简介 二.固定阈值 三.自适应阈值 #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat src ...
- opencv学习之路(12)、图像滤波
一.图像滤波简介 二.方框滤波——boxFilter() #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat ...
- opencv分水岭算法对图像进行切割
先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...
- 新手学,java使用分水岭算法进行图像切割(一)
近期被图像切割整的天昏地暗的,在此感谢老朋友周洋给我关于分水岭算法的指点!本来打算等彩色图像切割有个完满的结果再写这篇文章,可是考虑到到了这一步也算是一个阶段,所以打算对图像切割做一个系列的博文,于是 ...
- Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练
在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资 ...
- opencv学习之路(40)、人脸识别算法——EigenFace、FisherFace、LBPH
一.人脸识别算法之特征脸方法(Eigenface) 1.原理介绍及数据收集 特征脸方法主要是基于PCA降维实现. 详细介绍和主要思想可以参考 http://blog.csdn.net/u0100066 ...
- Opencv学习之路——自己编写的HOG算法
#include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv ...
- python学习之路-6 冒泡算法、递归、反射、os/sys模块详解
算法 冒泡算法 # 冒泡算法就是将需要排序的元素看作是一个个"气泡",最小的"气泡"最先浮出水面,排在最前面.从小到大依次排列. # 代码如下: li = [9 ...
随机推荐
- thymeleaf入门和学习
springboot框架不推荐使用jsp,一方面是兼容性的技术问题,一方面也是其前后端整合在一起,很难适合当下大规模的网站开发环境.HTML只是一种标记语言,并不具有获取model中数据的功能,所以视 ...
- M - COURSES
Consider a group of N students and P courses. Each student visits zero, one or more than one courses ...
- hdu2074 叠筐
叠筐 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...
- Java课程寒假之开发记账本软件(网页版)之一
一.制定网页版记账本的基础功能 首先是下载了几个记账本APP,大致地看了一下记账本的功能:添加记录(支出,收入,自定义模板),查询流水(分类查询),账户. 二.开始做出框架 鉴于记账本有上面的功能,所 ...
- python_代码中调用java类
1. 安装jpype (python调用java class文件用) 1.1. 自动安装:pip install jpype1 1.2. 手动方式安装jpype1 安装wheel:pip instal ...
- 第一个微信小程序踩的几个小坑
1.小程序测试调试阶段可以打开项目设置中的“开发环境不校验请求域名.TLS版本及HTTPS证书”配置,即可以和自己的服务器联调了. (需要在工具栏的设置 -> 项目设置 中配置,mac下直接co ...
- redis3.0.3集群搭建
redis3.0版本之后支持Cluster,具体介绍redis集群我就不多说,了解请看redis中文简介. 首先,直接访问redis.io官网,下载redis.tar.gz,现在版本3.0.3,我下面 ...
- maven工程下添加oracle驱动包
maven工程手动安装oracle驱动包到本地仓库 下载ojdbc.jar包 这个当然是最好去官网下载了.http://mvnrepository.com这个仓库上有,具体页面地址为: http:// ...
- 3、LwIP协议栈规范翻译——概述
3.概述 像许多其他TCP/IP实现一样,分层协议设计已经成为设计lwIP实现的指南.每个协议实现为自己的模块,其中几个功能充当每个协议的入口点.尽管协议层是单独实现的,一些层却不全是,正如前面所叙述 ...
- python练习题-day11
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), 要求:登录成功一次,后续的函数都无需再输入用户名和密码 flag=False def wrapper(fun): def inn ...