1. 程式人生 > >基於Mat變換的骨架提取Java

基於Mat變換的骨架提取Java

and ati ++ index turn 證明 public phi ont

針對一副二值圖像,區域內的點只有背景點(白點,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
/** 6 * Created by lenovo on 2016/6/20. 7 */ 8 public class Mat { 9 10 public static int[] matswitch(int w, int h, int[] inputs) { 11 int[] imgBuf = new int[w * h]; 12 int[] neighbor = new int[10]; 13 int[] mark = new int[w * h]; 14 int markNum1; 15 int
markNum2; 16 boolean s = true; 17 for(int index=0;index<w*h;index++) 18 imgBuf[index] = inputs[index]; 19 while (s) { 20 //第一步,統一黑點值為1,白點值為0 21 markNum1 = 0;//步驟1中標記被刪除的邊界點的個數 22 for (int x = 1; x < w - 1; x++) { 23 for (int y = 1; y < h - 1; y++) { 24 //條件1:p必須是邊界點,值為1, 8鄰域內至少有1個像素點值為0 25 if (imgBuf[y * w + x] == Color.WHITE) continue; 26 int[] detectBlack = new int[10]; 27 neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;//黑點neighbor為0,白點neighbor為1 28 neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255; 29 neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255; 30 neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255; 31 neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255; 32 neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255; 33 neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255; 34 neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255; 35 for (int i = 2; i <= 9; i++) { 36 if (neighbor[i] == 0) 37 detectBlack[i]++;//(黑點)neighbor為0,detectBlack就為1;(白點)neighbor為1,detectBlack就為0 38 } 39 //8領域的點都是黑點,證明該點不是邊界點,退出該輪循環,檢測下一個點 40 if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5] 41 * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0) 42 continue; 43 44 //條件2:2<=N(p)<=6 45 int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5] 46 + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]); 47 if (np < 2 || np > 6) continue; 48 49 //條件3:T(p)=1 50 int tp = 0; 51 for (int i = 3; i <= 9; i++) { 52 /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/ 53 if (detectBlack[i] - detectBlack[i - 1] == 1) 54 tp++; 55 } 56 if (detectBlack[2] - detectBlack[9] == 1) 57 tp++; 58 if (tp != 1) continue; 59 60 //條件4:p2*p4*p6=0 61 if (detectBlack[2] * detectBlack[4] * detectBlack[6] != 0) 62 continue; 63 //條件5:p4*p6*p8=0 64 if (detectBlack[4] * detectBlack[6] * detectBlack[8] != 0) 65 continue; 66 67 //標記要被刪除的點 68 mark[y * w + x] = 1; 69 markNum1++; 70 } 71 } 72 73 //將標記刪除的點置為背景色 74 if (markNum1 > 0) { 75 for (int x = 1; x < w - 1; x++) { 76 for (int y = 1; y < h - 1; y++) { 77 //刪除被標記的點,即置為背景色黑色 78 if (mark[y * w + x] == 1) { 79 imgBuf[y * w + x] = Color.WHITE; 80 } 81 } 82 } 83 } 84 85 86 //第二步 87 markNum2 = 0;//步驟2中標記被刪除的點的個數 88 for (int x = 1; x < w - 1; x++) { 89 for (int y = 1; y < h - 1; y++) { 90 //條件1:p必須是前景點BLACK 91 if (imgBuf[y * w + x] == Color.WHITE) continue; 92 int[] detectBlack = new int[10]; 93 neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255; 94 neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255; 95 neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255; 96 neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255; 97 neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255; 98 neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255; 99 neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255; 100 neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255; 101 for (int i = 2; i < 10; i++) { 102 if (neighbor[i] == 0) detectBlack[i]++; 103 } 104 105 if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5] 106 * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0) 107 continue; 108 109 //條件2:2<=N(p)<=6 110 int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5] 111 + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]); 112 if (np < 2 || np > 6) continue; 113 114 //條件3:T(p)=1 115 int tp = 0; 116 for (int i = 3; i <= 9; i++) { 117 /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/ 118 if (detectBlack[i] - detectBlack[i - 1] == 1) 119 tp++; 120 } 121 if (detectBlack[2] - detectBlack[9] == 1) 122 tp++; 123 if (tp != 1) continue; 124 125 //條件4:p2*p4*p8==0 126 if (detectBlack[2] * detectBlack[4] * detectBlack[8] != 0) 127 continue; 128 //條件5:p2*p6*p8==0 129 if (detectBlack[2] * detectBlack[6] * detectBlack[8] != 0) 130 continue; 131 132 //標記刪除 133 mark[y * w + x] = 1; 134 markNum2++; 135 } 136 } 137 138 //將標記刪除的點置為背景色WHITE 139 if (markNum2 > 0) { 140 for (int x = 1; x < w - 1; x++) { 141 for (int y = 1; y < h - 1; y++) { 142 if (mark[y * w + x] == 1) { 143 imgBuf[y * w + x] = Color.WHITE; 144 } 145 } 146 } 147 } 148 //先步驟1再步驟2,一次周期循環後,不再出現標記刪除的點時,說明已生成骨架了 149 if (markNum1 == 0 && markNum2 == 0) s = false; 150 else s = true; 151 } 152 return imgBuf; 153 } 154 155 156 }

基於Mat變換的骨架提取Java