基于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 public class Mat { 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 int markNum1; 12 int markNum2; 13 boolean s = true; 14 for(int index=0;index<w*h;index++) 15 imgBuf[index] = inputs[index]; 16 while (s) { 17 //第一步,统一黑点值为1,白点值为0 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 return imgBuf; 150 } 151 152 153 }
转载于:https://www.cnblogs.com/gxclmx/p/7498427.html
基于Mat变换的骨架提取Java相关推荐
- java骨架_基于Mat变换的骨架提取Java
针对一副二值图像,区域内的点只有背景点(白点,0值)和前景点(黑点,1值).对于给定区域的像素点逐次应用两个基本步骤,以提取骨架: step1,如果一个像素点满足下列4个条件,那么将它标记为要删除的点 ...
- 自己验证的一片扯淡的骨架提取论文
基于数学形态学的汉字骨架提取算法 程志君1 杨德强2 这篇论文的效果号称的效果图如下: 我经过自己的验证,写的程序如下,如果我的理解有错误,还请各位写评论啊, #include< ...
- 迷宫问题图解 : 基于骨架提取、四邻域
目录 1. 迷宫的连通域 2. How to remove branch ? 3. 基于4邻域的 remove 分支 3.1 找到分支的端点 3.2 4邻域的 remove 分支 3.3 循环移除分支 ...
- 基于灰度质心法和骨架的激光中心线提取
之前博主一直在做线结构光成像,硬件比较垃圾,相机加镜头和线激光器总共成本在1000以内,精度在0.1mm左右,感觉这种成本做出来还是不错的,其实主要大部分时间花在了分析上来达到最好的效果. 一般对于激 ...
- Udacity无人驾驶工程师课程笔记:1 计算机视觉基础——基于Hough变换的车道线提取
Udacity无人驾驶工程师课程笔记:1 计算机视觉基础--基于Hough变换的车道线提取 图像处理 颜色选择 区域遮罩 组合颜色和区域选择 边缘检测 Canny边缘检测 Hough变换 Hough变 ...
- 基于zhang 的骨架提取
最近在学图像处理的骨架提取,发现很多中文教材对这个方面讲的很有欠缺,于是我决定看英文原文的论文.看了2篇论文, "A fast parallel algorithm for thinning ...
- qr分解java代码_[转载]【原创】基于Givens变换QR分解Matlab代码
如果有任何问题.建议,或者更多资源.代码.视频,欢迎您访问专业的Matlab技术交流平台--Matlab技术论坛http://www.matlabsky.com Wish my dear girl,h ...
- 单像素骨架提取算法c语言实现,【图像】骨架提取与分水岭算法
1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. morphology子模块提供了两个函数用于骨架提取,分别是Skeletonize ...
- 去毛边 叶片图像_一种用于植物叶片图像骨架提取的去毛刺方法.PDF
一种用于植物叶片图像骨架提取的去毛刺方法 第 27 卷 第 1 期 电子测量与仪器学报 Vol. 27 No. 1 · 52 · JOURNAL OF ELECTRONIC MEASUREMENT A ...
- Zhang-Suen 图像骨架提取算法的原理和OpenCV实现
记录一下图像骨架提取算法,转载至 两种图像骨架提取算法的研究(1)原理部分 基于OpenCV的实现代码如下,代码部分参考 opencv骨架提取/图像细化 void thinImage(Mat & ...
最新文章
- shell实现批量在多台windows服务器上执行同一命令并获取返回结果
- 解决无法删除的dll文件
- GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
- Mysql 5.5的编译安装 在ubuntu 10平台上面
- Java 算法 S01串
- 基于容器的虚拟化资源调度系统架构设计 | 原力计划
- ORB-SLAM2 地图加载2
- 真正的研发之路(1)
- 运维 xshell 快捷键
- python工作流界面_python 版工作流设计
- 为什么大多公司不要培训班出来的JAVA程序员?
- ems苹果专线投递速度_苹果官网运抵速度让人欲罢不能
- 双十一,稳!2小时1000亿,阿里的技术露大脸了
- Java实现对称加密
- Miracle密码算法开源库(十三)分析 :mrflsh4.c
- 人工智能未来的发展前景
- 最全的BAT大厂面试题整理
- (转载)计算机视觉当中的专业英语
- 【电气设计】理论知识学习(持续更新中...)
- Java基础 —— 编程入门
热门文章
- html table奇偶行颜色设置 (CSS选择器)
- [ CSS ] animation 快速参考
- 同一进程不同线程之间的资源共享与独享
- java linux和windows下文件路径间隔符的写法——解决linux下程序在windows下运行时的上传文件出错问题...
- 非IT专业大学生对erp的思考
- 腾讯云dts使用注意事项
- 小辣椒android密码怎样开,小辣椒手机忘记密码怎么恢复出厂设置
- python处理文本_Python处理文本文件中控制字符的方法
- java文本框内容覆盖6_java中读入一个TXT文件到文本框空如何覆盖以前读的内容?...
- 广度搜索 -- 9.2 Word Ladder -- 求具体的路径 -- 图解