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.
28 trang |
Chia sẻ: vietpd | Lượt xem: 1316 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Xây dựng thư viện nhận dạng vân tay trên họ ARM, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
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.
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. 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; 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.
6.3 Xây dựng kiến trúc hệ thống nhận dạng vân tay trên họ ARM
6.3.1 Xây dựng thư viện vân tay
Hình 6.1 Kiến trúc chung của hệ thống nhận dạng vân tay.
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. 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; phần xử lý này được cài
đặt trong phần Image Modules).
Trang 91
o Tăng cường ảnh; phần xử lý này được cài đặt thành hàm
FP_PreProcessing.
o Rút trích đặc trưng; phần xử lý này được cài đặt thành hàm
FP_Extract.
o Đối sánh vân tay; phần xử lý này được cài đặt thành hàm
FP_Matching.
2. 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ị.
3. 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. Việc này cần thiết cho
việc nhận dạng dấu vân tay.
6.3.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, giúp cho việc tiết kiệm thời gian
khi đối sánh vân tay.
Hình 6.2 Các thành phần của mẫu đặc trưng đã được rút trích.
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.
Trang 92
• m_pCore: mãng chứa các điểm core.
• m_pDist: mãng chứa các khoảng cách giữa các đặ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ó.
• m_pCross: mãng chứa giá trị đếm số vân giữa 2 đặc trưng.
• m_nMinutiae: số đặc trưng đã được rút trích.
• m_pMinutiae: mãng chứa các đặc trưng đã được rút trích; bao gồm tọa độ
(x,y) và hướng của đặc trưng.
6.4 Xây dựng thư viện nhận dạng vân tay
6.4.1 Tăng cường ảnh bằng phương pháp lọc Gabor
6.4.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. 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.
6.4.1.2 Xây dựng thuật toán
Hình 6.3. Khung thuật toán Tăng cường ảnh bằng phương pháp lọc Gabor.
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.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].
Để 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:
Trang 93
• Đổi các tính toán số thực sang số nguyên; tính trước các giá trị số thực lưu vào
trong một mãng, như: tính trước cos, sin, artan2. Đặ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; vì vi xử lý này
không hỗ trợ tính toán số thực.
• 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].
• Thay thế những hàm được gọi nhiều trong thư viện bằng Macro [38].
• Sử dụng đếm ngược trong vòng lặp để tăng tốc độ [38].
• 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.
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, như: mặt nạ Gabor số nguyên (g_nGaborInt), và các
phép tính trước sin, cos. 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.
Hình 6.4. Khung thuật toán khởi tạo phục vụ cho tăng cường ảnh.
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, 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
for y = –(g_nWindowHeight / 2) to (g_nWindowHeight
+ 1) / 2
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.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 / (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.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].
Hình 6.5 cho thấy kết quả của việc phân đoạn ảnh.
Trang 95
Hình 6.5. 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; hình a) ảnh gốc; hình b) thể hiện độ thay đổi mức xám; hình c)
hình vân tay sau khi đã phân đoạn.
Hình 6.6. Khung thuật toán phân đoạn ảnh phục vụ cho tăng cường ảnh.
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.m_pPixel[u,v]
nX = pImg.m_pPixel[u + 1,v – 1] –
pImg.m_pPixel[u – 1,v – 1] + ((pImg.m_pPixel[u + 1,v] –
pImg.m_pPixel[u – 1,v]) * 2) + pImg.m_pPixel[u + 1,v + 1] –
pImg.m_pPixel[u – 1,v + 1]
nY = pImg.m_pPixel[u – 1,v + 1] –
pImg.m_pPixel[u – 1,v – 1] + ((pImg.m_pPixel[u,v + 1] –
pImg.m_pPixel[u,v – 1]) * 2) + pImg.m_pPixel[u + 1,v + 1] –
pImg.m_pPixel[u + 1,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]) * (nMean – pImg.m_pPixel[u,v])
end for
Trang 96
end for
fVar = sqrt(nVar) / (g_nSegmentBlock *
g_nSegmentBlock)
fCoh = nXX – nYY
fCoh = sqrt(fCoh * fCoh + 4 * nXY * nXY) / (nXX +
nYY)
fW = fCoh * g_fSegmentWeight1 + nMean *
g_fSegmentWeight2 + fVar * g_fSegmentWeight3 + g_fSegmentWeight4
if fW >= 0 then
nSegment[i,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.50 then
g_nInternalSegment[i,j] = 1
if nMean > 6 and fVar > 0.80 then //hằng số
6 và 0.8 lần lượt là ngưỡng của mean và variant
g_nSegment[i,j] = 1
end if
end if
end for
end for
end
Hình 6.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.
Hình 6.7. Khung thuật toán chuẩn hóa ảnh phục vụ cho tăng cường ảnh.
Normalize(SFSImage pImg)
begin
Trang 97
word i, j
double pPixel [256,256]
double fMean, fVar, fMin, fMax
fMean = 0
fVar = 0
for i = 0 to pImg.m_nHeight – 1
for j = 0 to pImg.m_nWidth – 1
pPixel[i,j] = pImg.m_pPixel[i,j] / 255
fMean = fMean + pPixel[i,j]
end for
end for
fMean = fMean / nSize
for i = 0 to pImg.m_nHeight – 1
for j = 0 to pImg.m_nWidth – 1
fVar = fVar + (pPixel[i,j] – fMean) * (pPixel[i,j]
– fMean)
end for
end for
fVar = sqrt(fVar/nSize)
fVar = sqrt(1 / fVar)
fMin = 0
fMax = 0
for i = 0 to pImg.m_nHeight – 1
for j = 0 to pImg.m_nWidth – 1
if pPixel[i,j] > fMean then
pPixel[i,j] = (pPixel[i,j] – fMean) * fVar
else
pPixel[i,j] = – (pPixel[i,j] + fMean) * fVar
end if
if pPixel[i,j] < fMin then
fMin = pPixel[i,j]
end if
if pPixel[i,j] > fMax then
fMax = pPixel[i,j]
end if
end for
end for
for i = 0 to pImg.m_nHeight – 1
for j = 0 to pImg.m_nWidth – 1
pImg.m_pPixel[i,j] = 255 * (pPixel[i,j] – fMin) /
(fMax – fMin)
end for
end for
end
Hình 6.9 thể hiện thuật toán ước lượng hướng vân. Trong bài báo gốc [28], nhóm tác
giả làm mượt hướng bằng phương pháp lọc trung bình. Phương pháp làm mượt này
thường cho kết quả hướng sai ở gần điểm core. Chúng tôi đề xuất phương pháp làm
Trang 98
mượt bằng lọc Gaussian. Kết quả của phương pháp này (hình 6.8) đã khắc phục được
hướng sai ở gần điểm core.
Hình 6.8. Hình a) làm mượt hướng bằng phương pháp lọc trung bình, hình b) dùng
phương pháp lọc Gaussian.
Hình 6.9. Khung thuật toán xác định hướng vân phục vụ cho tăng cường ảnh.
EstimateOrient(SFSImage pImg)
begin
word i, j, x ,y
word nOrientHeight, nOrientWidth
word nSumX, nSumY
word nOrientBlock
double fOrient, pDx, pDy
nOrientBlock = 7
nOrientHeight = (pImg.m_nHeight – 2) / nOrientBlock
nOrientWidth = (pImg.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
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.m_pPixel[u + g,v + h] * nOrientMask[g + 3,h + 3]
nX = nX +
pImg.m_pPixel[u + g,v + h] * nOrientMask[h + 3,g + 3]
end for
end for
nSumX = nSumX + nX *
nY
nSumY = nSumX + (nX –
nY) * (nX + nY)
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,j] * nGaussianMask_5[2,2]
nSumY = –pDy[i,j] * nGaussianMask_5[2,2]
if fOrient[i,j] = 1 then
for m = –nOrientGaussian to nOrientGaussian
u = i + m
if u >= 0 and u < nOrientHeight then
Trang 100
for n = –nOrientGaussian to
nOrientGaussian
v = j + n
if v >= 0 and v <
nOrientWidth then
if pDx[u,v] 0 and
pDy[u,v] 0 then
nSumX = nSumX +
pDx[u,v] * nGaussianMask[m + nOrientGaussian,n + nOrientGaussian]
nSumY = nSumY +
pDy[u,v] * nGaussianMask[m + nOrientGaussian,n + nOrientGaussian]
end if
end if
end for
end if
end for
if nSumX 0 and nSumY 0 then
fOrient[i,j] = 0.5 * ATAN2(nSumX,
nSumY)
end if
else
fOrient[i,j] = 255
end if
end for
end for
end
Hình 6.11 thể hiện thuật toán ước lượng tần số theo bài báo [32]. Trong phần thuật
toán này, 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ố. 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.10).
Trang 101
Hình 6.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ả.
Hình 6.11. Khung thuật toán ước lượng tần số phục vụ cho tăng cường ảnh.
EstimateFrequency(SFSImage pImg)
begin
double fSin, fCos, fOrient, fMean, fVar
word i, j, x, y, m, n, u, v, k, l
word nW, nH, nValidSigCount, nPeakCount, 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,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.m_nHeight
and v >= 0 and v < pImg.m_nWidth then
pSig[m + nW] = pSig[m + nW]
+ pImg.m_pPixel[u,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
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 - 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.165 then
fFrequency[i,j] = 0
else
fFrequency[i,j] = nPeakCount /
nSumDis
if fFrequency[i,j] < 0.04 or
fFrequency[i,j] > 0.5 then
fFrequency[i,j] = 0
end if
end if
end if
end if
y = y + nFrequencyBlock
end for
x = x + nFrequencyBlock
end for
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,y + nFrequencyGaussian]
fOrient = fOrient +
fFrequency[u,v] * nGaussianMask[x + nFrequencyGaussian,y +
nFrequencyGaussian]
end if
end for
end if
end for
if k 0 then
fFrequency[i,j] = fOrient / k
end if
end for
end for
end
Hình 6.12 thể hiện thuật toán lọc Gabor [32]. Kết quả của tăng cường ảnh (hình
6.13).
Hình 6.12. Khung thuật toán lọc Gabor phục vụ cho tăng cường ảnh.
GaborFilter(SFSImage pImg)
begin
SFSImage imgResult
nMaxX = min(g_nOrientBlock * g_nOrientWidth,
g_nFrequencyBlock * g_nFrequencyWidth)
nMaxY = min(g_nOrientBlock * g_nOrientHeight,
g_nFrequencyBlock * g_nFrequencyHeight)
nMaskS = nMaskS – (g_nGaborMask / 2)
nMaskE = (g_nGaborMask + 1) / 2
nMaskSize = g_nGaborMask * g_nGaborMask
Image_Create(imgResult, pImg.m_nWidth, pImg.m_nHeight)
for i = 0 to nMaxY – 1
for j = 0 to nMaxX – 1
nOrient = g_nOrientInt[i / g_nOrientBlock,j /
g_nOrientBlock]
if nOrient 255 then
Trang 104
nFrequency = g_nFrequencyInt[i /
g_nFrequencyBlock,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_nHeight then
for y = nMaskS to nMaskE – 1
v = j + y
if v >= 0 and v <
pImage.m_nWidth then
nConvolution =
nCon