368 lines
18 KiB
Plaintext
368 lines
18 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Testing CoarseNet\n",
|
|
"Code for FineNet in paper \"Robust Minutiae Extractor: Integrating Deep Networks and Fingerprint Domain Knowledge\" at ICB 2018: https://arxiv.org/pdf/1712.09401.pdf\n",
|
|
"\n",
|
|
"If you use whole or partial function in this code, please cite paper:\n",
|
|
"\n",
|
|
" @inproceedings{Nguyen_MinutiaeNet,\n",
|
|
"\tauthor = {Dinh-Luan Nguyen and Kai Cao and Anil K. Jain},\n",
|
|
"\ttitle = {Robust Minutiae Extractor: Integrating Deep Networks and Fingerprint Domain Knowledge},\n",
|
|
"\tbooktitle = {The 11th International Conference on Biometrics, 2018},\n",
|
|
"\tyear = {2018},\n",
|
|
"\t}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"To run this script, you need to prepare dataset as follows:\n",
|
|
"`path/to/dataset/`:\n",
|
|
" - img_files/*.bmp\n",
|
|
"\n",
|
|
"If using groundtruth mask instead of mask generated by CoarseNet:\n",
|
|
" - seg_files/*.bmp\n",
|
|
" \n",
|
|
"## CoarseNet can run with any image size\n",
|
|
"See [CoarseNet_run.py](https://github.com/luannd/MinutiaeNet/blob/master/CoarseNet/CoarseNet_run.py) if running from command line.\n",
|
|
"\n",
|
|
"CoarseNet can be improved by:\n",
|
|
"- Train on new dataset instead of FVC\n",
|
|
"- Correct the orientation\n",
|
|
"- Tune threshold for different dataset\n",
|
|
"\n",
|
|
"## CoarseNet can provides:\n",
|
|
"- Orientation field estimation\n",
|
|
"- Mask for fingerprint area\n",
|
|
"- Minutiae location and orientation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Using TensorFlow backend.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from __future__ import absolute_import\n",
|
|
"from __future__ import division\n",
|
|
"\n",
|
|
"import sys, os\n",
|
|
"sys.path.append(os.path.realpath('./CoarseNet'))\n",
|
|
"\n",
|
|
"os.environ[\"CUDA_VISIBLE_DEVICES\"] = '1'\n",
|
|
"os.environ['KERAS_BACKEND'] = 'tensorflow'\n",
|
|
"\n",
|
|
"\n",
|
|
"from keras import backend as K\n",
|
|
"\n",
|
|
"from MinutiaeNet_utils import *\n",
|
|
"from CoarseNet_utils import *\n",
|
|
"from CoarseNet_model import *\n",
|
|
"import argparse\n",
|
|
"\n",
|
|
"\n",
|
|
"config = K.tf.ConfigProto(gpu_options=K.tf.GPUOptions(allow_growth=True))\n",
|
|
"sess = K.tf.Session(config=config)\n",
|
|
"K.set_session(sess)\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"inference_set = './data/input/'\n",
|
|
"output_dir = './data/output/'\n",
|
|
"\n",
|
|
"CoarseNet_path = './Models/CoarseNet.h5'\n",
|
|
"FineNet_path = './Models/FineNet.h5'\n",
|
|
"\n",
|
|
"# If use FineNet to refine, set into True\n",
|
|
"isHavingFineNet = False"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This can test with different folders.\n",
|
|
"\n",
|
|
"Threshold for each image is automatically chosen"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Loading model\n",
|
|
"Model loaded\n",
|
|
"Processing image: test2\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/usr/local/lib/python2.7/dist-packages/ipykernel_launcher.py:26: DeprecationWarning: `imread` is deprecated!\n",
|
|
"`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.\n",
|
|
"Use ``imageio.imread`` instead.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Running neural net\n",
|
|
"Adaptive threshold\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/usr/local/lib/python2.7/dist-packages/ipykernel_launcher.py:140: DeprecationWarning: `imsave` is deprecated!\n",
|
|
"`imsave` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.\n",
|
|
"Use ``imageio.imwrite`` instead.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Processing image: test\n",
|
|
"Running neural net\n",
|
|
"Adaptive threshold\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Read image and GT\n",
|
|
"img_name, folder_name, img_size = get_maximum_img_size_and_names(inference_set)\n",
|
|
"\n",
|
|
"mkdir(output_dir + '/')\n",
|
|
"mkdir(output_dir + '/mnt_results/')\n",
|
|
"mkdir(output_dir + '/OF_results/')\n",
|
|
"mkdir(output_dir + '/seg_results/')\n",
|
|
"\n",
|
|
"print(\"Loading model\")\n",
|
|
"main_net_model = CoarseNetmodel((None, None, 1), CoarseNet_path, mode='deploy')\n",
|
|
"print(\"Model loaded\")\n",
|
|
"\n",
|
|
"# ====== Load FineNet to verify\n",
|
|
"if isHavingFineNet == True:\n",
|
|
" model_FineNet = FineNetmodel(num_classes=2,\n",
|
|
" pretrained_path=FineNet_path,\n",
|
|
" input_shape=(224,224,3))\n",
|
|
"\n",
|
|
" model_FineNet.compile(loss='categorical_crossentropy',\n",
|
|
" optimizer=Adam(lr=0),\n",
|
|
" metrics=['accuracy'])\n",
|
|
"\n",
|
|
"for i in xrange(0, len(img_name)):\n",
|
|
" print(\"Processing image: %s\" % img_name[i])\n",
|
|
"\n",
|
|
" image = misc.imread(inference_set + img_name[i] + '.jpg', mode='L')\n",
|
|
"\n",
|
|
" image = cv2.resize(image, dsize=(480, 270), interpolation=cv2.INTER_CUBIC)\n",
|
|
"\n",
|
|
" img_size = image.shape\n",
|
|
" img_size = np.array(img_size, dtype=np.int32) // 8 * 8\n",
|
|
" image = image[:img_size[0], :img_size[1]]\n",
|
|
"\n",
|
|
" original_image = image.copy()\n",
|
|
"\n",
|
|
" # Generate OF\n",
|
|
" texture_img = FastEnhanceTexture(image, sigma=2.5, show=False)\n",
|
|
" dir_map, fre_map = get_maps_STFT(texture_img, patch_size=64, block_size=16, preprocess=True)\n",
|
|
"\n",
|
|
" show_orientation_field(original_image, dir_map + np.pi, fname=\"%s/OF_results/%s_OFnm.jpg\" % (output_dir, img_name[i]))\n",
|
|
" \n",
|
|
" image = np.reshape(image, [1, image.shape[0], image.shape[1], 1])\n",
|
|
"\n",
|
|
" print(\"Running neural net\")\n",
|
|
" enh_img, enh_img_imag, enhance_img, ori_out_1, ori_out_2, seg_out, mnt_o_out, mnt_w_out, mnt_h_out, mnt_s_out \\\n",
|
|
" = main_net_model.predict(image)\n",
|
|
"\n",
|
|
" # Use for output mask\n",
|
|
" round_seg = np.round(np.squeeze(seg_out))\n",
|
|
" seg_out = 1 - round_seg\n",
|
|
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))\n",
|
|
" seg_out = cv2.morphologyEx(seg_out, cv2.MORPH_CLOSE, kernel)\n",
|
|
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))\n",
|
|
" seg_out = cv2.morphologyEx(seg_out, cv2.MORPH_OPEN, kernel)\n",
|
|
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))\n",
|
|
" seg_out = cv2.dilate(seg_out, kernel)\n",
|
|
"\n",
|
|
" #========== Adaptive threshold ==================\n",
|
|
" final_minutiae_score_threashold = 0.45\n",
|
|
" early_minutiae_thres = final_minutiae_score_threashold + 0.05\n",
|
|
"\n",
|
|
"\n",
|
|
" # In cases of small amount of minutiae given, try adaptive threshold\n",
|
|
" while final_minutiae_score_threashold >= 0:\n",
|
|
" print(\"Adaptive threshold\")\n",
|
|
" \n",
|
|
" mnt = label2mnt(np.squeeze(mnt_s_out) * np.round(np.squeeze(seg_out)), mnt_w_out, mnt_h_out, mnt_o_out,\n",
|
|
" thresh=early_minutiae_thres)\n",
|
|
"\n",
|
|
" mnt_nms_1 = py_cpu_nms(mnt, 0.5)\n",
|
|
" mnt_nms_2 = nms(mnt)\n",
|
|
" # Make sure good result is given\n",
|
|
" if mnt_nms_1.shape[0] > 4 and mnt_nms_2.shape[0] > 4:\n",
|
|
" break\n",
|
|
" else:\n",
|
|
" final_minutiae_score_threashold = final_minutiae_score_threashold - 0.05\n",
|
|
" early_minutiae_thres = early_minutiae_thres - 0.05\n",
|
|
"\n",
|
|
"\n",
|
|
" mnt_nms = fuse_nms(mnt_nms_1, mnt_nms_2)\n",
|
|
"\n",
|
|
" mnt_nms = mnt_nms[mnt_nms[:, 3] > early_minutiae_thres, :]\n",
|
|
" mnt_refined = []\n",
|
|
"\n",
|
|
" if isHavingFineNet == True:\n",
|
|
" # ======= Verify using FineNet ============\n",
|
|
" patch_minu_radio = 22\n",
|
|
" if FineNet_path != None:\n",
|
|
" for idx_minu in range(mnt_nms.shape[0]):\n",
|
|
" try:\n",
|
|
" # Extract patch from image\n",
|
|
" x_begin = int(mnt_nms[idx_minu, 1]) - patch_minu_radio\n",
|
|
" y_begin = int(mnt_nms[idx_minu, 0]) - patch_minu_radio\n",
|
|
" patch_minu = original_image[x_begin:x_begin + 2 * patch_minu_radio,\n",
|
|
" y_begin:y_begin + 2 * patch_minu_radio]\n",
|
|
"\n",
|
|
" patch_minu = cv2.resize(patch_minu, dsize=(224, 224), interpolation=cv2.INTER_NEAREST)\n",
|
|
"\n",
|
|
" ret = np.empty((patch_minu.shape[0], patch_minu.shape[1], 3), dtype=np.uint8)\n",
|
|
" ret[:, :, 0] = patch_minu\n",
|
|
" ret[:, :, 1] = patch_minu\n",
|
|
" ret[:, :, 2] = patch_minu\n",
|
|
" patch_minu = ret\n",
|
|
" patch_minu = np.expand_dims(patch_minu, axis=0)\n",
|
|
"\n",
|
|
" # # Can use class as hard decision\n",
|
|
" # # 0: minu 1: non-minu\n",
|
|
" # [class_Minutiae] = np.argmax(model_FineNet.predict(patch_minu), axis=1)\n",
|
|
" #\n",
|
|
" # if class_Minutiae == 0:\n",
|
|
" # mnt_refined.append(mnt_nms[idx_minu,:])\n",
|
|
"\n",
|
|
" # Use soft decision: merge FineNet score with CoarseNet score\n",
|
|
" [isMinutiaeProb] = model_FineNet.predict(patch_minu)\n",
|
|
" isMinutiaeProb = isMinutiaeProb[0]\n",
|
|
" # print isMinutiaeProb\n",
|
|
" tmp_mnt = mnt_nms[idx_minu, :].copy()\n",
|
|
" tmp_mnt[3] = (4*tmp_mnt[3] + isMinutiaeProb) / 5\n",
|
|
" mnt_refined.append(tmp_mnt)\n",
|
|
"\n",
|
|
" except:\n",
|
|
" mnt_refined.append(mnt_nms[idx_minu, :])\n",
|
|
" else:\n",
|
|
" mnt_refined = mnt_nms\n",
|
|
"\n",
|
|
" mnt_nms_backup = mnt_nms.copy()\n",
|
|
" mnt_nms = np.array(mnt_refined)\n",
|
|
"\n",
|
|
" if mnt_nms.shape[0] > 0:\n",
|
|
" mnt_nms = mnt_nms[mnt_nms[:, 3] > final_minutiae_score_threashold, :]\n",
|
|
" \n",
|
|
" final_mask = ndimage.zoom(np.round(np.squeeze(seg_out)), [8, 8], order=0)\n",
|
|
" # Show the orientation\n",
|
|
" show_orientation_field(original_image, dir_map + np.pi, mask=final_mask, fname=\"%s/OF_results/%s_OFnm.jpg\" % (output_dir, img_name[i]))\n",
|
|
"\n",
|
|
"\n",
|
|
" fuse_minu_orientation(dir_map, mnt_nms, mode=3)\n",
|
|
"\n",
|
|
" mnt_writer(mnt_nms, img_name[i], img_size, \"%s/mnt_results/%s.mnt\"%(output_dir, img_name[i]))\n",
|
|
" draw_minutiae(original_image, mnt_nms, \"%s/%s_minu.jpg\"%(output_dir, img_name[i]),saveimage=True)\n",
|
|
" misc.imsave(\"%s/seg_results/%s_seg.jpg\" % (output_dir, img_name[i]), final_mask)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<matplotlib.image.AxesImage at 0x7f9beb7ce110>"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plt.imshow(original_image)\n",
|
|
"plt.imshow(final_mask)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 2",
|
|
"language": "python",
|
|
"name": "python2"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 2
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython2",
|
|
"version": "2.7.18"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|