分水岭分割方法原理 (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. Git:SSH、SSH与HTTP区别、git常用命令

    SSH1.首先需要检查你电脑是否已经有 SSH key cd ~/.sshls12.ssh表示ssh文件是个隐藏文件查看是否存在 id_rsa.pub 或 id_dsa.pub 文件,如果文件已经存在 ...

  2. 【微信小程序】安装EsayWechat简化微信小程序的开发

    1.安装easywechat composer require "overtrue/laravel-wechat" 2.文档 EasyWhchat官方文档

  3. Angular 学习笔记(一)

    什么是 Angular: Angular 是一个 JavaScript 框架,可通过 <script> 标签添加到 HTML 页面,然后通过指令扩展 HTML,且通过表达式绑定数据到 HT ...

  4. python中的随机模块random

    random模块是 python 中为随机数所使用的模块 ```import random # 随机生成0-1范围内的随机浮点数i = random.random()print(i) # 随机生成范围 ...

  5. eclipse C++ 配置自动提示

    转:http://www.cnblogs.com/myitm/archive/2010/12/17/1909194.html 定位到:Windows→Preferences→Java→Editor→C ...

  6. linux 安装PostgreSQL12

    一.安装步骤 1.设置保存安装包的目录 # cd /usr/local/src 2.开始下载源包 # wget https://ftp.postgresql.org/pub/source/v12.1/ ...

  7. UEFI Install CentOS 7

    bios必须设置u盘为第一启动项 编辑E:\EFI\BOOT\grub.cfg中所有inst.stage2=hd:LABEL=*与卷标名称一致(区分大小写)(linux系统写入镜像无需修改) inst ...

  8. [C2P2] Andrew Ng - Machine Learning

    ##Linear Regression with One Variable Linear regression predicts a real-valued output based on an in ...

  9. NG-ZORRO 使用相关

    Upload上传 import { Component, Input, Output, EventEmitter, Inject } from '@angular/core'; import { Nz ...

  10. Serializers 序列化组件——ModelSerializer详解

    前面学习Serializers用法时,发现所有的序列化都与我们的模型紧密相关. django_restframework也给我提供了跟模型紧密相关的序列化器——ModelSerializer. 它会根 ...