基于Mat变换的骨架提取Java

针对一副二值图像,区域内的点只有背景点(白点,0值)和前景点(黑点,1值)。对于给定区域的像素点逐次应用两个基本步骤,以提取骨架:

step1,如果一个像素点满足下列4个条件,那么将它标记为要删除的点:

(1)2<=N(p1)<=6,其中N(p1)=p2+p3+p4+...+p8+p9;

(2)T(p1)=1,其中T(p1)是以p2,p3,...,p8,p9,p2的次序旋转,从0到1的变换次数;

(3)p2*p4*p6=0;

(4)p4*p6*p8=0.

step2,条件(1)(2)不变,但是条件(3)(4)变为:


(3)p2*p4*p8=0;

(4)p2*p6*p8=0.

这里,每个像素点的八邻域结构为

p9 p2 p3
p8 p1 p4
p7 p6 p5

基于Mat变换的骨架提取的完整步骤:

(1)执行step1,对需要删除的边界点进行标记;

(2)删除标记点;

(3)执行step2,对需要删除的边界点进行标记;

(4)删除标记点;

(1)到(4)属于一个循环过程,不断反复进行这一循环过程,检测是否存在符合条件的删除点,直到再也找不到可删除的点的时候,说明此时骨架已经生成,结束循环。

  1 package com.example.lenovo.linehough;
  2
  3 import android.graphics.Color;
  4
  5 /**
  6  * Created by lenovo on 2016/6/20.
  7  */
  8 public class Mat {
  9
 10     public static int[] matswitch(int w, int h, int[] inputs) {
 11         int[] imgBuf = new int[w * h];
 12         int[] neighbor = new int[10];
 13         int[] mark = new int[w * h];
 14         int markNum1;
 15         int markNum2;
 16         boolean s = true;
 17         for(int index=0;index<w*h;index++)
 18             imgBuf[index] = inputs[index];
 19         while (s) {
 20             //第一步,统一黑点值为1,白点值为0
 21             markNum1 = 0;//步骤1中标记被删除的边界点的个数
 22             for (int x = 1; x < w - 1; x++) {
 23                 for (int y = 1; y < h - 1; y++) {
 24                     //条件1:p必须是边界点,值为1, 8邻域内至少有1个像素点值为0
 25                     if (imgBuf[y * w + x] == Color.WHITE) continue;
 26                     int[] detectBlack = new int[10];
 27                     neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;//黑点neighbor为0,白点neighbor为1
 28                     neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
 29                     neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;
 30                     neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
 31                     neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;
 32                     neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
 33                     neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;
 34                     neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
 35                     for (int i = 2; i <= 9; i++) {
 36                         if (neighbor[i] == 0)
 37                             detectBlack[i]++;//(黑点)neighbor为0,detectBlack就为1;(白点)neighbor为1,detectBlack就为0
 38                     }
 39                     //8领域的点都是黑点,证明该点不是边界点,退出该轮循环,检测下一个点
 40                     if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]
 41                             * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)
 42                         continue;
 43
 44                     //条件2:2<=N(p)<=6
 45                     int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]
 46                             + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);
 47                     if (np < 2 || np > 6) continue;
 48
 49                     //条件3:T(p)=1
 50                     int tp = 0;
 51                     for (int i = 3; i <= 9; i++) {
 52                        /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/
 53                         if (detectBlack[i] - detectBlack[i - 1] == 1)
 54                             tp++;
 55                     }
 56                     if (detectBlack[2] - detectBlack[9] == 1)
 57                         tp++;
 58                     if (tp != 1) continue;
 59
 60                     //条件4:p2*p4*p6=0
 61                     if (detectBlack[2] * detectBlack[4] * detectBlack[6] != 0)
 62                         continue;
 63                     //条件5:p4*p6*p8=0
 64                     if (detectBlack[4] * detectBlack[6] * detectBlack[8] != 0)
 65                         continue;
 66
 67                     //标记要被删除的点
 68                     mark[y * w + x] = 1;
 69                     markNum1++;
 70                 }
 71             }
 72
 73             //将标记删除的点置为背景色
 74             if (markNum1 > 0) {
 75                 for (int x = 1; x < w - 1; x++) {
 76                     for (int y = 1; y < h - 1; y++) {
 77                         //删除被标记的点,即置为背景色黑色
 78                         if (mark[y * w + x] == 1) {
 79                             imgBuf[y * w + x] = Color.WHITE;
 80                         }
 81                     }
 82                 }
 83             }
 84
 85
 86             //第二步
 87             markNum2 = 0;//步骤2中标记被删除的点的个数
 88             for (int x = 1; x < w - 1; x++) {
 89                 for (int y = 1; y < h - 1; y++) {
 90                     //条件1:p必须是前景点BLACK
 91                     if (imgBuf[y * w + x] == Color.WHITE) continue;
 92                     int[] detectBlack = new int[10];
 93                     neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;
 94                     neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
 95                     neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;
 96                     neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
 97                     neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;
 98                     neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
 99                     neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;
100                     neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
101                     for (int i = 2; i < 10; i++) {
102                         if (neighbor[i] == 0) detectBlack[i]++;
103                     }
104
105                     if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]
106                             * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)
107                         continue;
108
109                     //条件2:2<=N(p)<=6
110                     int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]
111                             + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);
112                     if (np < 2 || np > 6) continue;
113
114                     //条件3:T(p)=1
115                     int tp = 0;
116                     for (int i = 3; i <= 9; i++) {
117                        /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/
118                         if (detectBlack[i] - detectBlack[i - 1] == 1)
119                             tp++;
120                     }
121                     if (detectBlack[2] - detectBlack[9] == 1)
122                         tp++;
123                     if (tp != 1) continue;
124
125                     //条件4:p2*p4*p8==0
126                     if (detectBlack[2] * detectBlack[4] * detectBlack[8] != 0)
127                         continue;
128                     //条件5:p2*p6*p8==0
129                     if (detectBlack[2] * detectBlack[6] * detectBlack[8] != 0)
130                         continue;
131
132                     //标记删除
133                     mark[y * w + x] = 1;
134                     markNum2++;
135                 }
136             }
137
138             //将标记删除的点置为背景色WHITE
139             if (markNum2 > 0) {
140                 for (int x = 1; x < w - 1; x++) {
141                     for (int y = 1; y < h - 1; y++) {
142                         if (mark[y * w + x] == 1) {
143                             imgBuf[y * w + x] = Color.WHITE;
144                         }
145                     }
146                 }
147             }
148             //先步骤1再步骤2,一次周期循环后,不再出现标记删除的点时,说明已生成骨架了
149             if (markNum1 == 0 && markNum2 == 0) s = false;
150             else s = true;
151         }
152         return imgBuf;
153     }
154
155
156 }
时间: 2024-10-11 21:11:44

