一、简介


二、分水岭算法

1 #include "opencv2/opencv.hpp"
2 using namespace cv;
3
4 void main()
5 {
6 Mat srcImg = imread("E://bird.jpg");
7 imshow("src", srcImg);
8 Mat dstImg = srcImg.clone();
9 //medianBlur(srcImg, srcImg, 5);
10 //GaussianBlur(srcImg, srcImg, Size(5, 5), 0, 0);
11 Mat imgMask(srcImg.size(), CV_8U, Scalar(0));//标记图像
12 //标示背景图像
13 rectangle(imgMask, Point(1, 1), Point(srcImg.cols - 2, srcImg.rows - 2), Scalar(255), 4);
14 //标示鸟
15 rectangle(imgMask, Point(srcImg.cols / 2 - 10, srcImg.rows / 2 - 10), Point(srcImg.cols / 2 + 10, srcImg.rows / 2 + 10), Scalar(128), 10);
16 //标示岩石
17 rectangle(imgMask, Point(264, 353), Point(314, 395), Scalar(64), 10);
18 imshow("mask", imgMask);
19
20 imgMask.convertTo(imgMask, CV_32S);
21 watershed(srcImg, imgMask); //调用分水岭算法
22 Mat mark1, mark2;
23 imgMask.convertTo(mark1, CV_8U);
24 imshow("mark1", mark1);
25
26 Mat mark3 = mark1.clone();
27 bitwise_not(mark1, mark2);//图像取反
28 imshow("mark2", mark2);
29 threshold(mark1, mark1, 64, 255, CV_THRESH_TOZERO_INV);//CV_THRESH_TOZERO_INV:大于阈值都为0,其余正常 找出岩石
30 threshold(mark2, mark2, 127, 255, CV_THRESH_TOZERO_INV);//因为取反后背景为0,所以筛选掉岩石后剩下的即为鸟
31 threshold(mark3, mark3, 128, 255, CV_THRESH_BINARY);//鸟为128,大于128才能为255,所以找出了背景
32
33 vector<vector<Point>> contours;
34 vector<Vec4i> hierarcy;
35 findContours(mark1, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
36 drawContours(dstImg, contours, -1, Scalar(0, 255, 0), -1, 8);
37
38 vector<vector<Point>> contours2;
39 vector<Vec4i> hierarcy2;
40 findContours(mark2, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
41 drawContours(dstImg, contours2, -1, Scalar(0, 0, 255), -1, 8);
42
43 vector<vector<Point>> contours3;
44 vector<Vec4i> hierarcy3;
45 findContours(mark3, contours3, hierarcy3, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
46 drawContours(dstImg, contours3, -1, Scalar(255, 0, 0), -1, 8);
47
48 Mat result = srcImg*0.5 + dstImg*0.5;
49 imshow("result", result);
50 waitKey(0);
51 }

三、图像修补

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

四、祛痘
1 #include "opencv2/opencv.hpp"
2 using namespace cv;
3
4 #define WINDOW_NAME0 "【原始图参考】"
5 #define WINDOW_NAME1 "【原始图】"
6 #define WINDOW_NAME2 "【修补后的效果图】"
7
8 Mat srcImage0, srcImage1, inpaintMask;
9 Point previousPoint(-1, -1);//原来的点坐标
10
11 static void ShowHelpText()
12 {
13 printf("
当前使用的OpenCV版本为:" CV_VERSION);
14 printf("
----------------------------------------------------------------------------
");
15
16 printf("
请在进行图像修复操作之前,在【原始图】窗口中进行适量的绘制"
17 "
按键操作说明:
"
18 " 【鼠标左键】-在图像上绘制白色线条
"
19 " 键盘按键【ESC】- 退出程序
"
20 " 键盘按键【2】- 恢复原始图像
"
21 " 键盘按键【1】或【SPACE】-进行图像修复操作
");
22 }
23
24 //-----------------------------------【On_Mouse( )函数】--------------------------------
25 // 描述:响应鼠标消息的回调函数
26 //----------------------------------------------------------------------------------------------
27 static void On_Mouse(int event, int x, int y, int flags, void*)
28 {
29 //鼠标左键弹起消息
30 if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))//提取flags的CV_EVENT_FLAG_LBUTTON的标志位,!()的意思是标志位无效,即鼠标左键不是拖拽动作
31 previousPoint = Point(-1, -1);
32 //鼠标左键按下消息
33 else if (event == CV_EVENT_LBUTTONDOWN)
34 previousPoint = Point(x, y);
35 //鼠标按下并移动,进行绘制
36 else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
37 {
38 Point pt(x, y);
39 if (previousPoint.x < 0)
40 previousPoint = pt;
41 //绘制白色线条
42 line(inpaintMask, previousPoint, pt, Scalar::all(255), 5, 8, 0);
43 line(srcImage1, previousPoint, pt, Scalar::all(255), 5, 8, 0);
44 previousPoint = pt;
45 imshow(WINDOW_NAME1, srcImage1);
46 }
47 }
48
49 void main()
50 {
51 system("color 2F");
52 ShowHelpText();
53
54 //载入原始图并进行掩膜的初始化
55 Mat srcImage = imread("face.jpg", -1);
56 if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~!
"); return; }
57 srcImage0 = srcImage.clone();
58 srcImage1 = srcImage.clone();
59 inpaintMask = Mat::zeros(srcImage1.size(), CV_8U);
60
61 imshow(WINDOW_NAME0, srcImage0);
62 imshow(WINDOW_NAME1, srcImage1);
63 //设置鼠标回调消息
64 setMouseCallback(WINDOW_NAME1, On_Mouse, 0);
65
66 //轮询按键,根据不同的按键进行处理
67 while (1)
68 {
69 //获取按键键值
70 char c = (char)waitKey();
71 //键值为ESC,程序退出
72 if (c == 27)
73 break;
74 //键值为2,恢复成原始图像
75 if (c == '2')
76 {
77 inpaintMask = Scalar::all(0);
78 srcImage.copyTo(srcImage1);
79 imshow(WINDOW_NAME1, srcImage1);
80 }
81 //键值为1或者空格,进行图像修补操作
82 if (c == '1' || c == ' ')
83 {
84 Mat inpaintedImage;
85 inpaint(srcImage1, inpaintMask, inpaintedImage, 3, CV_INPAINT_TELEA);
86 imshow(WINDOW_NAME2, inpaintedImage);
87 }
88 }
89 }

