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 ...
随机推荐
- java8时间类的一些封装
1.判断平年和闰年 (prolepticYear & 3) == 0 这个条件使用了位运算,与上3在二进制计算下即为:& 00…011.目的是保留最后2位二进制数,然后判断是否最后两位 ...
- R 540
好久没写题解了嘻嘻嘻,昨天补edu自闭了一天还没补完fg这div3令人愉悦. A: #include <bits/stdc++.h> #define mk(a,b) make_pair(a ...
- php算法题2
一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大 ...
- git链接到远程github上
Git链接到自己的Github(1)简单的开始 好长时间没上来弄东西了,今天回来先开始弄下Git,之后再继续写uboot与kernel的编译,在版本控制下更加宏观地观察每次的变化. 1.在ubuntu ...
- linux crontab详解 php开发相关
vi vi /etc/crontab 注意不是这么直接干的! 下面是内容 SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root ...
- SQL基础语法提纲
一.SQL需知5点 1.SQL是Structured Query Language的缩写,是用来访问关系型数据库的,非过程化的,高级编程语言. 2.SQL具有语法高度综合统一,高度的非过程化,对集合进 ...
- CSS弹性盒布局(display:flex)
CSS弹性布局(display:flex) 参考: http://www.runoob.com/w3cnote/flex-grammar.html https://www.jianshu.com/p/ ...
- 判断np.array里面为空字符串的方法
#多在编译器里尝试新操作 import numpy as np for i range(100): eval1 = {"A": ''"} eval2 = {"A ...
- JavaBean-EL-JSTL-MVC
JavaBean规范 类必须使用public修饰 必须保证有公共无参数构造器. (一般就是可以通过反射轻松的创建对象) 包含了属性的操作(给属性赋值,获取属性值). JavaBean中的成 ...
- fiddler学习总结--利用fiddler快速模拟mock
Mock的应用就是在测试接口的时候,去模拟我们想要的接口 1.创建一个txt文件,里面随意写一个json字符串,如图所示: 2.选择目标消息,并且点击“autoresponde”-->“add ...