C++:void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize)

参数详解:

InputArray src:输入的图像,一般为二值图像

OutputArray dst:输出的图像

int distanceType:所用的求解距离的类型、

It can be CV_DIST_L1, CV_DIST_L2 , or CV_DIST_C

mask_size  距离变换掩模的大小,可以是 3 或 5. 对 CV_DIST_L1 或 CV_DIST_C 的情况,参数值被强制设定为 3, 因为 3×3 mask 给出 5×5 mask 一样的结果,而且速度还更快。

mask
用户自定义距离情况下的 mask。 在 3×3 mask 下它由两个数(水平/垂直位量,对角线位移量)组成, 5×5 mask 下由三个数组成(水平/垂直位移量,对角位移和 国际象棋里的马步(马走日))

  1 #include <opencv2/opencv.hpp>
  2 #include <iostream>
  3
  4 using namespace cv;
  5 using namespace std;
  6
  7 Mat src;
  8
  9 int main(int argc, char** argv)
 10 {
 11     src = imread("分水岭.jpg");
 12     if (src.empty())
 13     {
 14         printf("Can not load Image...");
 15         return -1;
 16     }
 17     imshow("input Image",src);
 18
 19     //白色背景变成黑色
 20     for (int row=0;row<src.rows;row++)
 21     {
 22         for (int col = 0; col < src.cols; col++) {
 23             if (src.at<Vec3b>(row, col) == Vec3b(255, 255, 255)) {
 24                 src.at<Vec3b>(row, col)[0] = 0;
 25                 src.at<Vec3b>(row, col)[1] = 0;
 26                 src.at<Vec3b>(row, col)[2] = 0;
 27             }
 28         }
 29     }
 30     imshow("black backgroung", src);
 31
 32     //sharpen(提高对比度)
 33     Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);
 34
 35     //make it more sharp
 36     Mat imgLaplance;
 37     Mat sharpenImg = src;
 38     //拉普拉斯算子实现边缘提取
 39     filter2D(src, imgLaplance, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);//拉普拉斯有浮点数计算,位数要提高到32
 40     src.convertTo(sharpenImg, CV_32F);
 41
 42     //原图减边缘(白色)实现边缘增强
 43     Mat resultImg = sharpenImg - imgLaplance;
 44
 45     resultImg.convertTo(resultImg,CV_8UC3);
 46     imgLaplance.convertTo(imgLaplance, CV_8UC3);
 47     imshow("sharpen Image", resultImg);
 48
 49     //转换成二值图
 50     Mat binary;
 51     cvtColor(resultImg, resultImg, CV_BGR2GRAY);
 52     threshold(resultImg, binary,40,255,THRESH_BINARY|THRESH_OTSU);
 53     imshow("binary image",binary);
 54
 55     //距离变换
 56     Mat distImg;
 57     distanceTransform(binary,distImg,DIST_L1,3,5);
 58     normalize(distImg, distImg, 0, 1, NORM_MINMAX);
 59     imshow("dist image",distImg);
 60
 61     //二值化
 62     threshold(distImg, distImg, 0.4, 1, THRESH_BINARY);
 63     imshow("dist binary image", distImg);
 64
 65     //腐蚀(使得连在一起的部分分开)
 66     Mat k1 = Mat::ones(3, 3, CV_8UC1);
 67     erode(distImg, distImg, k1);
 68     imshow("分开", distImg);
 69
 70     //标记
 71     Mat dist_8u;
 72     distImg.convertTo(dist_8u,CV_8U);
 73     vector<vector<Point>> contours;
 74     findContours(dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
 75
 76     //创建标记
 77     Mat marker = Mat::zeros(src.size(),CV_32SC1);
 78
 79     //画标记
 80     for (size_t i = 0; i < contours.size(); i++)
 81     {
 82         drawContours(marker,contours,static_cast<int>(i),Scalar(static_cast<int>(i)+1),-1);
 83     }
 84
 85     circle(marker, Point(5, 5), 3, Scalar(255, 255, 255), -1);
 86     imshow("marker",marker*1000);
 87
 88     //分水岭变换
 89     watershed(src,marker);//根据距离变换的标记,在原图上分离
 90     Mat water = Mat::zeros(marker.size(),CV_8UC1);
 91     marker.convertTo(water,CV_8UC1);
 92     bitwise_not(water, water,Mat());//取反操作
 93     //imshow("源 image", src);
 94     imshow("watershed Image", water);
 95
 96     // generate random color
 97     vector<Vec3b> colors;
 98     for (size_t i = 0; i < contours.size(); i++) {
 99         int r = theRNG().uniform(0, 255);
100         int g = theRNG().uniform(0, 255);
101         int b = theRNG().uniform(0, 255);
102         colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
103     }
104
105     // fill with color and display final result
106     Mat dst = Mat::zeros(marker.size(), CV_8UC3);
107     for (int row = 0; row < marker.rows; row++) {
108         for (int col = 0; col < marker.cols; col++) {
109             int index = marker.at<int>(row, col);
110             if (index > 0 && index <= static_cast<int>(contours.size())) {
111                 dst.at<Vec3b>(row, col) = colors[index - 1];
112             }
113             else {
114                 dst.at<Vec3b>(row, col) = Vec3b(0, 0, 0);
115             }
116         }
117     }
118     imshow("Final Result", dst);
119     waitKey(0);
120     return 0;
121 }

