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

一般的分水岭算法会对微弱边缘,图像中的噪声,物体表面细微的灰度变化造成过度的分割。

以下为分水岭算法的示例程序。

watershedSegmenter.h

#if !defined WATERSHS
#define WATERSHS #include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp> class WatershedSegmenter { private:
Mat markers; public:
//设置标记图
void setMarkers(const Mat& markerImage) { //watershed()的输入参数必须为一个32位有符号的标记,所以要先进行转换
markerImage.convertTo(markers,CV_32S);
}
//执行watershed()
Mat process(const Mat &image) { // Apply watershed
watershed(image,markers); return markers;
} // 以图像形式返回结果
Mat getSegmentation() { Mat tmp;
// 从32S到8U(0-255)会进行饱和运算,所以像素高于255的一律复制为255
markers.convertTo(tmp,CV_8U); return tmp;
} // 以图像形式返回分水岭
Mat getWatersheds() { Mat tmp;
//在设置标记图像,即执行setMarkers()后,边缘的像素会被赋值为-1,其他的用正整数表示
//下面的这个转换可以让边缘像素变为-1*255+255=0,即黑色,其余的溢出,赋值为255,即白色。
markers.convertTo(tmp,CV_8U,,);
return tmp;
}
}; #endif

main.cpp

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "watershedSegmenter.h" using namespace std;
using namespace cv;
int main()
{
//设置视频读入,括号里面的数字是摄像头的选择,一般自带的是0
VideoCapture capture(); if (!capture.isOpened())
{
cout << "can not open the video" << endl;
return -;
} Mat frame;
Mat binImage; bool stop = false;
while (!stop)
{
//读入视频帧,转换颜色空间,并分割通道
capture >> frame;
cvtColor(frame, binImage, CV_BGR2GRAY); threshold(binImage, binImage, , , THRESH_BINARY); //膨胀图像
dilate(binImage, binImage, Mat()); /*分水岭算法*/
//*************************************************************
Mat fg;
//腐蚀图像6次
erode(binImage, fg, Mat(), Point(-, -), );
// Identify image pixels without objects
Mat bg; //膨胀图像6次
dilate(binImage, bg, Mat(), Point(-, -), ); imshow("bg", bg);
//进行固定阈值操作
threshold(bg, bg, , , THRESH_BINARY_INV); // Show markers image
Mat markers(binImage.size(), CV_8U, Scalar());
markers = fg + bg;
imshow("markers image", markers);
WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
segmenter.process(frame); imshow("segmentation", segmenter.getSegmentation());
imshow("Watersheds", segmenter.getWatersheds());
}
waitKey();
return ;
}

最新文章

  1. intellij 调试spark scala 程序 报错
  2. 源码编译安装 MySQL 5.5.x 实践
  3. ASP.NET MVC 实现AJAX跨域请求方法《1》
  4. BSGS[bzoj2242][bzoj3122]
  5. 评分视图的封装 (星星 RatingView)
  6. 3-5年的PHPer常见的面试题
  7. no.1
  8. SQL Server系统数据库
  9. Jquery-json
  10. HW4.25
  11. python学习笔记 改变字符串中的某一位
  12. Django项目创建02
  13. HDU2063-过山车-匈牙利算法
  14. 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)
  15. Python读取配置文件,并连接数据库SQL Server
  16. vs 2012 更新update4 后出现问题
  17. Linux 小知识翻译 - 「Linux」怎么读?
  18. oracle 12.2 linux/solaris正式发布
  19. Arcgis for Js之加载wms服务
  20. charles https抓包 (安卓安装证书)

热门文章

  1. C#this的五种用法
  2. xampp集成安装的mysql修改密码(Window)
  3. 移动端常见的不同苹果手机media query汇总
  4. Cut the sticks
  5. IOS 保存图片至相册
  6. javascript-ajax学习
  7. mysql主从数据库复制
  8. LeetCode_Valid Palindrome
  9. linux系统下svn服务器操作命令
  10. 阵列卡,组成的磁盘组就像是一个硬盘,pci-e扩展出sata3.0