分水岭分割方法原理 (3种)
- 基于浸泡理论的分水岭分割方法 (距离)
- 基于连通图的方法
- 基于距离变换的方法 图像形态学操作:
- 腐蚀与膨胀
- 开闭操作 分水岭算法运用
- 分割粘连对象,实现形态学操作与对象计数
- 图像分割

#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; int main(int argc, char** argv) {
Mat src = imread("D:/images/coins_001.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src); Mat gray, binary, shifted;
pyrMeanShiftFiltering(src, shifted, , );
//imshow("shifted", shifted); //灰度
cvtColor(shifted, gray, COLOR_BGR2GRAY);
threshold(gray, binary, , , THRESH_BINARY | THRESH_OTSU);
//imshow("binary", binary); // 距离变换
Mat dist;
distanceTransform(binary, dist, DistanceTypes::DIST_L2, , CV_32F);
normalize(dist, dist, , , NORM_MINMAX);
//imshow("distance result", dist); // 二值化
threshold(dist, dist, 0.4, , THRESH_BINARY);
//imshow("distance binary", dist); // markers
Mat dist_m;
dist.convertTo(dist_m, CV_8U);
vector<vector<Point>> contours;
findContours(dist_m, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(, )); // create markers
Mat markers = Mat::zeros(src.size(), CV_32SC1);
for (size_t t = ; t < contours.size(); t++) {
drawContours(markers, contours, static_cast<int>(t), Scalar::all(static_cast<int>(t) + ), -);
}
circle(markers, Point(, ), , Scalar(), -);
//imshow("markers", markers*10000); // 形态学操作 - 彩色图像,目的是去掉干扰,让结果更好
Mat k = getStructuringElement(MORPH_RECT, Size(, ), Point(-, -));
morphologyEx(src, src, MORPH_ERODE, k); // 完成分水岭变换
watershed(src, markers);
Mat mark = Mat::zeros(markers.size(), CV_8UC1);
markers.convertTo(mark, CV_8UC1);
bitwise_not(mark, mark, Mat());
//imshow("watershed result", mark); // generate random color
vector<Vec3b> colors;
for (size_t i = ; i < contours.size(); i++) {
int r = theRNG().uniform(, );
int g = theRNG().uniform(, );
int b = theRNG().uniform(, );
colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
} // 颜色填充与最终显示
Mat dst = Mat::zeros(markers.size(), CV_8UC3);
int index = ;
for (int row = ; row < markers.rows; row++) {
for (int col = ; col < markers.cols; col++) {
index = markers.at<int>(row, col);
if (index > && index <= contours.size()) {
dst.at<Vec3b>(row, col) = colors[index - ];
}
else {
dst.at<Vec3b>(row, col) = Vec3b(, , );
}
}
} imshow("Final Result", dst);
printf("number of objects : %d\n", contours.size()); waitKey();
return ;
}

