运行环境:ubuntu16.04+Qt+opencv2.4.13.3

watershed.cpp

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace cv;
using namespace std; Vec3b RandomColor(int value); //生成随机颜色函数 int main( char argc, char* argv[] )
{
Mat image=imread("/home/osksh/skin_c/06Apr03Face.jpg"); // Mat image=imread('/home/osksh/skin_c/family.jpg'); //载入RGB彩色图像
imshow("Source Image",image); //灰度化,滤波,Canny边缘检测
Mat imageGray;
cvtColor(image,imageGray,CV_RGB2GRAY);//灰度转换
GaussianBlur(imageGray,imageGray,Size(,),); //高斯滤波
imshow("Gray Image",imageGray);
Canny(imageGray,imageGray,,);
imshow("Canny Image",imageGray); //查找轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(imageGray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
Mat imageContours=Mat::zeros(image.size(),CV_8UC1); //轮廓
Mat marks(image.size(),CV_32S); //Opencv分水岭第二个矩阵参数
marks=Scalar::all();
int index = ;
int compCount = ;
for( ; index >= ; index = hierarchy[index][], compCount++ )
{
//对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点
drawContours(marks, contours, index, Scalar::all(compCount+), , , hierarchy);
drawContours(imageContours,contours,index,Scalar(),,,hierarchy);
} //我们来看一下传入的矩阵marks里是什么东西
Mat marksShows;
convertScaleAbs(marks,marksShows);
imshow("marksShow",marksShows);
imshow("轮廓",imageContours);
watershed(image,marks); //我们再来看一下分水岭算法之后的矩阵marks里是什么东西
Mat afterWatershed;
convertScaleAbs(marks,afterWatershed);
imshow("After Watershed",afterWatershed); //对每一个区域进行颜色填充
Mat PerspectiveImage=Mat::zeros(image.size(),CV_8UC3);
for(int i=;i<marks.rows;i++)
{
for(int j=;j<marks.cols;j++)
{
int index=marks.at<int>(i,j);
if(marks.at<int>(i,j)==-)
{
PerspectiveImage.at<Vec3b>(i,j)=Vec3b(,,);
}
else
{
PerspectiveImage.at<Vec3b>(i,j) =RandomColor(index);
}
}
}
imshow("After ColorFill",PerspectiveImage); //分割并填充颜色的结果跟原始图像融合
Mat wshed;
addWeighted(image,0.4,PerspectiveImage,0.6,,wshed);
imshow("AddWeighted Image",wshed); waitKey();
} Vec3b RandomColor(int value)
{
value=value%; //生成0~255的随机数
RNG rng;
int aa=rng.uniform(,value);
int bb=rng.uniform(,value);
int cc=rng.uniform(,value);
return Vec3b(aa,bb,cc);
}

#include"opencv2/imgproc/imgproc.hpp"
#include"opencv2/highgui/highgui.hpp"

#include<iostream>

usingnamespacecv;
usingnamespacestd;

Vec3bRandomColor(intvalue);//生成随机颜色函数