基于Mat变换的骨架提取Java的相关文章

基于红黑树的骨架提取Java

前面有提到基于Mat变换的骨架提取,然而在实际的应用中处理稍微大点的图片的时候耗时较长就是个问题了,于是针对这个问题寻找了另外一种方法--基于红黑树的骨架提取,这种方法明显处理速度要快一些. 基于红黑树的骨架提取的思路如下: 1,对输入的二值图像进行延拓(直白的说就是在图像的外边界加一圈白点),得到二值图像P: 2,针对骨架提取有8种结构类型(S0~S7)的待删除点.骨架提取的过程实际上就是不断的找符合这8种结构的待删除点,删除待删除点.初始化8个空的红黑树结构T0~T7,初始化current=

python数字图像处理(19):骨架提取与分水岭算法

骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内. 1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. morphology子模块提供了两个函数用于骨架提取,分别是Skeletonize()函数和medial_axis()函数.我们先来看Skeletonize()函数. 格式为:skimage.morphology.skeletonize(image) 输入和输出都是一幅二值图像. 例1: from s

基于遗传算法求解TSP问题(Java界面)

近期为做展示,改写了一个遗传算法求TSP的Java界面版,思路代码和 http://blog.csdn.net/wangqiuyun/article/details/12838903 这篇文章思路是一样的,追加了Java用Graphics画点及画线做路径展示,展示部分做得比較粗糙,须要的拿走,效果图例如以下. 下载地址:http://download.csdn.net/detail/wangqiuyun/7406201 另C#界面版:http://blog.csdn.net/wangqiuyun

