近期被图像切割整的天昏地暗的,在此感谢老朋友周洋给我关于分水岭算法的指点!本来打算等彩色图像切割有个完满的结果再写这篇文章,可是考虑到到了这一步也算是一个阶段,所以打算对图像切割做一个系列的博文,于是先写这篇。

啰嗦了这么多!先看效果:

效果一般,存在着非常多过切割现象,但比没使用滤波之前的效果好非常多,过切割是分水岭算法的通病。这个兴许博文会继续解决。

本文用java实现的是基于自己主动种子区域的分水岭算法,注意本文是基于单色的切割,所以将输入图片首先进行灰度化处理,这个比較简单,不多提了;因此,对于彩色图像,会存在一些偏差,这个在兴许博文里我会去解决。关于分水岭算法的概念,请自行百度,本系列主讲怎样实现以及实现效果。

算法大致分为四步:图像预处理、 种子区域获取、浸水过程(区域增长)、切割结果的合并处理。另外,算法在分水岭过程中的区域表示上,採用并查集的数据结构表示区域块,这样做的优点在于简化生长过程中的合并处理,关于并查集,參见我这篇博文: http://blog.csdn.net/abcd_d_/article/details/40316455

1、图像预处理过程:

本文採用二维高斯滤波进行图像(sigma=3.0)的平滑操作,经验证去操平滑效果好于中值滤波,读者能够自己实验其他的滤波。另外,为了简化操作,二维高斯模板可近似为两个一维的高斯模板,也就是在下图中,左边的滤波过程近似为右边的滤波过程。

核心代码为:

/**
* * 将图像进行高斯模糊:先利用模糊函数计算高斯模板矩阵,然后进行卷积运算。
*
* @高斯模糊 :高斯模糊是一种图像滤波器,它使用正态分布(高斯函数)计算模糊模板,并使用该模板与原图像做卷积运算,达到模糊图像的目的。
* 在实际应用中,在计算高斯函数的离散近似时,在大概3σ距离之外的像素都能够看作不起作用,这些像素的计算也就能够忽略。
* 通常,图像处理程序仅仅须要计算的矩阵就能够保证相关像素影响。
*
* @param source
* @param index 表示不同的sigma相应的模板
* @return double[][] 模糊后的图像信息矩阵
*/
public static double[][] gaussTran(double[][] source,int index){ int height=source.length;
int width=source[0].length;
///保存高斯过滤后的结果
double[][] result=new double[height][width]; double[] template=GaussTemplate1D.gettemplateX_Y(index);
int tWH=template.length;///模板维数 for(int i=0;i<height;i++){
for(int j=0;j<width;j++){ ///进行模糊处理——————卷积运算
double sum=0.0;///卷积结果
for(int m=0;m<tWH;m++){
///计算与模板相应的图像上的位置
int x=j-(int)tWH/2+m;
int y=i;//-(int)tWH/2+m; //假设模板数据没有超过边界
if(x>=0&&x<width){
sum=sum+source[y][x]*template[m];
}
} for(int m=0;m<tWH;m++){
///计算与模板相应的图像上的位置
int x=j;
int y=i-(int)tWH/2+m;//-(int)tWH/2+m; //假设模板数据没有超过边界
if(y>=0&&y<height){
sum=sum+source[y][x]*template[m];
}
}
result[i][j]=sum/2; }
}
int i=0;
i++;
return result;
}

效果为(左边是原图):

2、种子区域选取:

首先,获取梯度图像:高斯滤波图像使用sobel算子求取梯度图像。

然后,种子区域获取以及标记:梯度图像中,将梯度值小于预先设置的阈值THRESHOLD的像素点的灰度值设置为0,而其它像素点的灰度值等于其梯度值。这样每个像素都标记之后就開始进行区域增长,採用同一区域属于一个并查集的方法,将灰度值为0的区域进行分类标记(这些信息存储在blockData里)。如图,每个黑色块属于一个类(也就是一个种子区域)。

3、浸水过程(也就是区域生长过程):

參照周洋告诉我的方法:三层循环,第一层是梯度值从阈值到最大值,里面两层是二维图像数据的遍历。採用八领域的推断方法,假设某个未被标记为0(未知)的点周围仅仅有一个被标记为零的点(种子),则该点归并到该种子区域中,假设有两个以上被标记的点,而且属于不同的区域,那么该点标记为山脊(轮廓线)。对于外层循环的每个梯度值,区域生长的停止条件:没有新的点被并入到某个区域。这样事实上就有四层循环,由于须要一层来推断是否有新点被并入到种子区域。

