You are on page 1of 28

Trang 88

Chương 6

Xây dựng thư viện nhận dạng vân tay trên họ ARM
Nội dung của chương này sẽ trình bày kiến trúc hệ thống nhận dạng vân tay và mô tả chi tiết các thuật toán nhận dạng vân tay nào đuợc xây dựng trên họ vi xử lý ARM; từ việc chuẩn hóa, tăng cường, rút trích đặc trưng, … đến việc đối sánh vân tay. Ngoài ra, chương này còn trình bày một vài cải tiến để thuật toán nhận dạng vân tay phù hợp trên họ vi xử lý ARM.

6.1 Các vấn đề khi xây dựng thư viện nhận dạng vân tay trên họ ARM
6.1.1 Khả năng tính toán Một trong các hạn chế của họ ARM là khả năng tính toán của vi xử lý. Vi xử lý họ ARM dùng trong luận văn này là EP9315-CB có tốc độ xử lý 200MHz; chậm hơn nhiều so với máy tính để bàn thông thường, tốc độ này bằng khoảng 1/10 tốc độ của máy tính cá nhân. Còn tốc độ tính toán trên số thực còn thấp hơn rất nhiều (chậm hơn 60 lần). Một vấn đề khác là vi xử lý EP9315-CB sử dụng bộ xử lý RISC chỉ thực hiện một lệnh trong một chu kỳ CPU nên thời gian tính toán sẽ kéo dài hơn. Các phép toán trong bộ thư viện nhận dạng vân tay có yêu cầu về tốc độ tính toán rất lớn. Để thực hiện việc nhận dạng vân tay cần rất nhiều thao tác tính toán số học khá phức tạp. Các phép tính được thao tác nhiều trên số thực, đồng thời thực hiện sin, cos rất tốn tài nguyên bộ xử lý; do đó, việc xây dựng thư viện nhận dạng vân tay phải xem xét kỹ và tối ưu hóa về mặt xử lý tính toán để làm giảm thời gian chờ cho người sử dụng.

Trang 89

6.1.2 Khả năng lưu trữ Bo mạch NK9315 có bộ nhớ lưu trữ nhỏ và không gian bộ nhớ để thực thi chương trình cũng bị hạn chế. Mặc dù đã có các thiết bị thẻ nhớ để làm tăng bộ nhớ nhưng việc hạn chế về khả năng lưu trữ của bo mạch NK9315 cũng gây khó khăn cho lập trình viên xây dựng bộ thư viện và các ứng dụng. Điều này dẫn đến việc bộ thư viện trên bo mạch NK9315 phải được tối ưu về kích thước tập tin thực thi và lượng bộ nhớ sử dụng trong khi thi hành chương trình. Bộ thư viện và ứng dụng cần một lượng bộ nhớ để có thể lưu trữ các thông tin về mẫu đặc trưng vân tay của người dùng. Số lượng mẫu đặc trưng vân tay của người dùng cần lưu trữ nhiều thì sẽ chiếm khá nhiều bộ nhớ của bo mạch NK9315; do đó, cấu trúc dùng để lưu trữ cho các mẫu đặc trưng vân tay cần phải tổ chức cấu trúc lưu trữ sao cho ít tốn bộ nhớ mà vẫn đảm bảo cho việc đối sánh vân tay. 6.1.3 Mức độ hỗ trợ của các thư viện lập trình Do bo mạch NK9315 cài đặt hệ điều hành Embedded Linux, nên các thư viện lập trình hỗ trợ trên hệ điều hành này hạn chế. Để xây dựng bộ thư viện và các ứng dụng thì hầu hết chỉ sử dụng thư viện chuẩn C/C++. Việc tính toán các phép toán trên số thực của bo mạch NK9135 có sai số (không có độ chính xác bằng thư viện lập trình trên Window hay Linux). Điều này dẫn đến độ chính xác đối sánh vân tay cũng giảm. Công cụ để hỗ trợ lập trình cho bo mạch NK9135 gần như là không có. Để biên dịch thư viện hay ứng dụng thì phải làm hoàn toàn bằng tay; mở tập tin văn bản thô sơ, và gõ lệnh command line để làm.

6.2 Các giải pháp cụ thể
Thực hiện xây dựng bộ thư viện nhận dạng vân tay đòi hỏi phải có các tính chất quyết định sau: • Độ chính xác của các thuật toán phải đạt ở mức cao. • Tốc độ thuật toán ở mức thời gian thực.

Kiến trúc xây dựng hệ thống nhận dạng vân tay trên họ vi xử lý ARM gồm ba thành phần chính: 1. nghĩa là độ chính xác của thuật toán giảm xuống. . Các giải pháp có thể đề cập đến trong quá trình xây dựng thư viện nhận dạng vân tay là sử dụng các thư viện sẵn.Trang 90 Với những hạn chế đã nêu ở trên mà vẫn đảm bảo tốc độ thực hiện.3.1 Kiến trúc chung của hệ thống nhận dạng vân tay.1 Xây dựng thư viện vân tay Hình 6. 6. Thư viện nhận dạng vân tay SFSLib cung cấp các thành phần xử lý chính như: o Đọc tập tin và các thông tin từ ảnh vân tay. Việc cài đặt thuật toán phải làm trên các số nguyên thay cho các phép toán số thực. Nhưng ta phải đánh đổi độ chính xác của thuật toán.3 Xây dựng kiến trúc hệ thống nhận dạng vân tay trên họ ARM 6. phần xử lý này được cài đặt trong phần Image Modules).

