CHƢƠNG I : TỔNG QUAN VỀ HỆ THỐNG NHẬN DẠNG VÂN TAY TỰ ĐỘNG
3.1.3. Lập trình cài đặt thuật toán
Module xử lí vào ra và đọc ghi ảnh bitmap
Hàm tải ảnh bitmap từ bộ nhớ ngoài
Hàm này cho phép mở tệp ảnh bitmap với các cấu trúc 1, 4, 8 hay 24 bit. Đầu vào là tên file ảnh cần tải. Đầu ra hàm trả về một con trỏ kiểu byte lƣu trữ giá trị của các pixel ảnh cùng với hai biến height và width lƣu các giá trị kích thƣớc của ảnh.
///////////////////////////////////////////////////////////////// // load a .BMP file - 1,4,8,24 bit
// allocates and returns an RGB buffer containingthe image. // modifies width and height accordingly - NULL,0, 0 on error /////////////////////////////////////////////////////////////////
BYTE * CBmpFile::LoadBMP(CString fileName, UINT *width, UINT *height)
- 63 –
Hàm lưu ảnh dưới các cấu trúc khác nhau
Hàm này cho phép lƣu ảnh xuống bộ nhớ ngoài, đầu ra là một file ảnh bitmap với tên là fileName, hàm yêu cầu cung cấp đầu vào là một mảng con trỏ kiểu byte lƣu trữ dữ liệu ảnh, bên cạnh đó thông số đầu vào còn cần là kích cỡ của ảnh và bảng màu.
///////////////////////////////////////////////////////////////// // Save 1,4,8 bit BMP with a two dimension array // if you have a color-mapped image and a color map...
// the BMP saving code in SaveColorMappedBMP modified from // Programming for Graphics Files in C, by John Levine.
/////////////////////////////////////////////////////////////////
void CBmpFile::SaveBMP(CString fileName, // output path BYTE ** colormappedbuffer,
UINT width, UINT height,
int bitsperpixel, // 1, 4, 8
int colors,// number of color RGBQUAD*colormap)
Module xử lý ảnh
Module xử lý phân mảnh ảnh là module quan trọng nhất của chƣơng trình. Module này bao gồm:
Xử lý phân mảnh sơ bộ chỉ bản:
Thủ tục hạ bậc ảnh chỉ bản 10 ngón:
Sau khi nhận đƣợc mảng con trỏ kiểu byte lƣu trữ giá trị của các pixel ảnh chỉ bản 10 ngón, phần này sẽ tiến hành tính toán để đem lại kết quả là một ảnh đã hạ bậc từ ảnh chỉ bản ban đầu thành ảnh mới có mỗi chiều giảm xuống 8 lần, gồm thủ tục sau:
//////////////////////////////////////////////////////////////////////// //Thủ tục này đƣợc sử dụng để hạ bậc ảnh chỉ bản ////////////////////////////////////////////////////////////////////////
void CImgProcess:: DeResolution (UINT *nH,UINT *nW, UINT r)
Kết quả hạ bậc ảnh có kích thƣớc 4136 x 4133 xuống thành ảnh 512x512 để xử lý.
Làm trơn ảnh, chuyển đổi ảnh làm trơn về ảnh nhị phân:
Khi nhận đƣợc mảng con trỏ lƣu các giá trị của ảnh chỉ bản đã hạ bậc, sẽ tiến hành sử dụng các bộ lọc trung vị, lọc trung bình, lọc k trung bình để nâng cấp, làm
- 64 –
trơn ảnh, tiếp theo sử dụng phƣơng pháp cân bằng trắng đen để đƣa ảnh đa cấp xám về ảnh nhị phân, gồm các hàm và thủ tục sau: ///////////////////////////////////////////////////////////////// // Thủ tuc lọc trung vị ///////////////////////////////////////////////////////////////// void CImgProcess::MedianFilter() ///////////////////////////////////////////////////////////////// // Thủ tuc lọc trung bình ///////////////////////////////////////////////////////////////// void CImgProcess::AverageFilter() ///////////////////////////////////////////////////////////////// // Thủ tuc lọc k trung bình ///////////////////////////////////////////////////////////////// void CImgProcess::AverageFilterk() /////////////////////////////////////////////////////////////////
// Thủ tuc cân bằng trắng đen và biến đổi về ảnh nhị phân
/////////////////////////////////////////////////////////////////
void CImgProcess::BWBalance()
Kết quả cho ta một ảnh đen trắng nhƣ sau:
Tách các vùng trên ảnh
Sau khi thực hiện xong các bƣớc trên, chƣơng trình sẽ đƣa đƣợc ảnh đa cấp xám về ảnh nhị phân. Bƣớc tiếp theo là tiến hành tách các vùng liên thông trên ảnh nhị phân. Sử dụng các phƣơng pháp phân tích thành phần liên thông [1] và thuật toán véc tơ hóa đƣờng biên [3], ta xây dựng đƣợc các hàm và thủ tục sau:
- 65 – /////////////////////////////////////////////////////////////////
// Thủ tục dò biên trong cửa sổ
/////////////////////////////////////////////////////////////////
void CImgProcess::winbdfollow ()
/////////////////////////////////////////////////////////////////
// Hàm nhận biết điểm đó có phải là điểm biên của ảnh không /////////////////////////////////////////////////////////////////
UINT CImgProcess:: boundpoint(UINT X , UINT Y , UINT xb, UINT yb )
///////////////////////////////////////////////////////////////// // Toán tử dò biên 8-liên thông
/////////////////////////////////////////////////////////////////
void CImgProcess::nextpair( UINT xbgr, UINT ybgr, UINT xregion, UINT yregion )
Sau khi véc tơ hóa xong đƣờng biên trên ảnh, để nhận biết đƣợc đâu là vùng của vân tay, đâu là vùng nhiễu ta phải sử dụng tham số chu vi / diện tích để thống kê và tính ngƣỡng để nhận biết vùng vân. Việc tính diện tích vùng 8-liên thông trên cơ sở xâu mã hƣớng (chain code) có thể dùng công thức trong [3].
Cắt và tách ảnh vùng vân
Công đoạn cuối cùng để phân mảnh chỉ bản này, dựa vào các véc tơ của đƣờng biên để cắt và tách các vùng vân thành phần header, phần mã vạch và từng ngón lăn, từng ngón ấn ra riêng rẽ.
///////////////////////////////////////////////////////////////// // Thủ tục cắt và tách trên ảnh gốc.
/////////////////////////////////////////////////////////////////
void CImgProcess::DetectI(BYTE ** OImgData, Vector** iVector, UINT mHight, UINT mWidth)
Nhƣ vậy, tuy ở giai đoạn trên đã giải quyết đƣợc công đoạn phân mảnh từng ngón riêng rẽ nhƣng kết quả trên vẫn đang ở dạng kết quả phân mảnh thô trên ảnh đã hạ bậc và để đƣợc kết quả mịn hơn ta tiếp tục thực hiện phân mảnh mịn hơn trên các ảnh đã cắt và tách đƣợc ở trên.
Phân mảnh mịn – hoàn thiện ma trận hướng:
Phần này sẽ tiến hành tính toán để đem lại kết quả là ma trận hƣớng của ảnh vân tay (hƣớng của tất cả các pixel trên ảnh), gồm các hàm và thủ tục sau:
Thủ tục xác định hƣớng vân sơ bộ tại các pixel
Thủ tục này xác định hƣớng vân sơ bộ cho toàn bộ pixel của ảnh ban đầu . Mỗi pixel có thể có 4 phƣơng và 8 hƣớng. Để dễ dàng cho việc lập trình , hƣớng của các
- 66 –
pixel đƣợc đánh số từ 0 đến 7. Kết quả của thủ tục này là mỗi pixel đều đƣơ ̣c gán một giá trị từ 0 đến 7 biểu hiện cho 8 hƣớng.
/////////////////////////////////////////////////////////////////
// Thủ tục này tính hƣớng của tất cả các điểm ở trên ảnh và các hƣớng này sẽ đƣợc biểu diễn bằng các véc tơ /////////////////////////////////////////////////////////////////
void CImgProcess::ComputeDirectionImg()
Thủ tục tạo vectơ hƣớng trung bình của ma trận 8x8 pixel.
Thủ tục này đƣợc gọi để kết hợp hƣớng của 64 pixel trong một cửa sổ 8x8 thành một vectơ trung bình đại diện cho hƣớng của tất cả các pixel trong cửa sổ này. Kết quả của thủ tục này là mỗi cƣ̉a sổ gồm 8x8 pixel trên ảnh sẽ có giá trị từ 0 đến 7 biểu hiện cho 8 hƣớng.
/////////////////////////////////////////////////////////////////
// Thủ tục này tạo ma trận để tổng hợp các véc tơ trong mặt nạ cửa sổ /////////////////////////////////////////////////////////////////
void CImgProcess::CreateAverageVectorMatrix()
Thủ tục làm trơn ảnh theo hƣớng
Sau khi đã đƣợc một ma trận các vectơ hƣớng trung bình, thủ tục SmoothVMatrix đƣợc gọi để làm trơn hƣớng của ma trận vectơ này . Thủ tục này có thể đƣợc gọi nhiều lần đến khi thỏa mãn điều kiện trong hàm tìm điểm kỳ dị .
////////////////////////////////////////////////////////////////////// //Thủ tục này để làm trơn hƣớng của matrận iVector
void CImgProcess::SmoothVMatrix(AverageVector** iVector,AverageVector** oVector, UINT mHight, UINT mWidth)
- 67 –
Phân đoạn ảnh
Sau khi thu đƣơ ̣c ma trận các vector hƣớng trung bình đã đƣợc làm trơn , phần này thực hiện việc phân mảnh ảnh bằng cách chọn ra vùng nền của ảnh dựa vào các vùng