intmain(charargc,char*argv[])
{
Matimage=imread("/home/osksh/skin_c/06Apr03Face.jpg");

//Matimage=imread('/home/osksh/skin_c/family.jpg');//载入RGB彩色图像
imshow("SourceImage",image);

//灰度化,滤波,Canny边缘检测
MatimageGray;
cvtColor(image,imageGray,CV_RGB2GRAY);//灰度转换
GaussianBlur(imageGray,imageGray,Size(,),);//高斯滤波
imshow("GrayImage",imageGray);
Canny(imageGray,imageGray,,);
imshow("CannyImage",imageGray);

//查找轮廓
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(imageGray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
MatimageContours=Mat::zeros(image.size(),CV_8UC1);//轮廓
Matmarks(image.size(),CV_32S);//Opencv分水岭第二个矩阵参数
marks=Scalar::all();
intindex=;
intcompCount=;
for(;index>=;index=hierarchy[index][],compCount++)
{
//对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点
drawContours(marks,contours,index,Scalar::all(compCount+),,,hierarchy);
drawContours(imageContours,contours,index,Scalar(),,,hierarchy);
}

//我们来看一下传入的矩阵marks里是什么东西
MatmarksShows;
convertScaleAbs(marks,marksShows);
imshow("marksShow",marksShows);
imshow("轮廓",imageContours);
watershed(image,marks);

//我们再来看一下分水岭算法之后的矩阵marks里是什么东西
MatafterWatershed;
convertScaleAbs(marks,afterWatershed);
imshow("AfterWatershed",afterWatershed);

//对每一个区域进行颜色填充
MatPerspectiveImage=Mat::zeros(image.size(),CV_8UC3);
for(inti=;i<marks.rows;i++)
{
for(intj=;j<marks.cols;j++)
{
intindex=marks.at<int>(i,j);
if(marks.at<int>(i,j)==-)
{
PerspectiveImage.at<Vec3b>(i,j)=Vec3b(,,);
}
else
{
PerspectiveImage.at<Vec3b>(i,j)=RandomColor(index);
}
}
}
imshow("AfterColorFill",PerspectiveImage);

//分割并填充颜色的结果跟原始图像融合
Matwshed;
addWeighted(image,0.4,PerspectiveImage,0.6,,wshed);
imshow("AddWeightedImage",wshed);

waitKey();
}

Vec3bRandomColor(intvalue)
{
value=value%;//生成0~255的随机数
RNGrng;
intaa=rng.uniform(,value);
intbb=rng.uniform(,value);
intcc=rng.uniform(,value);
returnVec3b(aa,bb,cc);
}

分水岭分割算法(watershed segmentation)的C++实现(法2)的更多相关文章

  1. Matlab的标记分水岭分割算法

    1 综述 Separating touching objects in an image is one of the more difficult image processing operation ...

  2. [ZZ] 基于Matlab的标记分水岭分割算法

    基于Matlab的标记分水岭分割算法 http://blog.sina.com.cn/s/blog_725866260100rz7x.html 1 综述 Separating touching obj ...

  3. 基于Matlab的标记分水岭分割算法

    转自:http://blog.sina.com.cn/lyqmath 1 综述 Separating touching objects in an image is one of the more d ...

  4. 分水岭分割算法(watershed segmentation)的C++实现(法1)

    运行环境:ubuntu16.04+Qt+opencv2.4.13 参考链接:http://blog.csdn.net/u010741471/article/details/45193521 water ...

  5. 基于标记的分水岭分割算法/OpenCV中距离变换

    Opencv分水岭算法——watershed自动图像分割用法 OpenCV距离变换distanceTransform应用 图像分割作为图像识别的基础,在图像处理中占有重要地位,通常需要在进行图像分割算 ...

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

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

  7. 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法

    1. 从细菌的趋化性谈起 0x1:物质化学浓度梯度 类似于概率分布中概率密度的概念.在溶液中存在不同的浓度区域. 如放一颗糖在水盆里,糖慢慢溶于水,糖附近的水含糖量比远离糖的水含糖量要高,也就是糖附近 ...

  8. 三维网格分割算法(Random Walks)

    首先以一维随机游走(1D Random Walks)为例来介绍下随机游走(Random Walks)算法,如下图所示,从某点出发,随机向左右移动,向左和向右的概率相同,都为1/2,并且到达0点或N点则 ...

  9. VIPS:基于视觉的页面分割算法[微软下一代搜索引擎核心分页算法]

    VIPS:基于视觉的页面分割算法[微软下一代搜索引擎核心分页算法] - tingya的专栏 - 博客频道 - CSDN.NET VIPS:基于视觉的页面分割算法[微软下一代搜索引擎核心分页算法] 分类 ...

随机推荐

  1. 002-线程实现方式【thread、runnable、callale、thread和runnable对比】

    一.概述 1.实现方式 在java中对于多线程实现一定要有一个线程的主类,而这个线程的主类往往是需要操作一些资源,但是对于多线程主类的实现是: 继承Thread父类 从java的Thread类继承实现 ...

  2. Mysql学习笔记—concat以及group_concat的用法(转载)

    本文中使用的例子均在下面的数据库表tt2下执行: 一.concat()函数 1.功能:将多个字符串连接成一个字符串. 2.语法:concat(str1, str2,...) 返回结果为连接参数产生的字 ...

  3. JS中手动触发事件的方法

    如果大家将一张网页看成一个form的话,大致上就成了一个web form的模型.在win form 下要想手动触发某一个对象的事件是很简单的,只要发送一条消息即可达成.(PostMessage) 但是 ...

  4. 比特股-去中心化交易所, STEEM - 去中心化社区, EOS - 下一代智能合约

    libsnark 是实现了 zkSNARK 模式的 C++ 库.zkSNARK 是一个证明/验证计算完整性的加密方法,也即零知识验证的算法, https://github.com/scipr-lab/ ...

  5. 利用HBase的快照功能来修改表名

    hbase的快照功能常常被用来做数据的恢复的,但是由于项目的特殊需求需要改hbase表的表名.在官网上通过快照功能来修改hbase表名的用法: 下面展示用shell命令的和Java api两种方式: ...

  6. JAVA正则表达式 Pattern和Matcher(转)

    1.简介: java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包.它包括两个类:Pattern和Matcher.        首先一个Pattern实例订制了一 ...

  7. SimpleDateFormat实现String与Date之间的转换

    基本用法: java.text.SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); java.util.Date ...

  8. VS2010/MFC编程入门之二十三(常用控件:按钮控件的编程实例)

    上一节VS2010/MFC编程入门教程中鸡啄米讲了按钮控件Button.Radio Button和Check Box的基本用法,本节就继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件 ...

  9. 2018 Multi-University Training Contest 8 Solution

    A - Character Encoding 题意:用m个$0-n-1$的数去构成k,求方案数 思路:当没有0-n-1这个条件是答案为C(k+m-1, m-1),减去有大于的关于n的情况,当有i个n时 ...

  10. ACM-ICPC 2018 徐州赛区网络预赛 Solution

    A. Hard to prepare 题意:有n个客人做成一圈,有$2^k$种面具,对于每种面具有一种面具不能使相邻的两个人戴,共有多少种做法. 思路: 把题意转化成相邻的人不能带同种面具.总数为$( ...