基本思想

分水岭(watershed)是地形学中的一个经典概念,例如美国落基山脉分水岭,将美国分为两个区域,落在这个分水岭一边的雨滴,最终会到达大西洋,但是落在另一边的雨滴,最终回流到太平洋。为了提取分水岭,人们提出了各种各样的算法,在这些算法中,Vincent和Soille提出了一种基于模拟沉浸的实现方法。在图像处理领域,灰度图像可以被视为地形表面,图像中每个像素的灰度代表这点的高度,其每一个局部极小值(local minima)及其影响区域成为集水盆地(catchments basin)。这样分水岭便被引入图像处理中来。设想每个区域底部刺了一个孔,水从刺过孔的海拔最低的谷底开始往上涌,慢慢地淹没图像的整个区域。当来自不同谷底的水即将汇合时,筑起一道假想的水坝来阻止它。浸没过程结束时,每个区域被水淹没,并被水坝完全包围。这些筑起的水坝确定了对应区域的分水岭,对应于图像的轮廓。此方法不仅速度更快,大大缩短了执行时间,而且结果也更加准确,这使得此算法具有使用价值。(摘自《医学图像处理及三维重建技术研究》[M])

示例演示

这里展示OpenCV Demo watershed。完整代码

#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"#include <cstdio>
#include <iostream>using namespace cv;
using namespace std;static void help(char** argv)
{cout << "\nThis program demonstrates the famous watershed segmentation algorithm in OpenCV: watershed()\n""Usage:\n" << argv[0] << " [image_name -- default is fruits.jpg]\n" << endl;cout << "Hot keys: \n""\tESC - quit the program\n""\tr - restore the original image\n""\tw or SPACE - run watershed segmentation algorithm\n""\t\t(before running it, *roughly* mark the areas to segment on the image)\n""\t  (before that, roughly outline several markers on the image)\n";
}
Mat markerMask, img;
Point prevPt(-1, -1);static void onMouse(int event, int x, int y, int flags, void*)
{if (x < 0 || x >= img.cols || y < 0 || y >= img.rows)return;if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))prevPt = Point(-1, -1);else if (event == EVENT_LBUTTONDOWN)prevPt = Point(x, y);else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)){Point pt(x, y);if (prevPt.x < 0)prevPt = pt;line(markerMask, prevPt, pt, Scalar::all(255), 5, 8, 0);line(img, prevPt, pt, Scalar::all(255), 5, 8, 0);prevPt = pt;imshow("image", img);}
}int main(int argc, char** argv)
{cv::CommandLineParser parser(argc, argv, "{help h | | }{ @input | fruits.jpg | }");if (parser.has("help")){help(argv);return 0;}//string filename = samples::findFile(parser.get<string>("@input"));string filename = "D:\\TestData\\fruits.jpg";Mat img0 = imread(filename, 1), imgGray;if (img0.empty()){cout << "Couldn't open image ";help(argv);return 0;}help(argv);namedWindow("image", 1);img0.copyTo(img);cvtColor(img, markerMask, COLOR_BGR2GRAY);cvtColor(markerMask, imgGray, COLOR_GRAY2BGR);markerMask = Scalar::all(0);imshow("image", img);setMouseCallback("image", onMouse, 0);for (;;){char c = (char)waitKey(0);if (c == 27)break;if (c == 'r'){markerMask = Scalar::all(0);img0.copyTo(img);imshow("image", img);}if (c == 'w' || c == ' '){int i, j, compCount = 0;vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(markerMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);if (contours.empty())continue;Mat markers(markerMask.size(), CV_32S);markers = Scalar::all(0);int idx = 0;for (; idx >= 0; idx = hierarchy[idx][0], compCount++)drawContours(markers, contours, idx, Scalar::all(compCount + 1), -1, 8, hierarchy, INT_MAX);if (compCount == 0)continue;vector<Vec3b> colorTab;for (i = 0; i < compCount; i++){int b = theRNG().uniform(0, 255);int g = theRNG().uniform(0, 255);int r = theRNG().uniform(0, 255);colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));}double t = (double)getTickCount();watershed(img0, markers);t = (double)getTickCount() - t;printf("execution time = %gms\n", t*1000. / getTickFrequency());Mat wshed(markers.size(), CV_8UC3);// paint the watershed imagefor (i = 0; i < markers.rows; i++)for (j = 0; j < markers.cols; j++){int index = markers.at<int>(i, j);if (index == -1)wshed.at<Vec3b>(i, j) = Vec3b(255, 255, 255);else if (index <= 0 || index > compCount)wshed.at<Vec3b>(i, j) = Vec3b(0, 0, 0);elsewshed.at<Vec3b>(i, j) = colorTab[index - 1];}wshed = wshed * 0.5 + imgGray * 0.5;imshow("watershed transform", wshed);}}return 0;
}