#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat watershedCluster(Mat &image, int &numSegments);
void createDisplaySegments(Mat &segments, int numSegments, Mat &image);
int main(int argc, char** argv) {
Mat src = imread("D:/images/cvtest.png");
if (src.empty()) {
printf("could not load image...\n");
return -;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src); int numSegments;
Mat markers = watershedCluster(src, numSegments);
createDisplaySegments(markers, numSegments, src);
waitKey();
return ;
} Mat watershedCluster(Mat &image, int &numComp) {
// 二值化
Mat gray, binary;
cvtColor(image, gray, COLOR_BGR2GRAY);
//阈值
threshold(gray, binary, , , THRESH_BINARY | THRESH_OTSU);
// 形态学与距离变换
Mat k = getStructuringElement(MORPH_RECT, Size(, ), Point(-, -));
morphologyEx(binary, binary, MORPH_OPEN, k, Point(-, -));
Mat dist;
distanceTransform(binary, dist, DistanceTypes::DIST_L2, , CV_32F);
normalize(dist, dist, 0.0, 1.0, NORM_MINMAX); // 开始生成标记
threshold(dist, dist, 0.1, 1.0, THRESH_BINARY);
normalize(dist, dist, , , NORM_MINMAX);
dist.convertTo(dist, CV_8UC1); // 标记开始
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(dist, contours, hireachy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
if (contours.empty()) {
return Mat();
} Mat markers(dist.size(), CV_32S);
markers = Scalar::all();
for (int i = ; i < contours.size(); i++) {
drawContours(markers, contours, i, Scalar(i + ), -, , hireachy, INT_MAX);
}
//填充
circle(markers, Point(, ), , Scalar(), -); // 分水岭变换
watershed(image, markers);
numComp = contours.size();
return markers;
} void createDisplaySegments(Mat &markers, int numSegments, Mat &image) {
// generate random color
vector<Vec3b> colors;
for (size_t i = ; i < numSegments; i++) {
int r = theRNG().uniform(, );
int g = theRNG().uniform(, );
int b = theRNG().uniform(, );
colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
} // 颜色填充与最终显示
Mat dst = Mat::zeros(markers.size(), CV_8UC3);
int index = ;
for (int row = ; row < markers.rows; row++) {
for (int col = ; col < markers.cols; col++) {
index = markers.at<int>(row, col);
if (index > && index <= numSegments) {
dst.at<Vec3b>(row, col) = colors[index - ];
}
else {
dst.at<Vec3b>(row, col) = Vec3b(, , );
}
}
}
imshow("分水岭图像分割-演示", dst);
return;
}

opencv::分水岭图像分割的更多相关文章

  1. Opencv分水岭算法——watershed自动图像分割用法

    分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特 ...

  2. OpenCV 1 图像分割--分水岭算法代码

    // watershed_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" // // ch9_watershed ...

  3. opencv分水岭算法对图像进行切割

    先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...

  4. OpenCV 之 图像分割 (一)

    1  基于阈值 1.1  基本原理 灰度阈值化,是最简单也是速度最快的一种图像分割方法,广泛应用在硬件图像处理领域 (例如,基于 FPGA 的实时图像处理). 假设输入图像为 f,输出图像为 g,则经 ...

  5. Opencv 分水岭分割图片

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  6. opencv::KMeans图像分割

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  7. opencv 金字塔图像分割

    我所知的opencv中分割函数:watershed(只是看看效果,不能返回每类pixel类属),cvsegmentImage,cvPyrSegmentation(返回pixel类属) 金字塔分割原理篇 ...

  8. OpenCV——分水岭算法

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

  9. opencv kmeans 图像分割

    利用kmeans算法,将彩色图像的像素点作为样本,rgb值作为样本的属性, 对图像所有的像素点进行分类,从而实现对图像中目标的分割. c++代码(openCV 2.4.11) Scalar color ...

随机推荐

  1. Angular 学习笔记(二)

    控制器: 就像 JavaScript 里的构造函数一般,用来增强作用域(scope),当一个控制器通过 ng-controller 指令来添加到 DOM 中时, ng 会调用该控制器的构造函数来生成一 ...

  2. Springboot中定时器的简单使用

    在定时器的类上添加注解: @Component@EnableAsync@EnableScheduling 一.普通的定时器: 每天15:10执行的定时器 @Scheduled(cron="0 ...

  3. .net core 发布IIS 出现Http 500错误

    首先再webconfig中设置stdoutLogEnabled="true",然后运行之后,到logs中查看登陆错误日志. 根据不同的错误进行解决: 我的错误是发布文件夹中缺少Dw ...

  4. 第十二章 WEB渗透

    Web技术发展 • 静态WEB• 动态WEB • 应用程序 • 数据库 • 每个人看到的内容不同 • 根据用户输入返回不同结果 WEB攻击面• Network• OS• WEB Server• App ...

  5. 7.2 Spark Streaming

    一.Spark Streaming设计 Spark Streaming可整合多种输入数据源,如Kafka.Flume.HDFS,甚至是普通的TCP套接字.经处理后的数据可存储至文件系统.数据库,或显示 ...

  6. day77_10_24分页器

    一.偏移分页器. 在偏移分页器中,limit代表的是一次性显示的条数,而offset代表的是他基于开头的偏移量. from rest_framework.pagination import Limit ...

  7. 《深度学习》圣经"花书"经验法则中文版!

    作者:Jeff Macaluso https://jeffmacaluso.github.io/post/DeepLearningRulesOfThumb/ 转自CVer,仅用作个人学习 当我在研究生 ...

  8. java jvm虚拟机类加载过程

    加载 在加载阶段, 虚拟机需要完成以下3件事情:1) 通过一个类的全限定名来获取定义此类的二进制字节流.2) 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.3) 在内存中生成一个代表这 ...

  9. 数论2&莫&杜

    积性函数: 积性函数定义ok 积性函数指对于所有互质的整数\(a\)和\(b\)有性质\(f(ab)=f(a)f(b)\)的数论函数 除数函数? 莫比乌斯函数\(\mu\)ok \[ \phi(i) ...

  10. vscode (1.41.0版本,1.41.1版本)node_modules部分TS声明文件@types包会导致该版本没JS语法提示

    正常提示如下: 然而我的提示没了,本以为是插件问题,把所有插件禁用不行!卸载重装vscode还是不行!!但是其他电脑的1.41.1版本,同样代码确没问题!!!简直日了*了 折腾大半天,发下问题如下: ...