效果图例如以下:

能够看出,分水岭算法的优点在于能够得到一个个封闭区域,这个一般的二值化的轮廓图像是得不到的。

另外,经过对照发现,高斯滤波对降低过切割有着比較理想的作用,可是也不能消除过切割,因此须要有第四步——区域合并。这部分在兴许博文中我会继续讲。

由于还未写完,所以代码可能显得比較乱,比方程序中有个map成员变量,实际没多大意义,但考虑到測试用,还望见谅!

附上第一版程序的源代码:http://download.csdn.net/detail/abcd_d_/8169869

新手学,java使用分水岭算法进行图像切割(一)的更多相关文章

  1. opencv分水岭算法对图像进行切割

    先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...

  2. 新手学Java,有哪些入门知识点?

    很多小伙伴们在刚接触Java的时候,会有些迷茫,不知道该从哪里入手,不管是做前端还是后端,程序员都会用到JAVA,那该掌握哪些必要的基础知识呢.今天就跟大家分享新手学Java,有哪些入门知识点? 下面 ...

  3. opencv学习之路(30)、分水岭算法及图像修补

    一.简介 二.分水岭算法 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat srcImg = ...

  4. [新手学Java]使用beanUtils控制javabean

    使用BeanUtils设置/读取属性的值以及默认支持的自动转化: @Test //使用BeanUtils设置/读取属性的值以及自动转化 public void test1() throws Illeg ...

  5. [新手学Java]使用内省(Introspector)操作JavaBean属性

    获取类bean中的所有属性: @Test //获取类bean中的所有属性 public void test1() throws Exception{ BeanInfo info = Introspec ...

  6. [新手学Java]反射学习笔记

    示例类 @SuppressWarnings("unused") public class Person { public String Name; private int Age; ...

  7. OpenCV学习(7) 分水岭算法(1)

            分水岭算法主要用于图像分段,通常是把一副彩色图像灰度化,然后再求梯度图,最后在梯度图的基础上进行分水岭算法,求得分段图像的边缘线.         下面左边的灰度图,可以描述为右边的地 ...

  8. 第八节、图片分割之GrabCut算法、分水岭算法

    所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性.我们先对目前主要的图像分割方法做个概述,后面再 ...

  9. 图片分割之GrabCut算法、分水岭算法

    https://www.cnblogs.com/zyly/p/9392881.html 所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出 ...

随机推荐

  1. Insert Data with C# Driver

    https://docs.mongodb.com/getting-started/csharp/insert/ OverView You can use the InsertOneAsync meth ...

  2. 设计url 通过分发的方式 Xadmin_demo

    如 urlpatterns = [ url(r'^Xadmin/',([ url(r'^add/$', views.add) url(r'^delete/$', views.delete) ], No ...

  3. java9新特性-9-语法改进:try语句

    1. 使用举例 在java8 之前,我们习惯于这样处理资源的关闭:     java 8 中,可以实现资源的自动关闭,但是要求执行后必须关闭的所有资源必须在try子句中初始化,否则编译不通过.如下例所 ...

  4. Java类和对象9

    (1)创建一个叫做机动车的类:属性:车牌号(String),车速(int),载重量(double)功能:加速(车速自增).减速(车速自减).修改车牌号,查询车的载重量.编写两个构造方法:一个没有形参, ...

  5. nginx的gizp压缩

    好处:         页面另存为大小比浏览器传输大小大很多.好处是加快传输.节省带宽.   原理:           浏览器 -> 请求 -> 声明可以接受的压缩方式[http 协议请 ...

  6. Redis数据持久化的两种方式RDB和AOF

    由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁 盘上,当redis重启后,可以从磁盘中恢复数据.redis提 ...

  7. NOIP 2017 小凯的疑惑(同余类)

    题意 给出两个互质的数a,b问最大的不能被xa+yb(x,y>=0)表示的数.(a,b<=109) 题解 NOIPday1T1一道数论题,不知埋葬了多少人的梦想. 用同余类去解释. 我们依 ...

  8. Hexo 与 Git 集成

    git初始化项目 登录Github,初始化GitHub Pages项目.即是添加一个Git Project. 点击New repository创建一个新的Project.需要填写选项如下:    -  ...

  9. 作诗(si)[分块]

    题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读 ...

  10. 【Codeforces Round #422 (Div. 2) A】I'm bored with life

    [题目链接]:http://codeforces.com/contest/822/problem/A [题意] 让你求a!和b!的gcd min(a,b)<=12 [题解] 哪个小就输出那个数的 ...