运行结果

图像分割之分水岭分割算法相关推荐

  1. 基于标记的分水岭分割算法

    分水岭技术是一种众所周知的分割算法,特别适用于提取图片中的相邻或重叠对象.使用分水岭方法时,我们必须从用户定义的标记开始.这些标记可以使用点击手动定义,也可以使用阈值或形态学处理方法定义. 分水岭技术 ...

  2. 基于matlab山脊线,基于Matlab的标记分水岭分割算法

    lyqmath 1 综述 Separating touching objects in an image is one of the more difficult image processing o ...

  3. matlab迭代分水岭分割,matlab分水岭分割算法

    single [-1, 1] double 17-17 17-17 Normalized Difference Vegetation Index NDVI with Threshold Applied ...

  4. 基于Matlab的标记分水岭分割算法(imreconstruct)

    1 综述 Separating touching objects in an image is one of the more difficult image processing operation ...

  5. OpenCV watershed分水岭分割算法的实例(附完整代码)

    OpenCV watershed分水岭分割算法的实例 OpenCV watershed分水岭分割算法的实例 OpenCV watershed分水岭分割算法的实例 #include <opencv ...

  6. 做形态学方法的团队_图像分割实战-分水岭分割方法和GrabCut 算法

    1. 分水岭分割方法 它是依赖于形态学的,图像的灰度等级不一样,如果图像的灰度等级一样的情况下怎么人为的把它造成不一样?可以通过距离变换实现,这样它们的灰度值就有了阶梯状的变换.风水岭算法常见的有三种 ...

  7. OpenCV分水岭分割算法2

    分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用,例如上图中的硬币. 使用传统的图像处理方法,如阈值和轮廓检测,我们将无法从图像中提取每一个硬币,但通过利用分水岭算法,我们能够检 ...

  8. python图像分割算法_Opencv(二)—图像分割之分水岭算法!

    做图像处理时,我们可能会遇到一个问题:我们只需要图片的一部分区域,如何把图片中的某部分区域提取出来 或者 图像想要的区域用某种颜色(与其它区域颜色不一致)标记起来 ,以上描述的问题在像处理领域称为 图 ...

  9. 图像分割之分水岭算法

    使用C++.opencv进行分水岭分割图像 分水岭概念是以对图像进行三维可视化处理为基础的:其中两个是坐标,另一个是灰度级.基于"地形学"的这种解释,我们考虑三类点: a.属于局部 ...

最新文章

  1. 区块链分叉如何解决_什么是分叉区块链又该如何分叉
  2. jinjia2 模板不解析html
  3. mysql max_allowed_packet查询和修改
  4. 如何在 CentOS 7上安装和使用 Docker Compose
  5. mysql十万条数据_2秒内向数据库中插入十万条数据?
  6. linux服务器内存占用太高-释放内存
  7. Openlayers 详细记录controls(控件)
  8. [剪视频]Premiere快速从入门到实战
  9. OPENWRT,爱快等软路由推荐
  10. 【全自动网盘扩容软件使用教程】百度网盘自助无限扩容+自助无限修复软件使用步骤说明
  11. python父亲节祝福_2020年精选优美的父亲节祝福语28条
  12. [Leetcode] 382. Linked List Random Node 解题报告
  13. could not initialize proxy - the owning Session was closed解决
  14. MATLAB绘制三维曲面图和等高线 绘图(2)
  15. Python性能分析利器pyinstrument讲解
  16. 祈福医疗冲刺港股:年营收12亿 经营利润2.27亿
  17. GetAsyncKeyState函数中按键的信息
  18. Pycharm激活步骤
  19. 2020牛客暑期多校训练营(第八场)E Enigmatic Partition —— 找规律,差分上差分,有丶东西
  20. Cosmos 基础 -- Ignite CLI(一)

热门文章

  1. sklearn代码9 7-KNN-salay
  2. 李欣桐 计算机竞赛,【赛出精彩】我校举行数学计算能力竞赛活动
  3. 保送清华计算机,2018年北大、清华五大学科竞赛集训队保送生争夺战结果
  4. prompt learning——你需要掌握的基础知识以及离散型 prompt 的代码
  5. 【论文阅读】MobileNet V2——MobileNetV2: Inverted Residuals and Linear Bottlenecks
  6. Layui环境下form表单提交;jquery.form.js;lay-verify,lay-filter;
  7. 高速公路上边有没有人脸识别摄像头_支小蜜初高中智慧校园人脸识别消费系统...
  8. Ubuntu18.04设置截屏快捷方式
  9. 公司邮箱后缀有哪些?外贸邮箱域名有哪些你知道吗?
  10. 服务器2012分辨率不能修改,《F1 2012》无法修改分辨率解决方法