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 ...
随机推荐
- vb编程中的选择结构语句的写法
1996年,Bohra和Jacopin提出了结构化算法的3中种基本结构:顺序结构.选择结构和循环结构 目前已经得到证明,无论多么复杂的程序,都是由上面的3种基本结构中的一种或者多种的组合构成 在此笔者 ...
- Laravel 5.4设置logout注销账户的重定向路径
当我们修改Laravel默认Auth默认路径时,在点击logout按钮注销时,默认跳转的地址为项目的根目录, 若想设置成自定义的重定向路径,可以按照如下设置: 方法一: 在Auth \ LoginCo ...
- javascript 缩写技巧
19种JS高(炫)效(技)缩写法 https://segmentfault.com/a/1190000011229633
- 补充:MySQL修改表
- ERROR org.hibernate.hql.internal.ast.ErrorCounter unexpected token: form 异常解决
ERROR org.hibernate.hql.internal.ast.ErrorCounter unexpected token: form 异常解决 根据异常提示:我找了我的MySQL语句:果然 ...
- RDLC报表刷新问题
使用RDLC做报表,当数据源发生改变时重新绑定数据发现报表没有变化,跟踪时发现数据绑定已经正确执行,前端也显示了加载过程,但内容未刷新. 在代码中使用了 ReportViewer1.LocalRepo ...
- Java如何获取图片验证码保存
举例网站:https://my.1hai.cn/Login/?url=http://www.1hai.cn/ 一.场景:出于安全性考虑,越来越多的Web平台登录都会增加图形验证码(图片),或者短信验证 ...
- 修改jupyter notebook的默认打开地址
1)在Anaconda Prompt终端中输入下面命令,查看你的notebook配置文件在哪里: jupyter notebook --generate-config 2)通过搜索关键词:c.Note ...
- 深入理解Java虚拟机1-chap1-2-斗之气8段
1.HotSpot VM:热点代码探测能力,与JIT技术共同进行编译优化,输出高质量代码 2.运行时数据区域 程序计数器:控制程序执行顺序,无OOM Java虚拟机栈:生命周期与线程一致,描述Java ...
- WIN7虚拟桌面创建(多屏幕多桌面)
Windows7/WIN7虚拟桌面怎么用怎么创建多桌面(摘录) 在使用电脑中经常会遇到桌面软件太多了不够用的感慨,那么要是一台电脑有多个桌面就好了.在windows10中自带已经支持了虚拟桌面,在wi ...