一、简介
二、分水岭算法
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("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION); 14 printf("\n\n ----------------------------------------------------------------------------\n"); 15 16 printf("\n\t请在进行图像修复操作之前,在【原始图】窗口中进行适量的绘制" 17 "\n\n\t按键操作说明: \n\n" 18 "\t\t【鼠标左键】-在图像上绘制白色线条\n\n" 19 "\t\t键盘按键【ESC】- 退出程序\n\n" 20 "\t\t键盘按键【2】- 恢复原始图像\n\n" 21 "\t\t键盘按键【1】或【SPACE】-进行图像修复操作 \n\n"); 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函数指定图片存在~! \n"); 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 }