import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.imageio.ImageIO;
/**
*分水岭算法进行图像分割
*@author zhshl
*@date 2014-10-31
*/
public class WaterShed {
private BufferedImage sourceImg;///原图
private BufferedImage gradImage;////灰度图
/**
* ///此处采用数组实现指向父节点的多叉树,根节点的父节点是它自己(指向自己,下标用转化后的数值表示比如i行j列,下标为:i*width+j)
* ///用查集数据结构来进行区域标记,主要目的在于简化区域块的合并
* ////记录分块数据
*/
private int [][] blockData;
private int width;
private int height;
private final int THRESHOD=25;
private int maxGrad;////最大梯度值,也是灌水灌到的最高点
private int RIDGE=-100;////该标志表示山脊
////保存图像对应区域的 块整体信息,key对应分块标记值
private HashMap<Integer,Img_Area_Feature> nodes=new HashMap<>();
/**
* 开始进行分水岭算法分割图片
* @param file
*/
public void startWatering(File file){
////初始化,包括滤波以及种子区域标记
init(file);
////开始进行分水岭算法
startWatering();
////获取分割结果的邻接图
getAdjacencyGraph();
///区域合并
areaCombine();
}
/**
* 开始灌水生长
*/
private void startWatering(){
for(int altitude=THRESHOD;altitude<=maxGrad;altitude++){
////外层循环,表示每次灌水达到的高度
int addedPixes=0;////记录每次循环有多少个像素点加入了集水盆,
do{
addedPixes=0;
////在某个高度下,一直循环到没有新像素点加入到集水盆为止
for(int j=0;j<height;j++){
for(int i=0;i<width;i++){
///内部循环遍历图片
int grad=(gradImage.getRGB(i, j)>>16)&0xFF;
if((grad<=altitude)&&(blockData[j][i]==-1)){
////处理未标记的区域
int num=0;///记录四领域集水盆数目
int parentIndex=-1;
////左边
if(i>0){////不超出边界
int value=blockData[j][i-1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
parentIndex=left_parentIndex;
num++;
}
}
////右边
if(i<width-1){////不超出边界
int value=blockData[j][i+1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////上边
if(j>0){////不超出边界
int value=blockData[j-1][i];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////下边
if(j<height-1){////不超出边界
int value=blockData[j+1][i];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
////当该标记点所在区域的值与之前的区域值不一致时,四邻域集水盆数目加一
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////左上
if(i>0&&j>0){////不超出边界
int value=blockData[j-1][i-1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////右上
if(i<width-1&&j>0){////不超出边界
int value=blockData[j-1][i+1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////左下
if(i>0&&j<height-1){////不超出边界
int value=blockData[j+1][i-1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表示行
left_i=left_parentIndex%width;///余数表示列
}
if(left_parentIndex!=parentIndex){
num++;
}
///把该集水盆的代表节点的父节点下标值记录下来
parentIndex=left_parentIndex;
}
}
////右下
if(i<width-1&&j<height-1){////不超出边界
int value=blockData[j+1][i+1];
if(value!=-1&&value!=-100){
///找到左边区域的根节点即某节点指向自身
int left_parentIndex=value;
int left_j=left_parentIndex/width;///商表示行
int left_i=left_parentIndex%width;///余数表示列
while(blockData[left_j][left_i]!=left_parentIndex){
left_parentIndex=blockData[left_j][left_i];
left_j=left_parentIndex/width;///商表�
java源码分水岭算法
![star](https://csdnimg.cn/release/downloadcmsfe/public/img/star.98a08eaa.png)
![avatar](https://profile-avatar.csdnimg.cn/6acaa39a7bd945c79b5c1e3e8cb3219f_abcd_d_.jpg!1)
二哥的博客
- 粉丝: 99
- 资源: 3
最新资源
- python-leetcode python题解之第482题密钥格式化
- python-leetcode python题解之第479题最大回文数乘积
- python-leetcode python题解之第475题供暖器
- python-leetcode python题解之第463题岛屿的周长
- python-leetcode python题解之第461题汉明距离
- python-leetcode python题解之第458题可怜的小猪
- python-leetcode python题解之第457题环形数组是否存在循环
- python-leetcode python题解之第453题最小操作次数使数组元素相等
- python-leetcode python题解之第448题找到所有数组中消失的数字
- python-leetcode python题解之第443题压缩字符串
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)
- 1
- 2
前往页