2 Xây dựng cấu trúc mẫu đặc trưng đã được rút trích Việc xây dựng cấu trúc mẫu đặc trưng đã được rút trích dùng cho mục đích tránh phải rút trích đặc trưng nhiều lần trên cùng một vân tay. Cấu trúc mẫu đặc trưng vân tay đã được rút trích gồm các thành phần: • m_nCore: số điểm core. o Đối sánh vân tay. Phần xử lý lưu trữ cung cấp các thành phần xử lý nhằm lưu trữ các đặc trưng của các dấu vân tay đã được đăng ký vào hệ thống.Trang 91 o Tăng cường ảnh.2 Các thành phần của mẫu đặc trưng đã được rút trích.3. 3. Phần xử lý với đầu đọc vân tay cung cấp các thành phần đọc dữ liệu do thiết bị đầu đọc vân tay truyền xuống để hệ thống nhận dạng được thiết bị. phần xử lý này được cài đặt thành hàm FP_PreProcessing. . o Rút trích đặc trưng. Việc này cần thiết cho việc nhận dạng dấu vân tay. phần xử lý này được cài đặt thành hàm FP_Extract. Hình 6. 6. giúp cho việc tiết kiệm thời gian khi đối sánh vân tay. 2. phần xử lý này được cài đặt thành hàm FP_Matching.

1.1 Đặt vấn đề Phương pháp lọc Gabor được triển khai bởi Lin Hong [32] là một trong những phương pháp Tăng cường ảnh vân tay phổ biến nhất hiện nay. 6.y) và hướng của đặc trưng. • m_pDir: mãng chứa các hướng giữa 1 đặc trưng với 2 đặc trưng lân cận nó.3 thể hiện toàn bộ các bước chính của thuật toán Tăng cường ảnh bằng phương pháp lọc Gabor [32].4. Để tối ưu tốc độ chạy trên các họ vi xử lý ARM chúng tôi dùng các phương pháp sau để cài đặt mã chương trình cho thư viện SFSLib: . Fp_PreProcessing(SFSImage pImg) Begin call InitializeInt() call Segment() call Normalize(pImg) call EstimateOrient(pImg) call EstimateFrequency(pImg) call GaborFilter(pImg) end Hình 6.1 Tăng cường ảnh bằng phương pháp lọc Gabor 6.3. • m_pDist: mãng chứa các khoảng cách giữa các đặc trưng. bao gồm tọa độ (x.Trang 92 • m_pCore: mãng chứa các điểm core. • m_pMinutiae: mãng chứa các đặc trưng đã được rút trích. • m_pCross: mãng chứa giá trị đếm số vân giữa 2 đặc trưng.1.4. 6. • m_nMinutiae: số đặc trưng đã được rút trích.2 Xây dựng thuật toán Hình 6.4. Phương pháp này sẽ cho ra ảnh vân tay có chất lượng tốt sau khi được tăng cường. Khung thuật toán Tăng cường ảnh bằng phương pháp lọc Gabor.4 Xây dựng thư viện nhận dạng vân tay 6.

tính trước các giá trị số thực lưu vào trong một mãng. • Sử dụng đếm ngược trong vòng lặp để tăng tốc độ [38]. và các phép tính trước sin. vì vi xử lý này không hỗ trợ tính toán số thực.4. cos theo các góc for k = 0 to g_nOrientRange – 1 pSin[k] = SIN(fOrient) pCos[k] = COS(fOrient) fOrient = fOrient + fDecli end for pX = g_nWindowXInt pY = g_nWindowYInt for k = 0 to g_nOrientRange – 1 fSin = pSin[k] fCos = pCos[k] for x = –(g_nWindowWidth / 2) to (g_nWindowWidth + 1) / 2 + 1) / 2 for y = –(g_nWindowHeight / 2) to (g_nWindowHeight . Hình 6.4 thể hiện thuật toán khởi tạo các thông số cần thiết phục vụ cho việc tính toán trên số nguyên thay cho số thực. artan2. Việc khởi tạo này giúp tránh xử lý số thực để thuật toán chạy nhanh hơn ở trên họ vi xử lý ARM.Trang 93 • Đổi các tính toán số thực sang số nguyên. • Thay thế những hàm được gọi nhiều trong thư viện bằng Macro [38]. Đặc biệt phương pháp này rất hữu dụng với vi xử lý EP9315-CB mà chúng tôi đang dùng. Hình 6. như: tính trước cos. • Lưu mảng 2 chiều thành mảng 1 chiều để truy xuất các phần tử trong mảng nhanh hơn. InitializeInt() begin nSize = g_nOrientRange * g_nFrequencyRange * g_nGaborMask * g_nGaborMask fDecli = Q_PI / g_nOrientRange fOrient = –Q_PI_2 //Tính trước các giá trị sin. Khung thuật toán khởi tạo phục vụ cho tăng cường ảnh. sin. • Hạn chế sử dụng vòng lặp bằng cách dùng Macro để tránh việc nhảy mã lệnh nhiều lần làm phá vỡ pipeline [38]. cos. như: mặt nạ Gabor số nguyên (g_nGaborInt).

Trang 94 i = x * fCos – y * fSin j = x * fSin + y * fCos pX = i pY = j end for end for end for //Tính trước mảng Gabor dựa vào hướng và tần số fDecli = 0.6 thể hiện thuật toán phân đoạn ảnh nhằm loại bỏ các vùng ảnh bị nhiễu khi lấy từ thiết bị. Thuật toán dựa vào giá trị mean và variant để phân đoạn ảnh [32].5 / g_nFrequencyRange for i = 0 to g_nOrientRange – 1 fSin = pSin[i] fCos = pCos[i] for j = 0 to g_nFrequencyRange – 1 fFrequency = j * fDecli + 0.04 fSigma = 20 * fFrequency fR = –0.5 cho thấy kết quả của việc phân đoạn ảnh. .5 / (fSigma * fSigma) for x = – (g_nWindowWidth / 2) to (g_nWindowWidth + 1) / 2 for y = – (g_nWindowHeight / 2) to (g_nWindowHeight + 1) / 2 m = x * fCos + y * fSin n = –x * fSin + y * fCos fGabor = exp(fR * (m * m + n * n)) * COS(m * fFrequency * Q_2PI) g_nGaborInt = fGabor * 127 end for end for end for end for end Hình 6. Hình 6.

m_pPixel[u + 1.m_pPixel[u + 1.m_pPixel[u. Segment(SFSImage pImg) begin x = 1 for i = 0 to g_nSegmentHeight – 1 m = x + g_nSegmentBlock y = 1 for j = 0 to g_nSegmentWidth – 1 n = y + g_nSegmentBlock nXX = nYY = nXY = 0 nMean = nVar = 0 for u = x to m – 1 for v = y to n – 1 nMean = nMean + pImg.v]) * 2) + pImg. Hình 6.m_pPixel[u – 1.m_pPixel[u – 1.m_pPixel[u – 1.v – 1]) * 2) + pImg.m_pPixel[u – 1.m_pPixel[u.v – 1] nXX = nXX + nX * nX nYY = nYY + nY * nY nXY = nXY + nX * nY end for end for nMean = nMean / g_nSegmentBlock * g_nSegmentBlock for u = x to m – 1 for v = y to n – 1 nVar = nVar + (nMean – pImg.m_pPixel[u.v + 1] – pImg.v + 1] nY = pImg.v + 1] – pImg.m_pPixel[u + 1.v – 1] + ((pImg.v + 1] – pImg. Khung thuật toán phân đoạn ảnh phục vụ cho tăng cường ảnh.v]) * (nMean – pImg.m_pPixel[u.v] – pImg.m_pPixel[u – 1.m_pPixel[u + 1.m_pPixel[u.m_pPixel[u + 1.v – 1] + ((pImg.v – 1] – pImg.Trang 95 Hình 6. hình b) thể hiện độ thay đổi mức xám.6. hình c) hình vân tay sau khi đã phân đoạn. hình a) ảnh gốc. Kết quả phân đoạn ảnh với ngưỡng variance là 100 và kích thước vùng phân đoạn 16 x 16.v] nX = pImg.5.v]) end for .v + 1] – pImg.

