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 }