转载于:https://www.cnblogs.com/long5683/p/9692845.html

OpenCV——距离变换与分水岭算法的(图像分割)相关推荐

  1. OpenCV(26)图像分割 -- 距离变换与分水岭算法(硬币检测、扑克牌检测、车道检测)

    目录 一.基础理论 1.思想 2.原理 二.分水岭实战:硬币 步骤归纳 1.把原图像转二值图 2.开运算去噪 3.确定背景区域(膨胀)(得到背景/最大连通域) 4.确定前景区域(距离变换) (分离)( ...

  2. OpenCV距离变换和分水岭算法的图像分割

    OpenCV距离变换和分水岭算法的图像分割 距离变换和分水岭算法的图像分割 目标 代码 说明/结果 距离变换和分水岭算法的图像分割 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: f ...

  3. Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm)

    Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm) ############################ ...

  4. OpenCV | 分水岭算法进行图像分割

    分水岭算法进行图像分割 分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称 ...

  5. 图像处理:分水岭算法(图像分割)

    图像处理:分水岭算法(图像分割) 分水岭算法 分水岭算法是一种图像区域分割法,分割的过程中将图片转化为灰度图,然后我会将灰度值看作是海拔,然后向较低点注水,这种基于地形学的解释,我们着重考虑三种点: ...

  6. opencv进阶学习笔记14:分水岭算法 实现图像分割

    基础版学习笔记目录: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 分水岭算法原理 分水岭算法 ...

  7. opencv python 基于分水岭算法的图像分割

    Image Segmentation with Watershed Algorithm 理论 任何灰度图像都可以看作是地形表面,其中高强度表示山峰和丘陵,而低强度表示山谷.用不同颜色的水(标签)填充每 ...

  8. opencv28:分水岭算法的图像分割

    目标 在本章中,将学习 使用分水岭算法实现基于标记的图像分割 函数:cv2.watershed() 理论 任何灰度图像都可以看作是一个地形表面,其中高强度的像素表示山峰,低强度表示山谷.可以用不同颜色 ...

  9. OpenCV 距离变换的笔记

    目前正在学习<图像处理,分析与机器视觉>里面有提到距离变换计算,以此笔记记录生活.  距离变换的定义 :计算图像中像素点到最近零像素点的距离,也就是零像素点的最短距离. Mat srcIm ...

  10. OpenCV 源码中分水岭算法 watershed 函数源码注解

    为了研究分水岭算法,阅读了OpenCV 2.4.9 中watershed函数的源码实现部分,代码位于 opencv\sources\modules\imgproc\src\segmentation.c ...

最新文章

  1. Intellij Idea创建一个简单的java项目
  2. 领课网络在线教育系统开源项目
  3. 河海大学839计算机技术基础,2017年河海大学计算机与信息学院839通信原理考研强化模拟题...
  4. notepad json格式化插件_Prettier + ESLint VSCode 插件配置指南
  5. MATLAB调用Python自定义函数(类、函数等) Python调用MATLAB
  6. Java 编解码问题
  7. 前端 JavaScript 复制粘贴的奥义——Clipboard 对象概述
  8. python文件怎么打开_py文件怎么打开?
  9. 【持续更新】总结国内外图形学物理模拟相关学者和网站
  10. 5G时代芯片之王——射频芯片
  11. 2022飞鸟,飞鸟源码,飞鸟新圣源码,仿新圣源码,飞鸟二开,飞鸟采集,飞鸟运营版
  12. uoj #172. 【WC2016】论战捆竹竿
  13. 顶级域名、一级域名、二级域名、子域名如何区分
  14. 发现一个美女,在黑夜中独自YY.
  15. 利用网线在两台电脑之间传输文件
  16. github本地项目上传到远程仓库
  17. 什么是勒索病毒,勒索病毒简介,电脑中病毒了怎么修复
  18. 用mirai做机器人方法
  19. 论文阅读笔记《Matching Images With Multiple Descriptors: An Unsupervised Approach for Locally Adaptive》
  20. 金山pdf独立版右键菜单

热门文章

  1. 熬了一个通宵,终于把Reids的7千万个Key删完了,今天脑子都嗡嗡响!
  2. 小型电商Web架构!小而美!值得学习!
  3. 这才是真正的薪资水平
  4. 如何选择 Offer?
  5. 2019夏软工暑期随笔3
  6. python + selenium 获取标签文本的为空解决办法
  7. RQNOJ 95 多多看DVD(加强版):01背包
  8. java 源码分析1 -String
  9. 如何对 Oracle 数据泵(expdp/impdp) 进行 debug
  10. C# .Net中的类型转换(5)