基于TF-IDF的新闻标签提取

基于TF-IDF的新闻标签提取 1. 新闻标签 新闻标签是一条新闻的关键字,可以由编辑上传,或者通过机器提取.新闻标签的提取主要用于推荐系统中,所以,提取的准确性影响推荐系统的有效性.同时,对于将标签展示出来的新闻网站,标签的准确性也会影响用户体验. 2. 新闻标签提取算法 新闻首先是一段文本,新闻的标签首先是这一段文本的关键字.在文本关键字提取当中,TD-IDF是首先可以想到的算法.TF-IDF算法的优点是:简单快速,结果比较符合实际情况:缺点是,单纯以"词频"衡量一个词的重要性,不

基于CAS线程安全的计算方法 java并发编程的艺术上的一个案例

package thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /**  * @author  changxiangxiang  * @date 2014年8月6日 下午3:25:12  * @description  * @since  sprint2  */ public class Counter {     privat

基于JSP的二手车拍卖网-java二手车拍卖系统

基于JSP的二手车拍卖网-java二手车拍卖系统1.包含源程序,数据库脚本.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善.开发环境:Eclipse ,MySQL 5.1,JDK1.7,Tomcat 7涉及技术点:MVC模式.JavaWeb.JDBC.HTML.CSS.JQUERY.文件上传.购物车等. 系统没用任何框架,前台纯JSP实现,后台servlet映射,适合刚学习J2EE的新手,代码思路清晰,注解详细,数据库用的是mysql5.1,服务器用的tomcat7,JDK版本1.7.

基于SSM的水质检测系统-java水质检测系统

基于SSM的水质检测系统-java水质检测系统 1.包含源程序,数据库脚本.代码和数据库脚本都有详细注释.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善开发环境:Eclipse ,MYSQL,JDK1.7,Tomcat 7涉及技术点:MVC模式.SpringMvc.Mybatis.Spring.HTML.JavaScript.CSS.JQUERY.DWR.Ajax等系统采用Mybatis框架实现ORM对象关系映射,前台JSP实现,后台springMvc映射,使用Spring框架进行整合

基于JSP的网上订餐系统-java网上订餐系统源代码系统演示

基于JSP的网上订餐系统-java网上订餐系统源代码系统演示 1.包含源程序,数据库脚本.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善.开发环境:Eclipse ,MySQL 5.1,JDK1.7,Tomcat 7涉及技术点:MVC模式.JavaWeb.JDBC.HTML.CSS.JQUERY.文件上传.购物车等. 系统没用任何框架,前台纯JSP实现,后台servlet映射,适合刚学习J2EE的新手,代码思路清晰,注解详细,数据库用的是mysql5.1,服务器用的tomcat7,JD

基于SSM的汽车出租管理系统-mysql&amp;java汽车出租管理系统租车管理系统

基于SSM的汽车出租管理系统-mysql&java汽车出租管理系统租车管理系统 1.包含源程序,数据库脚本.代码和数据库脚本都有详细注释.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善开发环境:Eclipse ,MYSQL,JDK1.7,Tomcat 7涉及技术点:MVC模式.SpringMvc.Mybatis.Spring.HTML.JavaScript.CSS.JQUERY.DWR.Ajax等系统采用Mybatis框架实现ORM对象关系映射,前台JSP实现,后台springMvc映