分水岭分割方法原理 (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. Qt 显示图片

    QImage qImag("img.jpg"); //qImag = qImag.scaled(width, height); //缩放图片 qImag = qImag.scale ...

  2. 9.python3实用编程技巧进阶(四)

    4.1.如何读写csv数据 爬取豆瓣top250书籍 import requests import json import csv from bs4 import BeautifulSoup book ...

  3. FileSizeLimitExceededException

    org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException 很明显,这异常的意思是文件大小 ...

  4. ssh 使用指定网卡 连接特定网络

    有时候,当电脑有两个网卡时:一个网卡 连接免费网络,一个网卡连接收费网络.这样当你想使用免费网络与远程服务器建立连接,使用诸如scp命令或者 ssh 隧道之类传输大文件.这时候你需要指定特定的特定的网 ...

  5. 4. 海思Hi3519A MPP从入门到精通(四 视频输出)

    VO(Video Output,视频输出)模块主动从内存相应位置读取视频和图形数据,并通过相应的显示设备输出视频和图形. 1. 基本概念 3519A芯片支持的显示/回写设备.视频层和图形层见下表. 注 ...

  6. [PHP] Ubuntu快速安装起PHP7.4

    先安装一下这个命令 add-apt-repositoryapt-get install software-properties-common 添加第三方源:add-apt-repository ppa ...

  7. Flask Rest接口

    Flask适用于简单的接口请求 安装 pip install Flask pip install Flask-RESTful 仅简单请求url,然后出发处理程序,返回处理结果 app.py代码如下 f ...

  8. 13.Java基础_数组内存图

    单个数组内存图 new int[3]: 在堆内存里申请一块空间存储int类型的变量(初始化时值都为0) int[] array: 在栈内存申请一块内存存储堆内存里数组的首地址 array[i]: 通过 ...

  9. C++中的异常处理(中)

    为什么要在catch中重新抛出异常? #include <iostream> #include <string> using namespace std; void Demo( ...

  10. python 生成sql语句

    1. 别名 s = '' name = ['张三', '李四', '王五'] for i in range(len(name)): s += "'" + name[i] + &qu ...