java骨架_基于红黑树的骨架提取Java

这个Java代码实现了一个基于红黑树的骨架提取算法,用于图像处理。类`Framework`包含了图像的宽度、高度、像素信息,以及与红黑树相关的方法。它通过遍历二值化图像,利用lutTreeNum和lutTreeIdx数组,将待移除点插入到相应的红黑树中,逐步提取图像的骨架。
摘要由CSDN通过智能技术生成

1 packagecom.example.lenovo.linehough;2

3 importandroid.graphics.Color;4

5 public classFramework {6 intwidth;7 intheight;8 intFpn;9 int[] pixels;10 int[] treeValue;11 GRBTree[] grbTree;12 intcurrentTree;13 TList[] L;14 int[] InfluencedPnt;15 int lutTreeNum[] ={16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,17 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 2,18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,19 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1,20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,21 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 1,22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,25 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,27 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,29 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0,30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,31 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,35 0, 0, 1, 1, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,41 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,43 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,45 1, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0,46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,47 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0

48 };49

50 int lutTreeIdx1[] ={51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,52 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 3, 0, 0, 3, 2,53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,54 0, 0, 5, 5, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 2,55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3,57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,60 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,64 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,66 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,70 0, 0, 5, 5, 6, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,76 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,78 7, 0, 0, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,80 4, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,82 4, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0

83 };84

85 int lutTreeIdx2[] ={86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,89 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,99 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

118 };119

120 publicFramework() {121

122 }123

124 //TList建立一个矩阵,矩阵元素包含TreeIndex,Visited两个字段;125 //TreeIndex记录待移除点对应的红黑树序号(0~7),TreeIndex为-1时,该点为非移除点;Visited标记点是否被访问过了

126 public classTList {127 intTreeIndex;128 intVisited;129

130 publicTList() {131 this.TreeIndex = -1;132 this.Visited = 0;133 }134 }135

136 //提取骨架

137 public int[] getFramework(int w, int h, int[] inputs) {138 width =w;139 height =h;140 pixels = new int[width *height];141 //黑色为1,白色为0

142 for (int y = 0; y < height; y++) {143 for (int x = 0; x < width; x++) {144 if (inputs[y * width + x] ==Color.BLACK)145 pixels[y * width + x] = 1;146 else pixels[y * width + x] = 0;147 }148 }149 //新建8个红黑树对象

150 grbTree = new GRBTree[8];151 for (int i = 0; i <= 7; i++) {152 grbTree[i] = newGRBTree();153 }154 currentTree = 0;155

156 L = new TList[width *height];157 for (int i = 0; i < width * height; i++) {158 L[i] = newTList();159 }160 //第一次遍历二值化图像

161 FirstMatchTree();162

163 //当所有的树里面不再插入结点的时候,说明骨架已经生成,即n0~n7都为0

164 while (grbTree[0].root != null || grbTree[1].root != null || grbTree[2].root != null || grbTree[3].root != null ||

165 grbTree[4].root != null || grbTree[5].root != null || grbTree[6].root != null || grbTree[7].root != null) {166 for (int round = 0; round <= 7; round++) {167 treeValue = new int[width *height];168 //前序遍历树currentTree的移除点索引值,将它们先存放在数组treeValue里面

169 treeValue =grbTree[currentTree].preOrder(width, height);170 //存放在树currentTree里面的移除点总数

171 int valueCount =grbTree[currentTree].getiCount();172

173 //再清空树currentTree里面的数据,root置为null

174 grbTree[currentTree].Free();175

176 currentTree++;177 if (currentTree == 8) currentTree = 0;178

179 //更新pixels,L

180 for (int i1 = 0; i1 < valueCount; i1++) {181 int pntIndex =treeValue[i1];182 pixels[pntIndex] = 0;183 L[pntIndex].TreeIndex = -1;//TreeIndex为-1时,该点为非移除点

184 L[pntIndex].Visited = -1;//Visited为-1时,表明该点已成为非待移除点

185 }186 //遍历数组treeValue,InfluencedPnt记录受影响的领域点坐标,Fpn为受影响点的个数

187 InfluencedPnt = new int[width *height];188 Fpn = 0;189 for (int i1 = 0; i1 < valueCount; i1++) {190 int pntIndex =treeValue[i1];191 //查找移除点的8领域点

192 for (int i2 = -1; i2 <= 1; i2++) {193 for (int i3 = -1; i3 <= 1; i3++) {194 if (i2 == 0 && i3 == 0) continue;195 //8个领域点的下标索引值index

196 int index = pntIndex + i2 * width +i3;197 if (index < 0) index = 0;198 if (index > width * height - 1)199 index = width * height - 1;200 //该领域点为白点直接退出

201 if (pixels[index] == 0) continue;202 //Visite为1时,表明该领域点已被访问过,直接退出;

203 if (L[index].Visited == 1) continue;204 else{205 L[index].Visited = 1;206 InfluencedPnt[Fpn] =index;207 Fpn++;208 }209 //更新树T0到T7,只要检测到8领域点是待移除点的话,首先将它从原来的树里面删除;不是的话,不操作;210 //之后再根据该领域点的3*3结构(可能发生变化)来判断它是否是待移除点,以及它该插入到哪棵红黑树里面

211 int treeindex =L[index].TreeIndex;212 if (treeindex >= 0)213 grbTree[treeindex].Delete(index);214 //获取领域点index的3*3结构

215 int[] b = new int[9];216 for (int i4 = -1; i4 <= 1; i4++) {217 for (int i5 = -1; i5 <= 1; i5++) {218 int index8 = index + i5 * width +i4;219 if (index8 < 0) index = 0;220 if (index8 > width * height - 1)221 index8 = width * height - 1;222 b[(i4 + 1) * 3 + (i5 + 1)] =pixels[index8];223 }224 }225 //计算领域点index对应的lutTreeNum的下标值lutValue

226 int lutValue = 0;227 for (int i = 0; i <= 8; i++) {228 if (b[i] == 1)229 lutValue += Math.pow(2, i);230 }231 //将待移除的领域点index插入对应的红黑树k里面,并将k值记录到L中

232 int k =Put(index, lutValue);233 if (k >= 0) L[index].TreeIndex =k;234 else L[index].TreeIndex = -1;235 }236 }237 }238

239 for (int i = 0; i < Fpn; i++) {240 int f =InfluencedPnt[i];241 L[f].Visited = 0;242 }243

244 }245 }246 //while循环结束,再也没有移除点

247 for (int y = 0; y < height; y++) {248 for (int x = 0; x < width; x++) {249 if (pixels[y * width + x] == 1) inputs[y * width + x] =Color.BLACK;250 else inputs[y * width + x] =Color.WHITE;251 }252 }253 returninputs;254 }255

256 private voidFirstMatchTree() {257 //第一次遍历二值化图像,currentTree=0,把待移除点插入对应的红黑树里面

258 for (int y = 1; y < height - 1; y++) {259 for (int x = 1; x < width - 1; x++) {260 int pntIndex = y * width +x;261 //是白色点的话直接退出本次循环,检测下一个点

262 if (pixels[pntIndex] == 0) continue;263 //检测像素点的3*3领域结构,组成a[8]a[7]...a[1]a[0]的九位二进制数

264 int[] a = new int[9];265 for (int i = -1; i <= 1; i++) {266 for (int j = -1; j <= 1; j++) {267 a[(i + 1) * 3 + (j + 1)] = pixels[(y + j) * width + (x +i)];268 }269 }270 //通过上面的九位二进制数,计算出该像素点对应于lutTreeNum的下标值

271 int lutValue = 0;272 for (int i = 0; i <= 8; i++) {273 if (a[i] == 1)274 lutValue += Math.pow(2, i);275 }276 //k为树的序号数,pntIndex为待移除点的话,k的范围为0到7;不是待移除点的话,k为-1

277 int k =Put(pntIndex, lutValue);278 if (k >= 0) L[pntIndex].TreeIndex =k;279 else L[pntIndex].TreeIndex = -1;280 }281 }282 }283

284 private int GetTreeIndex(intlutValue) {285 if (lutTreeNum[lutValue] == 0)286 return -1;287

288 if (lutTreeNum[lutValue] == 1)289 returnlutTreeIdx1[lutValue];290

291 if (currentTree > lutTreeIdx1[lutValue] && currentTree <=lutTreeIdx2[lutValue])292 returnlutTreeIdx2[lutValue];293

294 returnlutTreeIdx1[lutValue];295 }296

297 private int Put(int pntIndex, intlutValue) {298 int ti =GetTreeIndex(lutValue);299

300 if (ti < 0)301 return -1;302

303 grbTree[ti].Insert(pntIndex);304

305 returnti;306 }307

308 private void Delete(int pntIndex, intlutValue) {309 int ti =GetTreeIndex(lutValue);310

311 if (ti < 0 || ti ==currentTree)312 return;313

314 grbTree[ti].Delete(pntIndex);315 }316

317

318 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值