7 thể hiện thuật toán chuẩn hóa ảnh [32]. Thuật toán này sẽ làm cho ảnh nhìn rỏ hơn một chút trước khi được đem đi tăng cường.7.Trang 96 g_nSegmentBlock) nYY) end for fVar = sqrt(nVar) / (g_nSegmentBlock * fCoh = nXX – nYY fCoh = sqrt(fCoh * fCoh + 4 * nXY * nXY) / (nXX + fW = fCoh * g_fSegmentWeight1 + nMean * g_fSegmentWeight2 + fVar * g_fSegmentWeight3 + g_fSegmentWeight4 if fW >= 0 then nSegment[i.50 then g_nInternalSegment[i. Normalize(SFSImage pImg) begin .80 then //hằng số 6 và 0.j] = 1 if nMean > 6 and fVar > 0.8 lần lượt là ngưỡng của mean và variant g_nSegment[i. Khung thuật toán chuẩn hóa ảnh phục vụ cho tăng cường ảnh.j] = 1 end if end if end for end for end Hình 6.j] = 1 end if y = y + g_nSegmentBlock end for x = x + g_nSegmentBlock end for for i = 0 to g_nSegmentHeight – 1 for j = 0 to g_nSegmentWidth – 1 nMean = 0 nVar = 0 for x = -1 to 1 for y = -1 to 1 m = i + x n = j + y if m >= 0 and m < g_nSegmentHeight and n >= 0 and n < g_nSegmentWidth then nMean = nMean + 1 if nSegment[m.n] <> 0 then nVar = nVar + 1 end if end if end for end for fVar = nVar / nMean if fVar > 0. Hình 6.

j] – fMean) * fVar else pPixel[i.m_nWidth – 1 pPixel[i.j] end if end for end for for i = 0 to pImg.j] > fMean then pPixel[i.j] = (pPixel[i. Chúng tôi đề xuất phương pháp làm . nhóm tác giả làm mượt hướng bằng phương pháp lọc trung bình.m_nWidth – 1 fVar = fVar + (pPixel[i.m_nWidth – 1 if pPixel[i.j] – fMean) * (pPixel[i.m_pPixel[i.Trang 97 word i.m_pPixel[i.j] > fMax then fMax = pPixel[i. fMax fMean = 0 fVar = 0 for i = 0 to pImg.j] end for end for fMean = fMean / nSize for i = 0 to pImg.m_nWidth – 1 pImg.m_nHeight – 1 for j = 0 to pImg. Trong bài báo gốc [28].j] + fMean) * fVar end if if pPixel[i.m_nHeight – 1 for j = 0 to pImg. fVar.9 thể hiện thuật toán ước lượng hướng vân.m_nHeight – 1 for j = 0 to pImg. Phương pháp làm mượt này thường cho kết quả hướng sai ở gần điểm core.j] = pImg.j] = 255 * (pPixel[i. fMin. j double pPixel [256.j] – fMean) end for end for fVar = sqrt(fVar/nSize) fVar = sqrt(1 / fVar) fMin = 0 fMax = 0 for i = 0 to pImg.j] – fMin) / (fMax – fMin) end for end for end Hình 6.m_nHeight – 1 for j = 0 to pImg.j] = – (pPixel[i.j] < fMin then fMin = pPixel[i.j] / 255 fMean = fMean + pPixel[i.j] end if if pPixel[i.256] double fMean.

nSumY word nOrientBlock double fOrient. EstimateOrient(SFSImage pImg) begin word i.8) đã khắc phục được hướng sai ở gần điểm core. Hình 6. hình b) dùng phương pháp lọc Gaussian.8. j. Hình 6.Trang 98 mượt bằng lọc Gaussian.y word nOrientHeight. nOrientWidth word nSumX. pDx. Khung thuật toán xác định hướng vân phục vụ cho tăng cường ảnh. x . pDy nOrientBlock = 7 nOrientHeight = (pImg. Kết quả của phương pháp này (hình 6.m_nWidth – 2) / nOrientBlock //Tính gradient magnitudes x = 3 for i = 0 to nOrientHeight – 1 k = (x – 1) / nSegmentBlock if k < nSegmentHeight then m = x + nOrientBlock y = 3 for j = 0 to nOrientWidth – 1 l = (y – 1) / nSegmentBlock if l < nSegmentWidth then if nInternalSegment[k.l] <> 0 then n = y + nOrientBlock nSumX = 0 nSumY = 0 .9.m_nHeight – 2) / nOrientBlock nOrientWidth = (pImg. Hình a) làm mượt hướng bằng phương pháp lọc trung bình.

j] * nGaussianMask_5[2.v + h] * nOrientMask[h + 3.2] if fOrient[i.m_pPixel[u + g.v + h] * nOrientMask[g + 3.h + 3] nX = nX + pImg.g + 3] end for end for nSumX = nSumX + nX * nY nY) * (nX + nY) nSumY = nSumX + (nX – nXX = nXX + nX * nX nXY = nXY + nX * nY nYY = nYY + nY * nY end for end for if (nXX + nYY) <> 0 then fCoh1 = nXX – nYY fCoh1 = sqrt(fCoh1 * fCoh1 + 4 * nXY * nXY) / (nXX + nYY) else fCoh1 = –1 end if pDx1 = nSumX * 2 pDy1 = nSumY end if end if y = y + nOrientBlock end for end if x = x + nOrientBlock end for //Hiệu chỉnh và làm mượt các hướng của block lại (dùng Gaussian) for i = 0 to nOrientHeight – 1 for j = 0 to nOrientWidth – 1 nSumX = nSumY = 0 nSumX = –pDx[i.2] nSumY = –pDy[i.m_pPixel[u + g.j] = 1 then for m = –nOrientGaussian to nOrientGaussian u = i + m if u >= 0 and u < nOrientHeight then .j] * nGaussianMask_5[2.Trang 99 nXX = nXY = nYY = 0 for u = x to m – 1 for v = x to n – 1 nX = 0 nY = 0 for g = –3 to 2 for h = –3 to 2 nY = nY + pImg.

10). Trong phần thuật toán này.5 * ATAN2(nSumX.j] = 0.n + nOrientGaussian] nSumY = nSumY + pDy[u.v] <> 0 and Hình 6. Phần cải tiến này đã loại bỏ được các đỉnh giả giúp cho việc ước lượng tần số chính xác hơn (hình 6. .n + nOrientGaussian] end if end if end for end if end for if nSumX <> 0 and nSumY <> 0 then fOrient[i. chúng tôi dùng phương pháp Gaussian với mặt nạ 1x5 để làm mượt các đỉnh hình sin sau khi đã ước lượng tần số.v] <> 0 then nSumX = nSumX + pDx[u.v] * nGaussianMask[m + nOrientGaussian.j] = 255 end if end for end for end v = j + n if v >= 0 and v < if pDx[u. nSumY) end if else fOrient[i.11 thể hiện thuật toán ước lượng tần số theo bài báo [32].Trang 100 for n = –nOrientGaussian to nOrientGaussian nOrientWidth then pDy[u.v] * nGaussianMask[m + nOrientGaussian.

n. k.m_nWidth then pSig[m + nW] = pSig[m + nW] + pImg. nH.l] if fOrient <> 255 then fSin = SIN(fOrient) fCos = COS(fOrient) for m = –nW to nW – 1 for n = –nH to nH – 1 u = x + (m * fCos – n * fSin) v = y + (m * fSin + n * fCos) if u >= 0 and u < pImg. EstimateFrequency(SFSImage pImg) begin double fSin. nPeakCount. Hình 6.v] pSigCount[m + nW] = pSigCount[m + nW] + 1 end if end for end for nValidSigCount = 0 for k = 0 to nWindowWidth – 1 if pSigCount[k] <> 0 then nValidSigCount = nValidSigCount + 1 pValidSig[nValidSigCount] = pSig[k] / pSigCount[k] end if end for for k = 2 to nWindowWidth – 3 . y. nValidSigCount.11.Trang 101 Hình 6. fMean. j.m_pPixel[u. Khung thuật toán ước lượng tần số phục vụ cho tăng cường ảnh.10. Làm mượt các đỉnh hình sin bằng phương pháp lọc Gaussian với mặt nạ 1x5 để loại bỏ các đỉnh giả. nSumDis nWindowWidth = 32 nWindowHeight = 16 nW = nWindowWidth / 2 nH = nWindowHeight / 2 x = nFrequencyBlock / 2 for i = 0 to nFrequencyHeight – 1 y = nFrequencyBlock / 2 for j = 0 to nFrequencyWidth – 1 k = x / nOrientBlock l = y / nOrientBlock if k >= nOrientHeight or l >= nOrientWidth then y = y + nFrequencyBlock continue end if fOrient = fOrient[k. v. l word nW. m. fVar word i. fCos. x. u.m_nHeight and v >= 0 and v < pImg. fOrient.

165 then fFrequency[i.04 or fFrequency[i.j] < 0.5 then fFrequency[i.j] = nPeakCount / nSumDis if fFrequency[i.1] <= pValidSig[k] and pValidSig[k] > pValidSig[k + 1] then if nPeakCount > 0 then nSumDis = nSumDis + k – l end if fMean = fMean + pValidSig[k] nPeakCount = nPeakCount + 1 l = k end if end for if nPeakCount > 2 then fMean = fMean / nPeakCount fVar = 0 for k = 1 to nValidSigCount – 2 if pValidSig[k – 1] <= pValidSig[k] and pValidSig[k] > pValidSig[k + 1] then if fMean > pValidSig[k] then fVar = fVar + fMean – pValidSig[k] else fVar = fVar + pValidSig[k] – fMean end if end if end for fVar = fVar / nPeakCount if (fVar / fMean) > 0.Trang 102 pValidSig[k] = (pValidSig[k – 2] + 2 * pValidSig[k – 1] + pValidSig[k] * 3 + 2 * pValidSig[k + 1] + pValidSig[k + 2]) / 9 end for nPeakCount = 0 nSumDis = 0 fMean = 0 for k = 1 to nWindowWidth – 2 if pValidSig[k .j] > 0.j] = 0 end if end if end if end if y = y + nFrequencyBlock end for x = x + nFrequencyBlock end for .j] = 0 else fFrequency[i.

g_nFrequencyBlock * g_nFrequencyWidth) nMaxY = min(g_nOrientBlock * g_nOrientHeight. Hình 6.12.m_nHeight) for i = 0 to nMaxY – 1 for j = 0 to nMaxX – 1 nOrient = g_nOrientInt[i / g_nOrientBlock. Kết quả của tăng cường ảnh (hình 6.y + nFrequencyGaussian] fOrient = fOrient + fFrequency[u.12 thể hiện thuật toán lọc Gabor [32].y + nFrequencyGaussian] end if end for end if end for if k <> 0 then fFrequency[i. GaborFilter(SFSImage pImg) begin SFSImage imgResult nMaxX = min(g_nOrientBlock * g_nOrientWidth.j / g_nOrientBlock] if nOrient <> 255 then .13). pImg. g_nFrequencyBlock * g_nFrequencyHeight) nMaskS = nMaskS – (g_nGaborMask / 2) nMaskE = (g_nGaborMask + 1) / 2 nMaskSize = g_nGaborMask * g_nGaborMask Image_Create(imgResult.Trang 103 //Hiệu chỉnh và làm mượt phần ước lượng hướng bằng phương pháp Gaussian for i = 0 to nFrequencyHeight – 1 for j = 0 to nFrequencyWidth – 1 fOrient = k = 0 for x = –nFrequencyGaussian to nFrequencyGaussian – 1 u = i + x if u >= 0 and u < g_nFrequencyHeight then for y = –nFrequencyGaussian to nFrequencyGaussian – 1 v = j + y if v >= 0 and v < g_nFrequencyWidth then k = k + nGaussianMask[x + nFrequencyGaussian.m_nWidth.v] * nGaussianMask[x + nFrequencyGaussian. Khung thuật toán lọc Gabor phục vụ cho tăng cường ảnh. pImg.j] = fOrient / k end if end for end for end Hình 6.

m_pPixel[i.m_nWidth then nConvolution = nConvolution + pGabor * pImg.m_pPixel[i.Trang 104 nFrequency = g_nFrequencyInt[i / g_nFrequencyBlock.j] = nConvolution / nWeight end if end if end if end if end for end for end .v] nWeight = nWeight + pGabor end if pGabor = pGabor + 1 end for else pGabor = pGabor + g_nGaborMask end if end for if nWeight <> 0 then if nConvolution <= 0 then imgResult.m_pPixel[i.m_pPixel[u.m_nHeight then for y = nMaskS to nMaskE – 1 v = j + y if v >= 0 and v < pImage.j] = nConvolution / nWeight pImg.j] = 0 else if nConvolution >= 255 * nWeight then imgResult.j / g_nFrequencyBlock] nWeight = nConvolution = 0 pGabor = g_nGaborInt + (nOrient * g_nFrequencyRange + nFrequency) * nMaskSize for x = nMaskS to nMaskE – 1 u = i + x if u > 0 and u < pImg.m_pPixel[i.j] = 255 else imgResult.

2. Hình 6.1 Đặt vấn đề Phương pháp rút trích các đặc trưng từ ảnh đã được nhị phân hóa là một phương pháp rút trích đơn giản [32].4.4.4. Extraction(SFSImage pImg. Khung thuật toán rút trích đặc trưng.14 thể hiện thuật toán rút trích đặc trưng từ ảnh đã được nhị phân hóa.Trang 105 Hình 6. pFea) end .2 Rút trích đặc trưng bằng phương pháp rút trích các đặc trưng từ ảnh đã được nhị phân hóa 6.13. Hình a) là ảnh vân tay đầu vào.2 Xây dựng thuật toán Hình 6. SFSFeature pFea) begin call Postprocessing(pImg) call Binarize(pImg) call Thinning(pImg) call ExtractFeatures(pImg. 6.14. 6. Các phép toán của phương pháp này đều thực hiện bằng số nguyên nên rất phù hợp cho việc cài đặt lên hệ thống nhúng. hình b) là kết quả của ảnh vân tay đã được tăng cường ảnh.2.

