分水岭算法及图像修补

转自:https://blog.csdn.net/abc8730866/article/details/69668703,感谢原创作者!

1.分水岭算法——watershed()

2.图像修补——inpaint()

先上ppt:










代码:1.分水岭算法

[cpp]  view plain  copy
  1. ///分水岭算法  
  2. #include "opencv2/opencv.hpp"  
  3. using namespace cv;  
  4. int main()  
  5. {  
  6.     Mat srcImg = imread("bird.jpg",CV_LOAD_IMAGE_COLOR);  
  7.     imshow("srcImg", srcImg);  
  8.     Mat copyImg = srcImg.clone();  
  9.     //1.定义标记图像markers  
  10.     Mat markers(srcImg.size(),CV_8UC1,Scalar(0));  
  11.     //标记背景  
  12.     rectangle(markers,Point(1,1),Point(srcImg.cols-2,srcImg.rows-2),Scalar(255),1,8);  
  13.     //标记鸟  
  14.     rectangle(markers, Point(srcImg.cols / 2 - 20, srcImg.rows / 2 - 20), Point(srcImg.cols / 2 +20, srcImg.rows / 2 + 20), Scalar(128), -1, 8);  
  15.     //标记石头  
  16.     rectangle(markers, Point(srcImg.cols / 2 - 30, srcImg.rows - 50), Point(srcImg.cols / 2 + 60, srcImg.rows - 10), Scalar(64), -1, 8);  
  17.     imshow("markers-input",markers);  
  18.     //2.基于标记图像的分水岭算法  
  19.     //将markers转换成32位单通道图像(分水岭函数要求)  
  20.     markers.convertTo(markers,CV_32S);  
  21.     //分水岭算法  
  22.     watershed(srcImg,markers);  
  23.     //将markers转换成8位单通道  
  24.     markers.convertTo(markers, CV_8UC1);  
  25.     imshow("markers-output", markers);  
  26.     //3.提取轮廓并绘制轮廓  
  27.     Mat mark1, mark2,mark3;  
  28.     mark1 = markers.clone();//提取鸟的轮廓  
  29.     mark2 = markers.clone();//提取石头轮廓  
  30.     mark3 = markers.clone();//提取背景轮廓  
  31.     //阈值化,黑中找白,找鸟  
  32.     threshold(mark1,mark1,129,255,CV_THRESH_TOZERO_INV);  
  33.     threshold(mark1,mark1,120,255,CV_THRESH_TOZERO);  
  34.     //阈值化,黑中找白,找石头  
  35.     threshold(mark2, mark2, 65, 255, CV_THRESH_TOZERO_INV);  
  36.     //阈值化,黑中找白,找背景  
  37.     threshold(mark3, mark3, 129, 255, CV_THRESH_BINARY);  
  38.     imshow("mark1", mark1);  
  39.     imshow("mark2", mark2);  
  40.     imshow("mark3", mark3);  
  41.     //寻找背景轮廓并绘制  
  42.     vector<vector<Point>> contours3;  
  43.     findContours(mark3, contours3, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);  
  44.     drawContours(copyImg, contours3, -1, Scalar(0, 0, 255), -1, 8);  
  45.     //寻找鸟轮廓并绘制  
  46.     vector<vector<Point>> contours1;  
  47.     findContours(mark1,contours1,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);  
  48.     drawContours(copyImg,contours1,-1,Scalar(255,0,0),-1,8);  
  49.     //寻找石头轮廓并绘制  
  50.     vector<vector<Point>> contours2;  
  51.     findContours(mark2, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);  
  52.     drawContours(copyImg, contours2, -1, Scalar(0, 255, 0), -1, 8);  
  53.     imshow("copyImg",copyImg);  
  54.     //4.与原图像叠加  
  55.     Mat result = srcImg*0.5 + copyImg*0.5;  
  56.     imshow("result", result);  
  57.     waitKey(0);  
  58.     return 0;  
  59. }  

运行结果:





代码:2.图像修补

[cpp]  view plain  copy
  1. ///图像修补  
  2. #include "opencv2/opencv.hpp"  
  3. using namespace cv;  
  4. //定义原图像srcImg和目标图像dstImg  
  5. Mat srcImg = imread("face.JPG", CV_LOAD_IMAGE_COLOR);  
  6. Mat dstImg = srcImg.clone();  
  7. //定义掩码inpaintMask,同srcImg一样大小,类型为8位单通道,初始化为纯黑(掩码非0部分起作用)  
  8. Mat inpaintMask(srcImg.size(), CV_8UC1, Scalar(0));  
  9. //定义鼠标左键是否按下的标志flag  
  10. bool flag=false;  
  11. //记录鼠标左键按下时的初始坐标  
  12. int xStart, yStart;  
  13. void onMouse(int event,int x,int y,int flags,void* param)  
  14. {  
  15.     switch (event)  
  16.     {  
  17.     case CV_EVENT_LBUTTONDOWN:  
  18.         flag = true;//鼠标左键按下,flag置为true  
  19.         xStart = x;//记录鼠标左键按下时的坐标  
  20.         yStart = y;  
  21.         break;  
  22.     case CV_EVENT_MOUSEMOVE:  
  23.         if (flag)  
  24.         {  
  25.             //在srcImg中画矩形,白色,向内填充  
  26.             rectangle(srcImg, Point(xStart, yStart), Point(x, y), Scalar(255, 255, 255), -1, 8);  
  27.             //在inpaintMask中画矩形,白色,向内填充  
  28.             rectangle(inpaintMask, Point(xStart, yStart), Point(x, y), Scalar(255, 255, 255), -1, 8);  
  29.         }  
  30.         break;  
  31.     case CV_EVENT_LBUTTONUP:  
  32.         flag = false;//鼠标左键抬起,flag置为false  
  33.         break;  
  34.     default:  
  35.         break;  
  36.     }  
  37.     //重新显示原图srcImg  
  38.     imshow("inpaint", srcImg);  
  39.     //重新显示掩码图像inpaintMask  
  40.     imshow("inpaintMask", inpaintMask);  
  41. }  
  42.   
  43. int main()  
  44. {     
  45.     imshow("srcImg", srcImg);  
  46.     //定义窗口"inpaint"  
  47.     namedWindow("inpaint",CV_WINDOW_AUTOSIZE);  
  48.     //设置鼠标回调函数  
  49.     setMouseCallback("inpaint",onMouse);  
  50.     //使得一开始就显示窗口"inpaint",显示原图srcImg  
  51.     imshow("inpaint", srcImg);  
  52.     //使得一开始就显示窗口"inpaintMask",显示掩码图像inpaintMask  
  53.     imshow("inpaintMask", inpaintMask);  
  54.     //使得一开始就显示窗口"dstImg",显示目标图像dstImg  
  55.     imshow("dstImg", dstImg);  
  56.     //无限循环,若按下空格键(ASCII码为32),则调用inpait()函数,重新显示目标图像dstImg  
  57.     while (1)  
  58.     {  
  59.         if (waitKey(0) == 32)//若按下空格键  
  60.         {  
  61.             //调用inpait()函数, 重新显示目标图像dstImg  
  62.             inpaint(srcImg, inpaintMask, dstImg, 4, CV_INPAINT_NS);  
  63.             imshow("dstImg", dstImg);  
  64.         }  
  65.     }  
  66.     waitKey(0);  
  67.     return 0;  
  68. }  

运行结果:





猜你喜欢

转载自blog.csdn.net/song_esther/article/details/80157946