针对一副二值图像,区域内的点只有背景点(白点,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 packagecom.example.lenovo.linehough;2

3 importandroid.graphics.Color;4

5 public classMat {6

7 public static int[] matswitch(int w, int h, int[] inputs) {8 int[] imgBuf = new int[w *h];9 int[] neighbor = new int[10];10 int[] mark = new int[w *h];11 intmarkNum1;12 intmarkNum2;13 boolean s = true;14 for(int index=0;index

18 markNum1 = 0;//步骤1中标记被删除的边界点的个数

19 for (int x = 1; x < w - 1; x++) {20 for (int y = 1; y < h - 1; y++) {21 //条件1:p必须是边界点,值为1, 8邻域内至少有1个像素点值为0

22 if (imgBuf[y * w + x] == Color.WHITE) continue;23 int[] detectBlack = new int[10];24 neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;//黑点neighbor为0,白点neighbor为1

25 neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;26 neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;27 neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;28 neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;29 neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;30 neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;31 neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;32 for (int i = 2; i <= 9; i++) {33 if (neighbor[i] == 0)34 detectBlack[i]++;//(黑点)neighbor为0,detectBlack就为1;(白点)neighbor为1,detectBlack就为0

35 }36 //8领域的点都是黑点,证明该点不是边界点,退出该轮循环,检测下一个点

37 if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]38 * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)39 continue;40

41 //条件2:2<=N(p)<=6

42 int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]43 + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);44 if (np < 2 || np > 6) continue;45

46 //条件3:T(p)=1

47 int tp = 0;48 for (int i = 3; i <= 9; i++) {49 /*if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/

50 if (detectBlack[i] - detectBlack[i - 1] == 1)51 tp++;52 }53 if (detectBlack[2] - detectBlack[9] == 1)54 tp++;55 if (tp != 1) continue;56

57 //条件4:p2*p4*p6=0

58 if (detectBlack[2] * detectBlack[4] * detectBlack[6] != 0)59 continue;60 //条件5:p4*p6*p8=0

61 if (detectBlack[4] * detectBlack[6] * detectBlack[8] != 0)62 continue;63

64 //标记要被删除的点

65 mark[y * w + x] = 1;66 markNum1++;67 }68 }69

70 //将标记删除的点置为背景色

71 if (markNum1 > 0) {72 for (int x = 1; x < w - 1; x++) {73 for (int y = 1; y < h - 1; y++) {74 //删除被标记的点,即置为背景色黑色

75 if (mark[y * w + x] == 1) {76 imgBuf[y * w + x] =Color.WHITE;77 }78 }79 }80 }81

82

83 //第二步

84 markNum2 = 0;//步骤2中标记被删除的点的个数

85 for (int x = 1; x < w - 1; x++) {86 for (int y = 1; y < h - 1; y++) {87 //条件1:p必须是前景点BLACK

88 if (imgBuf[y * w + x] == Color.WHITE) continue;89 int[] detectBlack = new int[10];90 neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;91 neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;92 neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;93 neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;94 neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;95 neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;96 neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;97 neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;98 for (int i = 2; i < 10; i++) {99 if (neighbor[i] == 0) detectBlack[i]++;100 }101

102 if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]103 * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)104 continue;105

106 //条件2:2<=N(p)<=6

107 int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]108 + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);109 if (np < 2 || np > 6) continue;110

111 //条件3:T(p)=1

112 int tp = 0;113 for (int i = 3; i <= 9; i++) {114 /*if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/

115 if (detectBlack[i] - detectBlack[i - 1] == 1)116 tp++;117 }118 if (detectBlack[2] - detectBlack[9] == 1)119 tp++;120 if (tp != 1) continue;121

122 //条件4:p2*p4*p8==0

123 if (detectBlack[2] * detectBlack[4] * detectBlack[8] != 0)124 continue;125 //条件5:p2*p6*p8==0

126 if (detectBlack[2] * detectBlack[6] * detectBlack[8] != 0)127 continue;128

129 //标记删除

130 mark[y * w + x] = 1;131 markNum2++;132 }133 }134

135 //将标记删除的点置为背景色WHITE

136 if (markNum2 > 0) {137 for (int x = 1; x < w - 1; x++) {138 for (int y = 1; y < h - 1; y++) {139 if (mark[y * w + x] == 1) {140 imgBuf[y * w + x] =Color.WHITE;141 }142 }143 }144 }145 //先步骤1再步骤2,一次周期循环后,不再出现标记删除的点时,说明已生成骨架了

146 if (markNum1 == 0 && markNum2 == 0) s = false;147 else s = true;148 }149 returnimgBuf;150 }151

152

153 }

java骨架_基于Mat变换的骨架提取Java相关推荐

  1. 图像mnf正变换_基于MNF 变换的多元变化检测变化信息的集中

    展开全部 (一)基于MNF变换的变化信息集中的基本流程 MNF变换是一种多元62616964757a686964616fe58685e5aeb931333433616234线性统计变换方法,是针对一组 ...

  2. java 分析java死锁_有益的CountDownLatch和棘手的Java死锁

    java 分析java死锁 您是否曾经使用过java.util.concurrent.CountDownLatch ? 这是在两个或多个线程之间实现同步的非常方便的类,在该类中,一个或多个线程可以等待 ...

  3. aix系统java堆_浅谈AIX环境下的Java性能调优

    1.什么是Java Java 是一种面向对象的编程语言.它以 C++ 为模型,被设计成小的.简单的.在源和二进制级别跨平台的可移植的语言,Java 程序(applets 和应用程序)可以运行于任何已经 ...

  4. 安装java环境_(一)环境安装之Java

    安装java 点击 JDK8下载,根据自己的平台,选择相应的版本进行下载. 小知识: Java环境分JDK和JRE ,JDK就是Java Development Kit.简单的说JDK是面向开发人员使 ...

  5. cmd编译java命令_使用CMD命令编译和运行Java程序

    对于初学者来说,使用CMD命令(Unix以及类Unix系统采用Termial)来编译和运行Java的好处是让初学者直观地体会到编译(Compile)这一步骤,加深记忆.所谓编译就是将文本文件xxx.j ...

  6. 数据结构和算法 java实现_数据结构与算法——常用数据结构及其Java实现

    前言 仿佛一下子,2017年就快过去一半了,研一马上就要成为过去式了,我打算抓住研一的尾巴,好好梳理一下数据结构与算法,毕竟这些基础知识是很重要的嘛.所以准备在这里搞一个系列的文章,以期透彻. 本系列 ...

  7. 二维几何变换java代码_基于Batik的SVG应用: 关于几何变换

    本文是作者在 SVGGIS 系统的开发实践过程中关于 SVG 坐标转换的总结.在描述 SVG 坐标变换原理的同时,使用 Apache Batik 项目实现了相关例子. SVG 是一种用 xml 语言来 ...

  8. 租车java 查询_基于java实现租车管理系统

    概述 基于java + swing + JFrame 的图书馆管理系统,租车,还车,管理员管理用户,付款等. 部分代码 public class Login extends JFrame { priv ...

  9. java r$_基于javacv的人脸检测Demo

    [实例简介] 基于javacv的人脸检测Demo,参考文章:http://blog.csdn.net/viviwen123/article/details/6386302#reply [实例截图] [ ...

最新文章

  1. 微信小程序提示 出现脚本错误或者未正确调用 Page()
  2. linux的dns的转发域,Linux DNS服务器子域授权、转发器和转发域配置实例(三)
  3. linux 内核 netfilter 网络过滤模块 (3)-NAT
  4. python切片操作例题_Python之切片操作
  5. debian 下配置common lisp环境
  6. 重构第12天 分解依赖(Break Dependencies)
  7. java 补充日期_Java 9对可选的补充
  8. 201809-2-买菜
  9. python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))…………
  10. windows环境tomcat8配置Solr5.5.1
  11. Nginx源码分析 - 主流程篇 - 多进程实现(14)
  12. NetAssist.exe网络调试工具
  13. 魅族消息推送服务器,内部员工透露魅族早已完成统一推送服务适配
  14. 【译】Jep 文档(2)——基本用法(Basic Usage)
  15. 数据泄露事件频发,深扒企业数据库安全隐患(内附高效防护手段)
  16. Raspberry Pi Zero W 安装配置
  17. java语言 用Switch语句划分成绩
  18. 移动端某些网络下域名无法解析的DNS问题
  19. java高校人员信息管理系统
  20. 中文的括号和英文的括号区别_浅谈中英文混排图书的标点和体例

热门文章

  1. 数据库操作:MFC连接与MYSQL
  2. 第十一章:WebSocket
  3. SpringMVC中获得HttpRequest对象的方法
  4. Android View.onMeasure方法的理解
  5. [Linux学习笔记] Linux常用命令 - 文件搜索命令
  6. 基于amoeba实现mysql数据库的读写分离/负载均衡
  7. 电子政务方向:We7.Cloud政府云门户
  8. Java乔晓松-android中调用系统拍照功能并显示拍照的图片
  9. 《深入理解Linux内核》条目式笔记 _2
  10. Java高手需要注意的25个学习目标