?? imagemanip.c
字號:
FvsInt_t peak_pos[BLOCK_L]; /* 頂點 */ FvsInt_t peak_cnt; /* 頂點數目 */ FvsFloat_t peak_freq; /* 頂點頻率 */ FvsFloat_t Xsig[BLOCK_L]; /* x signature */ FvsFloat_t pmin, pmax; memset(out, 0, size); memset(freq, 0, size); /* 1 - 圖像分塊 BLOCK_W x BLOCK_W - (16 x 16) */ for (y = BLOCK_L2; y < h-BLOCK_L2; y++) for (x = BLOCK_L2; x < w-BLOCK_L2; x++) { /* 2 - 脊線方向的窗口 l x w (32 x 16) */ dir = orientation[(x+BLOCK_W2) + (y+BLOCK_W2)*w]; cosdir = -sin(dir); sindir = cos(dir); /* 3 - 計算 x-signature X[0], X[1], ... X[l-1] */ for (k = 0; k < BLOCK_L; k++) { Xsig[k] = 0.0; for (d = 0; d < BLOCK_W; d++) { u = (FvsInt_t)(x + (d-BLOCK_W2)*cosdir + (k-BLOCK_L2)*sindir); v = (FvsInt_t)(y + (d-BLOCK_W2)*sindir - (k-BLOCK_L2)*cosdir); /* clipping */ if (u<0) u = 0; else if (u>w-1) u = w-1; if (v<0) v = 0; else if (v>h-1) v = h-1; Xsig[k] += p[u + (v*pitchi)]; } Xsig[k] /= BLOCK_W; } /* 計算 T(i,j) */ /* 尋找 x signature 中的頂點 */ peak_cnt = 0; pmax = pmin = Xsig[0]; for (k = 1; k < BLOCK_L; k++) { if (pmin>Xsig[k]) pmin = Xsig[k]; if (pmax<Xsig[k]) pmax = Xsig[k]; } if ((pmax - pmin)>64.0) { for (k = 1; k < BLOCK_L-1; k++) if ((Xsig[k-1] < Xsig[k]) && (Xsig[k] >= Xsig[k+1])) { peak_pos[peak_cnt++] = k; } } /* 計算均值 */ peak_freq = 0.0; if (peak_cnt>=2) { for (k = 0; k < peak_cnt-1; k++) peak_freq += peak_pos[k+1]-peak_pos[k]; peak_freq /= peak_cnt-1; } /* 4 - 驗證頻率范圍 [1/25-1/3] */ /* 可以擴大到 [1/30-1/2] */ if (peak_freq > 30.0) out[x+y*w] = 0.0; else if (peak_freq < 2.0) out[x+y*w] = 0.0; else out[x+y*w] = 1.0/peak_freq; } /* 5 - 未知點 */ for (y = BLOCK_L2; y < h-BLOCK_L2; y++) for (x = BLOCK_L2; x < w-BLOCK_L2; x++) { if (out[x+y*w]<EPSILON) { if (out[x+(y-1)*w]>EPSILON) { out[x+(y*w)] = out[x+(y-1)*w]; } else { if (out[x-1+(y*w)]>EPSILON) out[x+(y*w)] = out[x-1+(y*w)]; } } } /* 6 - 頻率插值 */ for (y = BLOCK_L2; y < h-BLOCK_L2; y++) for (x = BLOCK_L2; x < w-BLOCK_L2; x++) { k = x + y*w; peak_freq = 0.0; for ( v = -LPSIZE; v <= LPSIZE; v++) for ( u = -LPSIZE; u <= LPSIZE; u++) peak_freq += out[(x+u)+(y+v)*w]; freq[k] = peak_freq*LPFACTOR; } free(out); } return nRet;}/****************************************************************************** * 功能:獲取指紋圖像的有效區域,以進行進一步的處理。 * 如果某個區域不可用用,則掩碼置為0,包括如下區域: * 邊界,背景點,圖像質量很差的區域。 * 有效區域的掩碼置為255。 * 參數:image 指紋圖像 * direction 脊線方向 * frequency 脊線頻率 * mask 輸出的掩碼 * 返回:錯誤編號******************************************************************************/FvsError_t FingerprintGetMask(const FvsImage_t image, const FvsFloatField_t direction, const FvsFloatField_t frequency, FvsImage_t mask){ FvsError_t nRet = FvsOK; FvsFloat_t freqmin = 1.0 / 25; FvsFloat_t freqmax = 1.0 / 3; /* 輸入圖像的寬度高度 */ FvsInt_t w = ImageGetWidth (image); FvsInt_t h = ImageGetHeight(image); FvsByte_t* out; FvsInt_t pitchout; FvsInt_t pos, posout, x, y; FvsFloat_t* freq = FloatFieldGetBuffer(frequency); if (freq==NULL) return FvsMemory; /* 需要做改進:檢查 */ nRet = ImageSetSize(mask, w, h); if (nRet==FvsOK) nRet = ImageClear(mask); out = ImageGetBuffer(mask); if (out==NULL) return FvsMemory; if (nRet==FvsOK) { pitchout = ImageGetPitch(mask); for (y = 0; y < h; y++) for (x = 0; x < w; x++) { pos = x + y * w; posout = x + y * pitchout; out[posout] = 0; if (freq[pos] >= freqmin && freq[pos] <= freqmax) { out[posout] = 255; } } /* 補洞 */ for (y = 0; y < 4; y++) (void)ImageDilate(mask); /* 去除邊界 */ for (y = 0; y < 12; y++) (void)ImageErode(mask); } return nRet;}/* 細化算法 */#undef P#define P(x,y) ((x)+(y)*pitch)#define REMOVE_P { p[P(x,y)]=0x80; changed = FvsTrue; }/******************************************************************************** 鄰域點定義如下:** 9 2 3** 8 1 4** 7 5 6******************************************************************************//* 宏定義 */#define P1 p[P(x ,y )]#define P2 p[P(x ,y-1)]#define P3 p[P(x+1,y-1)]#define P4 p[P(x+1,y )]#define P5 p[P(x+1,y+1)]#define P6 p[P(x ,y+1)]#define P7 p[P(x-1,y+1)]#define P8 p[P(x-1,y )]#define P9 p[P(x-1,y-1)]FvsError_t ImageRemoveSpurs(FvsImage_t image){ FvsInt_t w = ImageGetWidth(image); FvsInt_t h = ImageGetHeight(image); FvsInt_t pitch = ImageGetPitch(image); FvsByte_t* p = ImageGetBuffer(image); FvsInt_t x, y, n, t, c; c = 0; do { n = 0; for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) { if( p[P(x,y)]==0xFF) { t=0; if (P3==0 && P2!=0 && P4==0) t++; if (P5==0 && P4!=0 && P6==0) t++; if (P7==0 && P6!=0 && P8==0) t++; if (P9==0 && P8!=0 && P2==0) t++; if (P3!=0 && P4==0) t++; if (P5!=0 && P6==0) t++; if (P7!=0 && P8==0) t++; if (P9!=0 && P2==0) t++; if (t==1) { p[P(x,y)] = 0x80; n++; } } } for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) { if( p[P(x,y)]==0x80) p[P(x,y)] = 0; } } while (n>0 && ++c < 5); return FvsOK;}/* a) 驗證其有2-6個鄰點 */#define STEP_A n = 0; /* 鄰點個數 */ \ if (P2!=0) n++; if (P3!=0) n++; if (P4!=0) n++; if (P5!=0) n++; \ if (P6!=0) n++; if (P7!=0) n++; if (P8!=0) n++; if (P9!=0) n++; \ if (n>=2 && n<=6)/* b) 統計由0變1的個數 */#define STEP_B t = 0; /* 變化的數目 */ \ if (P9==0 && P2!=0) t++; if (P2==0 && P3!=0) t++; \ if (P3==0 && P4!=0) t++; if (P4==0 && P5!=0) t++; \ if (P5==0 && P6!=0) t++; if (P6==0 && P7!=0) t++; \ if (P7==0 && P8!=0) t++; if (P8==0 && P9!=0) t++; \ if (t==1)/****************************************************************************** * 功能:細化指紋圖像 * 圖像必須是二值化過的(只包含0x00或oxFF) * 該算法基于領域的判斷,決定某個象素該移去還是保留 * 參數:image 指紋圖像 * 返回:錯誤編號******************************************************************************/ FvsError_t ImageThinConnectivity(FvsImage_t image){ FvsInt_t w = ImageGetWidth(image); FvsInt_t h = ImageGetHeight(image); FvsInt_t pitch = ImageGetPitch(image); FvsByte_t* p = ImageGetBuffer(image); FvsInt_t x, y, n, t; FvsBool_t changed = FvsTrue; if (p==NULL) return FvsMemory; if (ImageGetFlag(image)!=FvsImageBinarized) return FvsBadParameter; while (changed==FvsTrue) { changed = FvsFalse; for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) { if (p[P(x,y)]==0xFF) { STEP_A { STEP_B { /* c) 2*4*6=0 (2,4 ,or 6 為0) d) 4*6*8=0 */ if (P2*P4*P6==0 && P4*P6*P8==0) REMOVE_P; } } } } for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) if (p[P(x,y)]==0x80) p[P(x,y)] = 0; for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) { if (p[P(x,y)]==0xFF) { STEP_A { STEP_B { /* c) 2*6*8=0 d) 2*4*8=0 */ if (P2*P6*P8==0 && P2*P4*P8==0) REMOVE_P; } } } } for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) if (p[P(x,y)]==0x80) p[P(x,y)] = 0; } ImageRemoveSpurs(image); return ImageSetFlag(image, FvsImageThinned);} /* 重新定義 REMOVE_P */#undef REMOVE_P#define REMOVE_P { p[P(x,y)]=0x00; changed = FvsTrue; }/****************************************************************************** * 功能:細化指紋圖像,使用“Hit and Miss”結構元素。 * 圖像必須是二值化過的(只包含0x00或oxFF) * 該算法的缺點是產生很多偽造的線條(偽特征), * 必須由另外的算法來消除,后處理非常必要。 * 參數:image 指紋圖像 * 返回:錯誤編號******************************************************************************/FvsError_t ImageThinHitMiss(FvsImage_t image){ FvsInt_t w = ImageGetWidth(image); FvsInt_t h = ImageGetHeight(image); FvsInt_t pitch = ImageGetPitch(image); FvsByte_t* p = ImageGetBuffer(image); /* // // 0 0 0 0 0 // 1 1 1 0 // 1 1 1 1 // */ FvsInt_t x,y, t; FvsBool_t changed = FvsTrue; if (p==NULL) return FvsMemory; if (ImageGetFlag(image)!=FvsImageBinarized) return FvsBadParameter; while (changed==FvsTrue) { changed = FvsFalse; for (y=1; y<h-1; y++) for (x=1; x<w-1; x++) { if (p[P(x,y)]==0xFF) { /* // 0 0 0 0 1 1 1 1 1 0 // 1 0 1 1 1 1 1 0 // 1 1 1 0 1 0 0 0 1 0 */ if (p[P(x-1,y-1)]==0 && p[P(x,y-1)]==0 && p[P(x+1,y-1)]==0 && p[P(x-1,y+1)]!=0 && p[P(x,y+1)]!=0 && p[P(x+1,y+1)]!=0) REMOVE_P; if (p[P(x-1,y-1)]!=0 && p[P(x,y-1)]!=0 && p[P(x+1,y-1)]!=0 && p[P(x-1,y+1)]==0 && p[P(x,y+1)]==0 && p[P(x+1,y+1)]==0) REMOVE_P; if (p[P(x-1,y-1)]==0 && p[P(x-1,y)]==0 && p[P(x-1,y+1)]==0 && p[P(x+1,y-1)]!=0 && p[P(x+1,y)]!=0 && p[P(x+1,y+1)]!=0) REMOVE_P; if (p[P(x-1,y-1)]!=0 && p[P(x-1,y)]!=0 && p[P(x-1,y+1)]!=0 && p[P(x+1,y-1)]==0 && p[P(x+1,y)]==0 && p[P(x+1,y+1)]==0) REMOVE_P; /* // 0 0 0 0 1 1 // 1 1 0 0 1 1 0 1 1 1 1 0 // 1 1 0 0 0 0 */ if (p[P(x,y-1)]==0 && p[P(x+1,y-1)]==0 && p[P(x+1,y)]==0 && p[P(x-1,y)]!=0 && p[P(x,y+1)]!=0) REMOVE_P; if (p[P(x-1,y-1)]==0 && p[P(x,y-1)]==0 && p[P(x-1,y)]==0 && p[P(x+1,y)]!=0 && p[P(x,y+1)]!=0) REMOVE_P; if (p[P(x-1,y+1)]==0 && p[P(x-1,y)]==0 && p[P(x,y+1)]==0 && p[P(x+1,y)]!=0 && p[P(x,y-1)]!=0) REMOVE_P; if (p[P(x+1,y+1)]==0 && p[P(x+1,y)]==0 && p[P(x,y+1)]==0 && p[P(x-1,y)]!=0 && p[P(x,y-1)]!=0) REMOVE_P; } } } ImageRemoveSpurs(image); return ImageSetFlag(image, FvsImageThinned);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -