java骨架_基于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 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相关推荐
- 图像mnf正变换_基于MNF 变换的多元变化检测变化信息的集中
展开全部 (一)基于MNF变换的变化信息集中的基本流程 MNF变换是一种多元62616964757a686964616fe58685e5aeb931333433616234线性统计变换方法,是针对一组 ...
- java 分析java死锁_有益的CountDownLatch和棘手的Java死锁
java 分析java死锁 您是否曾经使用过java.util.concurrent.CountDownLatch ? 这是在两个或多个线程之间实现同步的非常方便的类,在该类中,一个或多个线程可以等待 ...
- aix系统java堆_浅谈AIX环境下的Java性能调优
1.什么是Java Java 是一种面向对象的编程语言.它以 C++ 为模型,被设计成小的.简单的.在源和二进制级别跨平台的可移植的语言,Java 程序(applets 和应用程序)可以运行于任何已经 ...
- 安装java环境_(一)环境安装之Java
安装java 点击 JDK8下载,根据自己的平台,选择相应的版本进行下载. 小知识: Java环境分JDK和JRE ,JDK就是Java Development Kit.简单的说JDK是面向开发人员使 ...
- cmd编译java命令_使用CMD命令编译和运行Java程序
对于初学者来说,使用CMD命令(Unix以及类Unix系统采用Termial)来编译和运行Java的好处是让初学者直观地体会到编译(Compile)这一步骤,加深记忆.所谓编译就是将文本文件xxx.j ...
- 数据结构和算法 java实现_数据结构与算法——常用数据结构及其Java实现
前言 仿佛一下子,2017年就快过去一半了,研一马上就要成为过去式了,我打算抓住研一的尾巴,好好梳理一下数据结构与算法,毕竟这些基础知识是很重要的嘛.所以准备在这里搞一个系列的文章,以期透彻. 本系列 ...
- 二维几何变换java代码_基于Batik的SVG应用: 关于几何变换
本文是作者在 SVGGIS 系统的开发实践过程中关于 SVG 坐标转换的总结.在描述 SVG 坐标变换原理的同时,使用 Apache Batik 项目实现了相关例子. SVG 是一种用 xml 语言来 ...
- 租车java 查询_基于java实现租车管理系统
概述 基于java + swing + JFrame 的图书馆管理系统,租车,还车,管理员管理用户,付款等. 部分代码 public class Login extends JFrame { priv ...
- java r$_基于javacv的人脸检测Demo
[实例简介] 基于javacv的人脸检测Demo,参考文章:http://blog.csdn.net/viviwen123/article/details/6386302#reply [实例截图] [ ...
最新文章
- 微信小程序提示 出现脚本错误或者未正确调用 Page()
- linux的dns的转发域,Linux DNS服务器子域授权、转发器和转发域配置实例(三)
- linux 内核 netfilter 网络过滤模块 (3)-NAT
- python切片操作例题_Python之切片操作
- debian 下配置common lisp环境
- 重构第12天 分解依赖(Break Dependencies)
- java 补充日期_Java 9对可选的补充
- 201809-2-买菜
- python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))…………
- windows环境tomcat8配置Solr5.5.1
- Nginx源码分析 - 主流程篇 - 多进程实现(14)
- NetAssist.exe网络调试工具
- 魅族消息推送服务器,内部员工透露魅族早已完成统一推送服务适配
- 【译】Jep 文档(2)——基本用法(Basic Usage)
- 数据泄露事件频发,深扒企业数据库安全隐患(内附高效防护手段)
- Raspberry Pi Zero W 安装配置
- java语言 用Switch语句划分成绩
- 移动端某些网络下域名无法解析的DNS问题
- java高校人员信息管理系统
- 中文的括号和英文的括号区别_浅谈中英文混排图书的标点和体例