16 thể hiện thuật toán nhị phân hóa ảnh vân tay. Để giải quyết vấn đề này ta đã có thêm thuật toán lọc đặc trưng. Postprocessing(SFSImage pImg) begin word i. Khung thuật toán rút trích đặc trưng.16.j] = 0 then v = j * g_nSegmentBlock for u = x to m – 1 memset(pImg.m_pPixel[u. các đứt gãy nhỏ và các cầu giữa các vân trên ảnh nhị phân hóa. u. Thuật toán đánh dấu các vùng ảnh nào có thể rút trích đặc trưng dựa vào xử lý phân đoạn ảnh trước đó. Khung thuật toán cải tiến nhị phân hóa ảnh. vì có sự xuất hiện các lỗ. Trong đa số phần lớn trường hợp phần cải tiến này cho kết quả tốt hơn. Thuật toán dùng ngưỡng cục bộ để nhị phân hóa ảnh.m_nWidth – x x = 0 for i = 0 to g_nSegmentHeight – 1 m = x + g_nSegmentBlock for j = 0 to g_nSegmentWidth – 1 if g_nInternalSegment[i.Trang 106 Hình 6. Hình 6.m_nHeight – g_nBinaryMask for m = 0 to nMaxY – 1 step g_nBinaryMask u = m + g_nBinaryMask . v j = g_nSegmentHeight * g_nSegmentBlock x = g_nSegmentWidth * g_nSegmentBlock m = pImg. Trong trường hợp ảnh vân tay có chất lượng thấp. m. kỹ thuật ngưỡng cục bộ không phải lúc nào cũng cho ra một kết quả tốt. j. Hình 6.15 thể hiện thuật giải tiền xử lý trước khi rút trích đặc trưng. x. bằng cách điều chỉnh giá trị của nó theo cường độ cục bộ trung bình.v].15. 255. g_nSegmentBlock) end for end if end for x = x + g_nSegmentBlock end for end Hình 6. Đây là một cải tiến so với việc dùng ngưỡng toàn cục để phân hóa.m_nWidth – g_nBinaryMask nMaxY = pImg. Binarize(SFSImage pImg) begin nMaxX = pImg.

y] > nLocalMean then pImg.y] = 0 else pT.m_nHeight – 2 for y = 1 to pImg. 255.y + n] = 0 then nCount = nCount + 1 end if end for end for if nCount > 4 then pT.m_pPixel[x.m_pPixel[x.2 pImg.m_pPixel[x.m_nWidth * pImg.y] = 255 end if end for end for .y] = 255 else pImg.m_nHeight) memset(pT. pImg.y] <> 0 then nLocalMean = nLocalMean + pImg.Trang 107 for n = 0 to nMaxX – 1 step g_nBinaryMask v = n + g_nBinaryMask nLocalMean = nCount = 0 for x = m to u – 1 for y = n to v – 1 k = pImg.y] = min(k.y] <> 255 and pImg.m_pPixel[x.y] = 0 end if end for end for end if end for end for if g_nBinaryMask < 7 then Image_Create(pT.m_pPixel[x.y] nCount = nCount + 1 end if end for end for if nCount <> 0 then nLocalMean = nLocalMean / nCount for x = m to u – 1 for y = n to v – 1 if pImg.m_pPixel[x.m_nWidth.y] * 1.m_pPixel[x. pImg.m_pPixel[x. pImg.m_pPixel[x + m.m_nHeight) for x = 1 to pImg.m_pBuf.m_nWidth – 2 nCount = 0 for m = –1 to 1 for n = –1 to 1 if pImg.m_pPixel[x.m_pPixel[x. 255) if pImg.

17. pT) end if end Hình 6.m_nWidth h = pImg.m_pBuf[temp1] <> 0 then count = count end if pImg. Hình 6.m_pBuf[x + 1] <> 0) end for //Quét ảnh để tìm điểm ảnh (pixel) có thể loại bỏ for y = 0 to h – 2 q = qb[0] temp = (y + 1) * w p = ((q << 3) & 0110) | (pImg.17 thể hiện thuật toán làm mỏng vân.m_pBuf[i] = 0 then pImg.m_pBuf[temp + (x + 1)] <> 0) qb[x] = p if ((p & m) = 0) and delet[p] then temp1 = y * w + x if pImg. Thinning(SFSImage pImg) begin pc = 0 w = pImg.m_pBuf[temp1] = 0 end if end for //Xử lý các điểm ảnh ở cạnh bên phải p = (p << 1) & 0666 if (p & m) = 0 and delet[p] then . Khung thuật toán làm mỏng vân.m_nHeight for i = 0 to w * h – 1 if pImg.m_pBuf[i] = 0 end if end for while count <> 0 pc = pc + 1 count = 0 for i = 0 to 3 m = masks[i] p = pImg.m_pBuf[0] <> 0 for x = 0 to w – 2 qb[x] = p = ((p << 1) & 0006) | (pImg.m_pBuf[temp] <> 0) for x = 0 to w – 2 q = qb[x] p = ((p << 1) & 0666) | ((q << 3) & 0110) | (pImg.m_pBuf[i] = 1 else pImg.Trang 108 Image_Copy(pImg.

Khung thuật toán rút trích các đặc trưng và lọc các đặc trưng sai. SFSFeature pFea) begin word nRow. ExtractFeatures(SFSImage pImg. thuật toán đếm láng giềng xung quanh với ma trận 3x3 để xác định và phân loại đặc trưng. Trong phần lọc các đặc trưng sai. nCol.nCol/g_nSegmentBlock] = 1 then value = 0 for i = 0 to 7 value = value + (P[i] = pImg.18. thuật toán dùng phương pháp lọc dựa vào cấu trúc vân.m_pBuf[h – 1 * w + x] = 0 end if end for end for end while end Hình 6.m_nWidth.m_pPixel[nRow + arrRow[i].nCol] = 1 and pSeg[nRow/g_nSegmentBlock.m_pBuf[y * w + w – 1] = 0 end if end for //Xử lý dòng quét dưới for x = 0 to w – 1 q = qb[x] p = ((p << 1) & 0666) | ((q << 3) & 0110) if (p & m) = 0 and delet[p] then count = count + 1 pImg.m_nHeight) //Rút trích các đặc trưng for nRow = g_BORDER to max_h – g_BORDER – 1 for nCol = g_BORDER to max_w – g_BORDER – 1 if pImg. value SFSImage minmap Image_Create(minmap.18 thể hiện thuật toán rút trích các đặc trưng và lọc các đặc trưng sai.Trang 109 count = count + 1 pImg.nCol + arrCol[i]]) end for if value = 1 then minmap. j. pImg.m_pPixel[nRow. Trong phần rút trích các đặc tính của đặc trưng.m_pPixel[nRow. pImg. Hình 6.nCol] = 1 //Đặc trưng kết thúc (ending) p[nRow * w + nCol] = 1 else if value = 3 and not((P[0] & P[1]) | (P[1] & P[2]) | (P[2] & P[3]) | (P[3] & P[4]) | (P[4] & P[5]) | (P[5] & P[6]) | (P[6] & P[7]) | (P[7] & P[0])) then . i.

3.4. Việc xác định 3 láng giềng cho điểm trung tâm được xác định như sau (hình 6.m_pPixel[nRow. Trong đó cấu trúc toàn bộ của Jiang và Yau đưa ra có dạng là một đặc trưng trung tâm cùng với hai đặc trưng láng giềng gần nó nhất.nCol] = 3 //Đặc trưng điểm rẽ nhánh (bifurcation) p[nRow * w + nCol] = 3 end if end if end if end for end for //Loại bỏ các đặc trưng sai for nRow = g_BORDER to max_h – g_BORDER – 1 for nCol = g_BORDER to max_w – g_BORDER – 1 if minmap. Dựa vào hướng của điểm trung tâm chia thành 3 phần bằng nhau. Khuyết điểm của phương pháp này dễ chọn láng giềng gần nhất sai trong những hình vân tay có chất lượng kém hay phần Tăng cường ảnh không tốt (hình 6.19). . Chúng tôi đề nghị một phương pháp khác có tên gọi là 3 láng giềng để cải tiến phần xác định lại cấu trúc toàn cục.4. 2. mỗi phần có độ lệch góc nhau 1200 theo chiều kim đồng hồ.nCol] = 1 then if Extract_IsFalseEndings(nRow. Xác định 1 đặc trưng láng giềng gần đặc trung tâm nhất ở mỗi phần. nCol.20): 1.3 Đối sánh vân tay bằng phương pháp đối sánh đặc trưng cục bộ và toàn cục 6.m_pPixel[nRow. pImg. minmap) then p[nRow * w + nCol] = 0 //Loại bỏ đặc trưng sai end if end if end for end for end 6.1 Đặc vấn đề Jiang và Yau (2000) và Ratha (2000) [21] đề nghị phương pháp đối sánh đặc trưng cục bộ và toàn cục.Trang 110 minmap.

19. Tính véc tơ khoảng cách. khoảng cách vân. Xác định cấu trúc toàn cục sẽ sai khi có đặc trưng nhiễu ở gần đặc trưng trung tâm hơn so với 2 đặc trưng láng giềng gần nhất. . Hình 6.Trang 111 3. … giống như [21] đề nghị. Phương pháp này hạn chế được việc xác định điểm tham chiếu sai khi có xuất hiện đặc trưng nhiễu trong lúc xác định cấu trúc toàn cục cho một đặc trưng trung tâm. Trong trường hợp nếu xuất hiện một đặc trưng nhiễu thì việc xác định cấu trúc toàn cục chỉ giảm đi 1/3. độ lệch hướng.

SFSResult result) begin word i. nT double sl double radial SFSLocalFeature pw SFSLocalFeature plf SFSLocalFeature plfInp SFSLocalFeature plfTmp //Tính ma trận tương tự giữa các đặc trưng của 2 mẫu đặc trưng Input và Template được đưa từ hàm vào. Việc đối sánh cục bộ và toàn cục làm cho việc đối sánh sẽ trở nên đơn giản. j. . Khung thuật toán đối sánh trưng cục bộ và toàn cục. Trong phần xây dựng thuật toán đối sánh vân tay trên họ vi xử lý ARM. Áp dụng phương pháp 3 láng giềng để xác định cấu trúc toàn cục cho một đặc trưng.21.Trang 112 Hình 6. SFSFeature pfTmp. l word nI. Matching(SFSFeature pfInp. độ phức tạp tính toán giảm.3. và độ phân biệt cao với các ngón tay khác.20.2 Xây dựng thuật toán Hình 6.4. k. phù hợp với những hình vân tay bị biến dạng (méo mó hay bị co giản). phương pháp đối sánh của Jiang và Yau được cài đặt. 6.

j] end if end for end for //Tìm các đặc trưng tham chiếu (reference) làm điểm tựa. i.m_nRow.1]] and msl[i.j] >= sl then sl = msl[i][j] result.m_pMinutia[result. radial) Input. pw. pgfInp) Match_ToGlobal(pfTmp. pfInp.j]) if msl[i.aRefValue[k] = msl[i.rtmp.rinp]. result) is true then //Tính độ lệch giữa 2 góc của 2 đặc trưng tham chiếu AngleDiff2(pfTmp.rinp].aRefTmp[k .j] < msl[result.rinp.m_nNumMinutia – 1 if result.result. pfInp.rtmp].m_nNumMinutia – 1 for j = 0 to pfTmp.m_nNumMinutia Match_ToLocal(pfInp.pfIn p.aRefTmp[k] = j result.aRefInp[k] = i result.1] <> -1 and msl[i. if Match_PAndC(pfInp. for k = 1 to g_numRef – 1 sl = 0 for i = 0 to pfInp. result. result. j.m_pMinutia[result. pfTmp.m_aCore.j] end if end for end for end for //Xác định các đặc trưng tham chiếu tin cậy nhất dựa vào điểm core. plf) Match_Similarity(plf.m_aCore.m_nCore.Trang 113 sl = 0 for i = 0 to pfInp. radial) //Kiểm tra số lượng đặc trưng của 2 mẫu đặc trưng if nI > g_numMin && nT > g_numMin then //Tính các thông tin toàn cục theo đặc trưng tham Match_ToGlobal(pfInp.aRefTmp[k . pfTmp.m_nCore. plfTmp) Match_Sub(plfInp. msl. //Xoay 1 góc radial cho các đặc trưng của mẫu đặc trưng Affine_Rotate(pfInp. pgfTmp) //Tính điểm đối sánh (có giá trị từ 0 đến 100) giữa 2 vân tay chiếu . plfInp) for j = 0 to pfTmp.m_pMinutia[result.m_nDir.1] <> -1 and result. msl[i.m_pMinutia[result.aRefInp[k – 1.aRefInp[k .j] > sl then sl = msl[i. plfTmp.rinp]. pfTmp.m_nDir.m_nNumMinutia Match_ToLocal(pfTmp.m_nCol. pfInp.

word nMinTmp. t. double msl.m_nDir. pgfTmp[j]. Hình 6. Giá trị của điểm đối sánh nằm trong khoảng 0 đến 100 tương ứng với mức độ đối sánh giữa hai vân tay.m_nCross pgfTmp[j]. result.m_nCross) dradius = fabs(pgfInp[i].Trang 114 MatchScoring(pgfInp. word rectT.Q_PI) < Ta)) then ml[i. numMinTmp.j] then ml[i.22 thể hiện thuật toán tính điểm đối sánh vân tay.score) end if end if end Hình 6.j] = 0 break else ml[i.m_nRadialAngle. SFSGlobalFeature pgfTmp.22. MatchScoring(SFSGlobalFeature pgfInp. pgfTmp[j].j] for k = 0 to j – 1 if ml[i. numMinInp.j] = 0 end if .j] = 0. rectT.m_nDir. msl. double score) begin word dcross double dradius. word rectI. t) AngleDiff2(pgfInp[i].m_nRadialAngle.j] then ml[i.k] = 0 end if end for for k = 0 to i – 1 if ml[k.m_nRadius) AngleDiff2(pgfInp[i].m_nRadius pgfTmp[j]. SFSFeature pfInp. p //Xác định các cặp đặc trưng gần tương tự nhau.j] = 0 break else ml[k.5 * msl[i. pfTmp.5 + 0. for i = 0 to nMinInp – 1 if rectI[i] = 1 then for j = 0 to nMinTmp – 1 if rectN[j] = 1 then dcross = abs(pgfInp[i]. SFSFeature pfTmp. Khung thuật toán tính điểm đối sánh vân tay. p) if dradius < Td and dcross < Tc and ((t < Ta and < Ta) or (t < Ta and fabs(p .k] >= ml[i.j] >= ml[i. word nMinInp. pgfTmp. rectI. pfInp. Giá trị của điểm đối sánh được tính dựa vào độ giống nhau giữa các cặp đặc trưng giữa hai vân tay so với đặc trưng tham chiếu.

nT) end .j] >= 0.Trang 115 end for else ml[i.j] = 0 end if end if end for end if end for //Tính điểm đối sánh cho những cặp đặc trưng tương tự nhau for i = 0 to nMinInp – 1 for j = 0 to nMinTmp – 1 if ml[i.j] end if end for end for //Tính điểm đối sánh score = 100 * score / max(nI.5 then score = score + ml[i.