diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/model/__init__.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/model/__init__.py diff --git a/model/attention.py b/model/attention.py new file mode 100755 index 0000000..9f2a0f5 --- /dev/null +++ b/model/attention.py @@ -0,0 +1,55 @@ +import torch +from torch import nn +import torch.nn.functional as F + + +class ASPP(nn.Module): + def __init__(self, in_channel=512, depth=256): + super(ASPP, self).__init__() + # global average pooling : init nn.AdaptiveAvgPool2d ;also forward torch.mean(,,keep_dim=True) + self.mean = nn.AdaptiveAvgPool2d((1, 1)) # (1,1) means output size + self.conv = nn.Conv2d(in_channel, depth, 1, 1) + # k=1 s=1 no pad + self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1) + self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6) + self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12) + self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18) + + self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1) + + self.conv_3x3_output1 = nn.Conv2d(in_channels= depth * 5, out_channels= 256, kernel_size=3, stride=1, padding=1) + self.conv_3x3_output2 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1) + self.sigmoid = F.sigmoid + + def forward(self, x): + size = x.shape[2:] + + image_features = self.mean(x) + image_features = self.conv(image_features) + image_features = F.upsample(image_features, size=size, mode='bilinear') + + atrous_block1 = self.atrous_block1(x) + + atrous_block6 = self.atrous_block6(x) + + atrous_block12 = self.atrous_block12(x) + + atrous_block18 = self.atrous_block18(x) + + concat = torch.cat([image_features, atrous_block1, atrous_block6, + atrous_block12, atrous_block18], dim=1) + + # 256 3*3 conv + out_conv = self.conv_3x3_output1(concat) + # 512 3*3 conv + out_conv = self.conv_3x3_output2(out_conv) + # sigmoid , M + M = self.sigmoid(out_conv) + # element-wise dot product:M*input + out = M * x + # concat with input + net = torch.cat([x, out], dim=1) + + # net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6, + # atrous_block12, atrous_block18], dim=1)) + return net diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/model/__init__.py diff --git a/model/attention.py b/model/attention.py new file mode 100755 index 0000000..9f2a0f5 --- /dev/null +++ b/model/attention.py @@ -0,0 +1,55 @@ +import torch +from torch import nn +import torch.nn.functional as F + + +class ASPP(nn.Module): + def __init__(self, in_channel=512, depth=256): + super(ASPP, self).__init__() + # global average pooling : init nn.AdaptiveAvgPool2d ;also forward torch.mean(,,keep_dim=True) + self.mean = nn.AdaptiveAvgPool2d((1, 1)) # (1,1) means output size + self.conv = nn.Conv2d(in_channel, depth, 1, 1) + # k=1 s=1 no pad + self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1) + self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6) + self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12) + self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18) + + self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1) + + self.conv_3x3_output1 = nn.Conv2d(in_channels= depth * 5, out_channels= 256, kernel_size=3, stride=1, padding=1) + self.conv_3x3_output2 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1) + self.sigmoid = F.sigmoid + + def forward(self, x): + size = x.shape[2:] + + image_features = self.mean(x) + image_features = self.conv(image_features) + image_features = F.upsample(image_features, size=size, mode='bilinear') + + atrous_block1 = self.atrous_block1(x) + + atrous_block6 = self.atrous_block6(x) + + atrous_block12 = self.atrous_block12(x) + + atrous_block18 = self.atrous_block18(x) + + concat = torch.cat([image_features, atrous_block1, atrous_block6, + atrous_block12, atrous_block18], dim=1) + + # 256 3*3 conv + out_conv = self.conv_3x3_output1(concat) + # 512 3*3 conv + out_conv = self.conv_3x3_output2(out_conv) + # sigmoid , M + M = self.sigmoid(out_conv) + # element-wise dot product:M*input + out = M * x + # concat with input + net = torch.cat([x, out], dim=1) + + # net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6, + # atrous_block12, atrous_block18], dim=1)) + return net diff --git a/model/unet_parts.py b/model/unet_parts.py new file mode 100755 index 0000000..a620d82 --- /dev/null +++ b/model/unet_parts.py @@ -0,0 +1,78 @@ +""" Parts of the U-Net model """ + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class DoubleConv(nn.Module): + """(convolution => [BN] => ReLU) * 2""" + + def __init__(self, in_channels, out_channels, mid_channels=None): + super(DoubleConv,self).__init__() + if not mid_channels: + mid_channels = out_channels + self.double_conv = nn.Sequential( + nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(mid_channels), + nn.ReLU(inplace=True), + nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True) + ) + + def forward(self, x): + return self.double_conv(x) + + +class Down(nn.Module): + """Downscaling with maxpool then double conv""" + + def __init__(self, in_channels, out_channels): + super(Down,self).__init__() + self.maxpool_conv = nn.Sequential( + nn.MaxPool2d(2), + DoubleConv(in_channels, out_channels) + ) + + def forward(self, x): + return self.maxpool_conv(x) + + +class Up(nn.Module): + """Upscaling then double conv""" + + def __init__(self, in_channels, out_channels, bilinear=True): + super(Up,self).__init__() + + # if bilinear, use the normal convolutions to reduce the number of channels + if bilinear: + self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) + self.conv = DoubleConv(in_channels, out_channels, in_channels // 2) + else: + self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2) + self.conv = DoubleConv(in_channels, out_channels) + + def forward(self, x1, x2): + x1 = self.up(x1) + # input is CHW + diffY = x2.size()[2] - x1.size()[2] + diffX = x2.size()[3] - x1.size()[3] + + x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, + diffY // 2, diffY - diffY // 2]) + # if you have padding issues, see + # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a + # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd + x = torch.cat([x2, x1], dim=1) + return self.conv(x) + + +class OutConv(nn.Module): + def __init__(self, in_channels, out_channels): + super(OutConv, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1) + + def forward(self, x): + return self.conv(x) + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/model/__init__.py diff --git a/model/attention.py b/model/attention.py new file mode 100755 index 0000000..9f2a0f5 --- /dev/null +++ b/model/attention.py @@ -0,0 +1,55 @@ +import torch +from torch import nn +import torch.nn.functional as F + + +class ASPP(nn.Module): + def __init__(self, in_channel=512, depth=256): + super(ASPP, self).__init__() + # global average pooling : init nn.AdaptiveAvgPool2d ;also forward torch.mean(,,keep_dim=True) + self.mean = nn.AdaptiveAvgPool2d((1, 1)) # (1,1) means output size + self.conv = nn.Conv2d(in_channel, depth, 1, 1) + # k=1 s=1 no pad + self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1) + self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6) + self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12) + self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18) + + self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1) + + self.conv_3x3_output1 = nn.Conv2d(in_channels= depth * 5, out_channels= 256, kernel_size=3, stride=1, padding=1) + self.conv_3x3_output2 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1) + self.sigmoid = F.sigmoid + + def forward(self, x): + size = x.shape[2:] + + image_features = self.mean(x) + image_features = self.conv(image_features) + image_features = F.upsample(image_features, size=size, mode='bilinear') + + atrous_block1 = self.atrous_block1(x) + + atrous_block6 = self.atrous_block6(x) + + atrous_block12 = self.atrous_block12(x) + + atrous_block18 = self.atrous_block18(x) + + concat = torch.cat([image_features, atrous_block1, atrous_block6, + atrous_block12, atrous_block18], dim=1) + + # 256 3*3 conv + out_conv = self.conv_3x3_output1(concat) + # 512 3*3 conv + out_conv = self.conv_3x3_output2(out_conv) + # sigmoid , M + M = self.sigmoid(out_conv) + # element-wise dot product:M*input + out = M * x + # concat with input + net = torch.cat([x, out], dim=1) + + # net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6, + # atrous_block12, atrous_block18], dim=1)) + return net diff --git a/model/unet_parts.py b/model/unet_parts.py new file mode 100755 index 0000000..a620d82 --- /dev/null +++ b/model/unet_parts.py @@ -0,0 +1,78 @@ +""" Parts of the U-Net model """ + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class DoubleConv(nn.Module): + """(convolution => [BN] => ReLU) * 2""" + + def __init__(self, in_channels, out_channels, mid_channels=None): + super(DoubleConv,self).__init__() + if not mid_channels: + mid_channels = out_channels + self.double_conv = nn.Sequential( + nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(mid_channels), + nn.ReLU(inplace=True), + nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True) + ) + + def forward(self, x): + return self.double_conv(x) + + +class Down(nn.Module): + """Downscaling with maxpool then double conv""" + + def __init__(self, in_channels, out_channels): + super(Down,self).__init__() + self.maxpool_conv = nn.Sequential( + nn.MaxPool2d(2), + DoubleConv(in_channels, out_channels) + ) + + def forward(self, x): + return self.maxpool_conv(x) + + +class Up(nn.Module): + """Upscaling then double conv""" + + def __init__(self, in_channels, out_channels, bilinear=True): + super(Up,self).__init__() + + # if bilinear, use the normal convolutions to reduce the number of channels + if bilinear: + self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) + self.conv = DoubleConv(in_channels, out_channels, in_channels // 2) + else: + self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2) + self.conv = DoubleConv(in_channels, out_channels) + + def forward(self, x1, x2): + x1 = self.up(x1) + # input is CHW + diffY = x2.size()[2] - x1.size()[2] + diffX = x2.size()[3] - x1.size()[3] + + x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, + diffY // 2, diffY - diffY // 2]) + # if you have padding issues, see + # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a + # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd + x = torch.cat([x2, x1], dim=1) + return self.conv(x) + + +class OutConv(nn.Module): + def __init__(self, in_channels, out_channels): + super(OutConv, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1) + + def forward(self, x): + return self.conv(x) + diff --git a/model/unet_vgg16_multitask_attention.py b/model/unet_vgg16_multitask_attention.py new file mode 100755 index 0000000..ac7eb10 --- /dev/null +++ b/model/unet_vgg16_multitask_attention.py @@ -0,0 +1,163 @@ +import torch +from .unet_parts import * +from .attention import ASPP + + +class UnetWithVGG16Attention(torch.nn.Module): + + def __init__(self, encoder, n_classes=1, bilinear=True): + super(UnetWithVGG16Attention, self).__init__() + + self.features = encoder.features[:-1] # drop last maxpooling + self.n_classes = n_classes + self.bilinear = bilinear + self.downs = [] + + self.feature_len: int = len(self.features) + + self.attention = ASPP(in_channel=512,depth=256) + + self.up1 = Up(1536, 256, self.bilinear) + self.up2 = Up(512, 128, self.bilinear) + self.up3 = Up(256, 64, self.bilinear) + self.up4 = Up(128, 32, self.bilinear) + self.outc = OutConv(32, n_classes * 3) + self.outc1 = OutConv(32, n_classes) + self.outc2 = OutConv(32, n_classes) + self.outc3 = OutConv(32, n_classes) + + def forward(self, x): + # dict = {'5':0, '12':1, '22':2, '32':3} + # concat_index = [5, 12, 22, 32] # bn + concat_index = [3, 8, 15, 22] + downs = [] + + f_len = self.feature_len + o = x + for i, feature in enumerate(self.features): + o = feature(o) + if i in concat_index: + downs.append(o) + # print(len(self.downs)) + # print(str(i) + ' ' + str(dict[str(i)])) + # self.downs[dict[str(i)]] = o + + o = self.attention(o) + + x = self.up1(o, downs[-1]) + x = self.up2(x, downs[-2]) + x = self.up3(x, downs[-3]) + x = self.up4(x, downs[-4]) + + mask_iris_pupil = self.outc(x) + + spilt_mask_iris_pupil = torch.split(mask_iris_pupil, 1, dim=1) + pupil = spilt_mask_iris_pupil[0] + mask = spilt_mask_iris_pupil[1] + iris = spilt_mask_iris_pupil[2] + + # mask = self.outc1(x) + # iris = self.outc2(x) + # pupil = self.outc3(x) + + return mask, iris, pupil + + def get_encoder(self, features, batch_norm=True): + downs = [] + pools = [] + + conv1_1 = features[0] + conv1_1_bn = nn.BatchNorm2d(64) + conv1_1_relu = features[1] + conv1_2 = features[2] + conv1_2_bn = nn.BatchNorm2d(64) + conv1_2_relu = features[3] + + # downs.append([conv1_1, conv1_1_bn, conv1_1_relu, + # conv1_2, conv1_2_bn, conv1_2_relu]) + downs.append( + nn.Sequential( + conv1_1, conv1_1_bn, conv1_1_relu, + conv1_2, conv1_2_bn, conv1_2_relu)) + + pools.append(features[4]) + + conv2_1 = features[5] + conv2_1_bn = nn.BatchNorm2d(128) + conv2_1_relu = features[6] + conv2_2 = features[7] + conv2_2_bn = nn.BatchNorm2d(128) + conv2_2_relu = features[8] + + # downs.append([conv2_1, conv2_1_bn, conv2_1_relu, + # conv2_2, conv2_2_bn, conv2_2_relu]) + downs.append( + nn.Sequential( + conv2_1, conv2_1_bn, conv2_1_relu, + conv2_2, conv2_2_bn, conv2_2_relu)) + + pools.append(features[9]) + + conv3_1 = features[10] + conv3_1_bn = nn.BatchNorm2d(256) + conv3_1_relu = features[11] + conv3_2 = features[12] + conv3_2_bn = nn.BatchNorm2d(256) + conv3_2_relu = features[13] + conv3_3 = features[14] + conv3_3_bn = nn.BatchNorm2d(256) + conv3_3_relu = features[15] + + # downs.append([conv3_1, conv3_1_bn, conv3_1_relu, + # conv3_2, conv3_2_bn, conv3_2_relu, + # conv3_3, conv3_3_bn, conv3_3_relu]) + downs.append( + nn.Sequential( + conv3_1, conv3_1_bn, conv3_1_relu, + conv3_2, conv3_2_bn, conv3_2_relu, + conv3_3, conv3_3_bn, conv3_3_relu)) + + pools.append(features[16]) + + conv4_1 = features[17] + conv4_1_bn = nn.BatchNorm2d(512) + conv4_1_relu = features[18] + conv4_2 = features[19] + conv4_2_bn = nn.BatchNorm2d(512) + conv4_2_relu = features[20] + conv4_3 = features[21] + conv4_3_bn = nn.BatchNorm2d(512) + conv4_3_relu = features[22] + + # downs.append([conv4_1, conv4_1_bn, conv4_1_relu, + # conv4_2, conv4_2_bn, conv4_2_relu, + # conv4_3, conv4_3_bn, conv4_3_relu]) + downs.append( + nn.Sequential( + conv4_1, conv4_1_bn, conv4_1_relu, + conv4_2, conv4_2_bn, conv4_2_relu, + conv4_3, conv4_3_bn, conv4_3_relu)) + + + pools.append(features[23]) + + conv5_1 = features[24] + conv5_1_bn = nn.BatchNorm2d(512) + conv5_1_relu = features[25] + conv5_2 = features[26] + conv5_2_bn = nn.BatchNorm2d(512) + conv5_2_relu = features[27] + conv5_3 = features[28] + conv5_3_bn = nn.BatchNorm2d(512) + conv5_3_relu = features[29] + + # downs.append([conv5_1, conv5_1_bn, conv5_1_relu, + # conv5_2, conv5_2_bn, conv5_2_relu, + # conv5_3, conv5_3_bn, conv5_3_relu]) + downs.append( + nn.Sequential( + conv5_1, conv5_1_bn, conv5_1_relu, + conv5_2, conv5_2_bn, conv5_2_relu, + conv5_3, conv5_3_bn, conv5_3_relu)) + + return downs, pools diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/caisc_iris_recognize.iml b/.idea/caisc_iris_recognize.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/caisc_iris_recognize.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bcd38e4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5421ccb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/checkpoints/unet_vgg16_multitask_attention_epoch600.pth b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth new file mode 100644 index 0000000..035d0c7 --- /dev/null +++ b/checkpoints/unet_vgg16_multitask_attention_epoch600.pth Binary files differ diff --git a/iris_encode.py b/iris_encode.py new file mode 100644 index 0000000..e798f60 --- /dev/null +++ b/iris_encode.py @@ -0,0 +1,204 @@ +import cv2 +import numpy as np + + + +def get_gabor_filters(): + gabor1 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor2 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, 0.00, 1.00, 1.00, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, 0.00, 0.50, 0.50, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor3 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + 0.50, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor4 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25], + ] + + gabor5 = [ + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor6 = [ + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -1.00, + -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, -1.00, 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, + -0.50], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, -0.50, + -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, -0.50, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, -0.25, + -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, + -0.25], + ] + + gabor_filter1 = np.array(gabor1,dtype=np.float) + gabor_filter2 = np.array(gabor2,dtype=np.float) + gabor_filter3 = np.array(gabor3,dtype=np.float) + gabor_filter4 = np.array(gabor4,dtype=np.float) + gabor_filter5 = np.array(gabor5,dtype=np.float) + gabor_filter6 = np.array(gabor6,dtype=np.float) + + gabor_filters = [gabor_filter1,gabor_filter2,gabor_filter3,gabor_filter4,gabor_filter5,gabor_filter6] + + return gabor_filters + + +def add_borders(pSrc, width): + + result = cv2.copyMakeBorder(pSrc,0,0,width,width,cv2.BORDER_REPLICATE,value=0) + src_cols = pSrc.shape[1] + result_cols = result.shape[1] + result[:,0:width] = pSrc[:,src_cols-width:] + result[:,result_cols - width:] = pSrc[:,0:width] + + return result + +def encode_image(image, gabor_filters): + + max_width = gabor_filters[-1].shape[1] + max_width = (max_width - 1) / 2 + max_width = int(max_width) + + resized = add_borders(image, int(max_width)) + + encode_image = np.zeros((image.shape[0]*len(gabor_filters), image.shape[1]),dtype=np.float) + + rows = image.shape[0] + cols = image.shape[1] + + for (i,filter) in enumerate(gabor_filters): + img1 = cv2.filter2D(resized,ddepth=cv2.CV_32F,kernel=filter) + ret, img2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY) + encode_image[i*rows:i*rows+rows , : ] = img2[:,max_width:max_width+cols] + + return encode_image + + + +if __name__ == '__main__': + + image = cv2.imread('/home/ubuntu/桌面/test.png',0) + re = add_borders(image, 50) + + gabor_filters = get_gabor_filters() + test = encode_image(image, gabor_filters) + + cv2.imshow("test",test) + cv2.waitKey(0) \ No newline at end of file diff --git a/iris_location.py b/iris_location.py new file mode 100755 index 0000000..4a9586c --- /dev/null +++ b/iris_location.py @@ -0,0 +1,155 @@ +import os +import logging +import time +import cv2 +import torch +import numpy as np + +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + + +def location(net, img, device, scale_factor = 1): + mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor = scale_factor) + mask = np.array(mask*255,dtype=np.uint8) + iris = np.array(iris*255,dtype=np.uint8) + pupil = np.array(pupil*255,dtype=np.uint8) + return mask, iris, pupil + +def predict_img(net, + image, + device, + scale_factor=1, + out_threshold=0.5): + net.eval() + + full_img = image + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + if image.ndim == 2: + image = image[:, :, None] + + mean = np.array([103.939, 116.779, 123.68]) + image = image - mean + + image = image.transpose((2, 0, 1)) + image = torch.from_numpy(image) + # if isinstance(image, torch.ByteTensor): + # image = image.float().div(255) + image = image.float() + + image = image.unsqueeze(0) + image = image.to(device=device, dtype=torch.float32) + + with torch.no_grad(): + mask_output, iris_output, pupil_output = net(image) + + if net.n_classes > 1: + mask_probs = F.softmax(mask_output, dim=1) + iris_probs = F.softmax(iris_output, dim=1) + pupil_probs = F.softmax(pupil_output, dim=1) + else: + mask_probs = torch.sigmoid(mask_output) + iris_probs = torch.sigmoid(iris_output) + pupil_probs = torch.sigmoid(pupil_output) + + + mask_probs = mask_probs.squeeze(0) + iris_probs = iris_probs.squeeze(0) + pupil_probs = pupil_probs.squeeze(0) + + # tf = transforms.Compose( + # [ + # transforms.ToPILImage(), + # transforms.Resize(full_img.shape[:2]), + # transforms.ToTensor() + # ] + # ) + + # mask_probs = tf(mask_probs.cpu()) + # iris_probs = tf(iris_probs.cpu()) + # pupil_probs = tf(pupil_probs.cpu()) + + mask_probs = mask_probs.cpu() + iris_probs = iris_probs.cpu() + pupil_probs = pupil_probs.cpu() + + full_mask = mask_probs.squeeze().cpu().numpy() + full_iris = iris_probs.squeeze().cpu().numpy() + full_pupil = pupil_probs.squeeze().cpu().numpy() + + return full_mask > out_threshold, full_iris > out_threshold, full_pupil + + + +def mask_to_image(mask): + return Image.fromarray((mask * 255).astype(np.uint8)) + + +# if __name__ == '__main__': +# +# # torch.set_num_threads(1) +# print(torch.get_num_threads()) +# print(torch.get_num_interop_threads()) +# +# logging.getLogger().setLevel(logging.INFO) +# +# if not os.path.exists(output_mask_dir): +# os.makedirs(output_mask_dir) +# +# if not os.path.exists(output_pupil_dir): +# os.makedirs(output_pupil_dir) +# +# if not os.path.exists(output_iris_dir): +# os.makedirs(output_iris_dir) +# +# vgg16 = vgg16() +# net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) +# +# logging.info("Loading model {}".format(model_path)) +# +# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +# logging.info('Using device {}'.format(device)) +# net.to(device=device) +# net.load_state_dict(torch.load(model_path, map_location=device)) +# +# logging.info("Model loaded !") +# +# in_files = os.listdir(input_dir) +# all_start_time = time.time() +# +# for i, fn in enumerate(in_files): +# +# filename = fn +# fn = input_dir + filename +# logging.info("\nPredicting image {} ...".format(fn)) +# +# img = cv2.imread(fn) +# +# start_time = time.time() +# mask, iris, pupil = predict_img(net=net, image=img, device=device, scale_factor=scale) +# +# out_mask_path = output_mask_dir + os.path.splitext(filename)[0] + '.bmp' +# mask = mask_to_image(mask) +# mask.save(out_mask_path) +# +# out_iris_path = output_iris_dir + os.path.splitext(filename)[0] + '.bmp' +# iris = mask_to_image(iris) +# iris.save(out_iris_path) +# +# out_pupil_path = output_pupil_dir + os.path.splitext(filename)[0] + '.bmp' +# pupil = mask_to_image(pupil) +# pupil.save(out_pupil_path) +# +# end_time = time.time() +# print(" time:" + str(end_time - start_time) + " sec") +# +# logging.info("Mask saved to {}".format(out_mask_path)) +# +# all_end_time = time.time() +# avg_time = (all_end_time - all_start_time) / len(in_files) +# print("average time is %f seconds" % avg_time) \ No newline at end of file diff --git a/iris_recognize.py b/iris_recognize.py new file mode 100644 index 0000000..83d9934 --- /dev/null +++ b/iris_recognize.py @@ -0,0 +1,195 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +scale_factor = 0.5 + +def get_application_points(point_path, width, height): + point_file = open(point_path,'r') + point_lines = point_file.readlines() + + application_points = np.zeros((height,width),dtype=np.uint8) + for lines in point_lines[1:]: + index = lines.split(" ") + application_points[int(index[0])][int(index[1])] = 255 + + return application_points + + +def process_eye(image, mask, iris, pupil,out = False, out_path = None): + + h, w = image.shape[:2] + new_w, new_h = int(scale_factor * w), int(scale_factor * h) + assert new_w > 0 and new_h > 0, 'Scale is too small' + image_resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_NEAREST) + + mask, iris_circle, pupil_circle = post_processing_image(mask, iris, pupil, debug=False) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + if out: + + mask_color = cv2.applyColorMap(mask, cv2.COLORMAP_JET) + show_image = cv2.addWeighted(image_resized, 0.7, mask_color, 0.3, 0) + cv2.circle(show_image, (iris_x, iris_y), iris_r, (0, 0, 255), 1) + cv2.circle(show_image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow("show_image",show_image) + # cv2.waitKey(0) + cv2.imwrite(out_path, show_image) + + if iris_r == 0 or pupil_r == 0: + return None, None, None + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + return None, None, None + + width = 512 + height = 64 + single_image = image_resized[:,:,0] + mask = mask + norm_image = normalize_image(single_image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + norm_mask = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + gabor_filters = get_gabor_filters() + encode = encode_image(norm_image, gabor_filters) + + return norm_image, norm_mask ,encode + +def match(code1,code2,norm_mask1, norm_mask2, application_points=None): + score = 1 + + temp = cv2.bitwise_and(norm_mask1,norm_mask2,mask=application_points) + total_mask = np.vstack([temp]*6) + + shift = 10 + shifted = add_borders(code1,shift) + + width = code1.shape[1] + for i in range(-shift,shift+1,1): + roi = shifted[:,shift+i:shift+i+width] + result = cv2.bitwise_xor(roi,code2,mask=total_mask) + + mean = cv2.sumElems(result)[0] / cv2.sumElems(total_mask)[0] + score = min(score, mean) + + return score + +if __name__ == '__main__': + # load application points + point_path = '/home/ubuntu/points.txt' + points = get_application_points(point_path,512,64) + # load model + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + inclass = 0 + outclass = 0 + + true_accept = 0 + false_accept = 0 + true_reject = 0 + false_reject = 0 + + score_threshold = 0.32 + + image_dir = '/home/ubuntu/iris_image/casic_iris_origin/image/' + image_list = os.listdir(image_dir) + + norm_img_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_image/' + if not os.path.exists(norm_img_dir): + os.makedirs(norm_img_dir) + + norm_mask_dir = '/home/ubuntu/iris_image/casic_iris_origin/norm_mask/' + if not os.path.exists(norm_mask_dir): + os.makedirs(norm_mask_dir) + + code_dir = '/home/ubuntu/iris_image/casic_iris_origin/code/' + if not os.path.exists(code_dir): + os.makedirs(code_dir) + + out = True + out_dir = '/home/ubuntu/iris_image/casic_iris_origin/output/' + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + for image_name in image_list: + print("processing", image_name) + image1 = cv2.imread(image_dir + image_name) + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=scale_factor) + out_path = out_dir + image_name + norm_image1, norm_mask1, encode1 = process_eye(image1, mask1, iris1, pupil1, out=out, out_path=out_path) + if encode1 is not None: + cv2.imwrite(norm_img_dir + image_name, norm_image1) + cv2.imwrite(norm_mask_dir + image_name, norm_mask1) + cv2.imwrite(code_dir + image_name, encode1) + + for image_name1 in image_list: + print("compare with " + image_name1 + "===========================================") + + + for image_name2 in image_list: + if image_name1 == image_name2: + continue + + encode1 = cv2.imread(code_dir + image_name1, 0) + encode2 = cv2.imread(code_dir + image_name2, 0) + + norm_mask1 = cv2.imread(norm_mask_dir + image_name1, 0) + norm_mask2 = cv2.imread(norm_mask_dir + image_name2, 0) + + if encode1 is None or encode2 is None: + continue + + score = match(encode1,encode2,norm_mask1,norm_mask2,points) + # e_time = time.time() + + out_info = image_name2 + " " + str(score) + " " + + # print(image_name2, score) + + file_match = (image_name1[0:image_name1.find("eye")] == image_name2[0:image_name2.find("eye")]) + # file_match = (image_name1[0:6] == image_name2[0:6]) + # file_match = (image_name1[0:7]==image_name2[0:7]) and (image_name1[16:17]==image_name2[16:17]) + + if file_match: + inclass += 1 + if score <= score_threshold: + true_accept += 1 + else: + false_reject += 1 + out_info += " " + "false_reject" + print(out_info) + else: + outclass += 1 + if score <= score_threshold: + false_accept += 1 + out_info += " " + "false_accept" + print(out_info) + else: + true_reject += 1 + + + + print('inclass',inclass) + print('outclass', outclass) + print('false_reject',false_reject) + print('false_accept',false_accept) + print('true_accept',true_accept) + print('true_reject',true_reject) + print('frr', false_reject/ inclass) + print('far', false_accept/outclass) + print('crr',(true_reject+true_accept)/(inclass+outclass)) diff --git a/iris_test.py b/iris_test.py new file mode 100644 index 0000000..30a736c --- /dev/null +++ b/iris_test.py @@ -0,0 +1,33 @@ +import os +import time + +import cv2 +import numpy as np +import torch +from torchvision.models.vgg import vgg16_bn, vgg16 +from model.unet_vgg16_multitask_attention import UnetWithVGG16Attention + +from iris_location import location +from iris_encode import add_borders, encode_image,get_gabor_filters +from post_processing import post_processing_image, normalize_image + +if __name__ == '__main__': + model_path = ('checkpoints/unet_vgg16_multitask_attention_epoch600.pth') + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + vgg16 = vgg16() + net = UnetWithVGG16Attention(encoder=vgg16, n_classes=1, bilinear=True) + net.to(device=device) + net.load_state_dict(torch.load(model_path, map_location=device)) + + image1 = cv2.imread('/home/ubuntu/iris_image/debug_image/1-2-19-righteye2.bmp') + mask1, iris1, pupil1 = location(net, image1, device, scale_factor=0.5) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + ret3, pupil1 = cv2.threshold(pupil1, 200, 255, cv2.THRESH_BINARY) + + cv2.imshow('pupil',pupil1) + cv2.waitKey(0) + + norm_image1, norm_mask1, encode1 = post_processing_image(mask1, iris1, pupil1,debug=False) \ No newline at end of file diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/model/__init__.py diff --git a/model/attention.py b/model/attention.py new file mode 100755 index 0000000..9f2a0f5 --- /dev/null +++ b/model/attention.py @@ -0,0 +1,55 @@ +import torch +from torch import nn +import torch.nn.functional as F + + +class ASPP(nn.Module): + def __init__(self, in_channel=512, depth=256): + super(ASPP, self).__init__() + # global average pooling : init nn.AdaptiveAvgPool2d ;also forward torch.mean(,,keep_dim=True) + self.mean = nn.AdaptiveAvgPool2d((1, 1)) # (1,1) means output size + self.conv = nn.Conv2d(in_channel, depth, 1, 1) + # k=1 s=1 no pad + self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1) + self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6) + self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12) + self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18) + + self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1) + + self.conv_3x3_output1 = nn.Conv2d(in_channels= depth * 5, out_channels= 256, kernel_size=3, stride=1, padding=1) + self.conv_3x3_output2 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1) + self.sigmoid = F.sigmoid + + def forward(self, x): + size = x.shape[2:] + + image_features = self.mean(x) + image_features = self.conv(image_features) + image_features = F.upsample(image_features, size=size, mode='bilinear') + + atrous_block1 = self.atrous_block1(x) + + atrous_block6 = self.atrous_block6(x) + + atrous_block12 = self.atrous_block12(x) + + atrous_block18 = self.atrous_block18(x) + + concat = torch.cat([image_features, atrous_block1, atrous_block6, + atrous_block12, atrous_block18], dim=1) + + # 256 3*3 conv + out_conv = self.conv_3x3_output1(concat) + # 512 3*3 conv + out_conv = self.conv_3x3_output2(out_conv) + # sigmoid , M + M = self.sigmoid(out_conv) + # element-wise dot product:M*input + out = M * x + # concat with input + net = torch.cat([x, out], dim=1) + + # net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6, + # atrous_block12, atrous_block18], dim=1)) + return net diff --git a/model/unet_parts.py b/model/unet_parts.py new file mode 100755 index 0000000..a620d82 --- /dev/null +++ b/model/unet_parts.py @@ -0,0 +1,78 @@ +""" Parts of the U-Net model """ + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class DoubleConv(nn.Module): + """(convolution => [BN] => ReLU) * 2""" + + def __init__(self, in_channels, out_channels, mid_channels=None): + super(DoubleConv,self).__init__() + if not mid_channels: + mid_channels = out_channels + self.double_conv = nn.Sequential( + nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(mid_channels), + nn.ReLU(inplace=True), + nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True) + ) + + def forward(self, x): + return self.double_conv(x) + + +class Down(nn.Module): + """Downscaling with maxpool then double conv""" + + def __init__(self, in_channels, out_channels): + super(Down,self).__init__() + self.maxpool_conv = nn.Sequential( + nn.MaxPool2d(2), + DoubleConv(in_channels, out_channels) + ) + + def forward(self, x): + return self.maxpool_conv(x) + + +class Up(nn.Module): + """Upscaling then double conv""" + + def __init__(self, in_channels, out_channels, bilinear=True): + super(Up,self).__init__() + + # if bilinear, use the normal convolutions to reduce the number of channels + if bilinear: + self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) + self.conv = DoubleConv(in_channels, out_channels, in_channels // 2) + else: + self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2) + self.conv = DoubleConv(in_channels, out_channels) + + def forward(self, x1, x2): + x1 = self.up(x1) + # input is CHW + diffY = x2.size()[2] - x1.size()[2] + diffX = x2.size()[3] - x1.size()[3] + + x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, + diffY // 2, diffY - diffY // 2]) + # if you have padding issues, see + # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a + # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd + x = torch.cat([x2, x1], dim=1) + return self.conv(x) + + +class OutConv(nn.Module): + def __init__(self, in_channels, out_channels): + super(OutConv, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1) + + def forward(self, x): + return self.conv(x) + diff --git a/model/unet_vgg16_multitask_attention.py b/model/unet_vgg16_multitask_attention.py new file mode 100755 index 0000000..ac7eb10 --- /dev/null +++ b/model/unet_vgg16_multitask_attention.py @@ -0,0 +1,163 @@ +import torch +from .unet_parts import * +from .attention import ASPP + + +class UnetWithVGG16Attention(torch.nn.Module): + + def __init__(self, encoder, n_classes=1, bilinear=True): + super(UnetWithVGG16Attention, self).__init__() + + self.features = encoder.features[:-1] # drop last maxpooling + self.n_classes = n_classes + self.bilinear = bilinear + self.downs = [] + + self.feature_len: int = len(self.features) + + self.attention = ASPP(in_channel=512,depth=256) + + self.up1 = Up(1536, 256, self.bilinear) + self.up2 = Up(512, 128, self.bilinear) + self.up3 = Up(256, 64, self.bilinear) + self.up4 = Up(128, 32, self.bilinear) + self.outc = OutConv(32, n_classes * 3) + self.outc1 = OutConv(32, n_classes) + self.outc2 = OutConv(32, n_classes) + self.outc3 = OutConv(32, n_classes) + + def forward(self, x): + # dict = {'5':0, '12':1, '22':2, '32':3} + # concat_index = [5, 12, 22, 32] # bn + concat_index = [3, 8, 15, 22] + downs = [] + + f_len = self.feature_len + o = x + for i, feature in enumerate(self.features): + o = feature(o) + if i in concat_index: + downs.append(o) + # print(len(self.downs)) + # print(str(i) + ' ' + str(dict[str(i)])) + # self.downs[dict[str(i)]] = o + + o = self.attention(o) + + x = self.up1(o, downs[-1]) + x = self.up2(x, downs[-2]) + x = self.up3(x, downs[-3]) + x = self.up4(x, downs[-4]) + + mask_iris_pupil = self.outc(x) + + spilt_mask_iris_pupil = torch.split(mask_iris_pupil, 1, dim=1) + pupil = spilt_mask_iris_pupil[0] + mask = spilt_mask_iris_pupil[1] + iris = spilt_mask_iris_pupil[2] + + # mask = self.outc1(x) + # iris = self.outc2(x) + # pupil = self.outc3(x) + + return mask, iris, pupil + + def get_encoder(self, features, batch_norm=True): + downs = [] + pools = [] + + conv1_1 = features[0] + conv1_1_bn = nn.BatchNorm2d(64) + conv1_1_relu = features[1] + conv1_2 = features[2] + conv1_2_bn = nn.BatchNorm2d(64) + conv1_2_relu = features[3] + + # downs.append([conv1_1, conv1_1_bn, conv1_1_relu, + # conv1_2, conv1_2_bn, conv1_2_relu]) + downs.append( + nn.Sequential( + conv1_1, conv1_1_bn, conv1_1_relu, + conv1_2, conv1_2_bn, conv1_2_relu)) + + pools.append(features[4]) + + conv2_1 = features[5] + conv2_1_bn = nn.BatchNorm2d(128) + conv2_1_relu = features[6] + conv2_2 = features[7] + conv2_2_bn = nn.BatchNorm2d(128) + conv2_2_relu = features[8] + + # downs.append([conv2_1, conv2_1_bn, conv2_1_relu, + # conv2_2, conv2_2_bn, conv2_2_relu]) + downs.append( + nn.Sequential( + conv2_1, conv2_1_bn, conv2_1_relu, + conv2_2, conv2_2_bn, conv2_2_relu)) + + pools.append(features[9]) + + conv3_1 = features[10] + conv3_1_bn = nn.BatchNorm2d(256) + conv3_1_relu = features[11] + conv3_2 = features[12] + conv3_2_bn = nn.BatchNorm2d(256) + conv3_2_relu = features[13] + conv3_3 = features[14] + conv3_3_bn = nn.BatchNorm2d(256) + conv3_3_relu = features[15] + + # downs.append([conv3_1, conv3_1_bn, conv3_1_relu, + # conv3_2, conv3_2_bn, conv3_2_relu, + # conv3_3, conv3_3_bn, conv3_3_relu]) + downs.append( + nn.Sequential( + conv3_1, conv3_1_bn, conv3_1_relu, + conv3_2, conv3_2_bn, conv3_2_relu, + conv3_3, conv3_3_bn, conv3_3_relu)) + + pools.append(features[16]) + + conv4_1 = features[17] + conv4_1_bn = nn.BatchNorm2d(512) + conv4_1_relu = features[18] + conv4_2 = features[19] + conv4_2_bn = nn.BatchNorm2d(512) + conv4_2_relu = features[20] + conv4_3 = features[21] + conv4_3_bn = nn.BatchNorm2d(512) + conv4_3_relu = features[22] + + # downs.append([conv4_1, conv4_1_bn, conv4_1_relu, + # conv4_2, conv4_2_bn, conv4_2_relu, + # conv4_3, conv4_3_bn, conv4_3_relu]) + downs.append( + nn.Sequential( + conv4_1, conv4_1_bn, conv4_1_relu, + conv4_2, conv4_2_bn, conv4_2_relu, + conv4_3, conv4_3_bn, conv4_3_relu)) + + + pools.append(features[23]) + + conv5_1 = features[24] + conv5_1_bn = nn.BatchNorm2d(512) + conv5_1_relu = features[25] + conv5_2 = features[26] + conv5_2_bn = nn.BatchNorm2d(512) + conv5_2_relu = features[27] + conv5_3 = features[28] + conv5_3_bn = nn.BatchNorm2d(512) + conv5_3_relu = features[29] + + # downs.append([conv5_1, conv5_1_bn, conv5_1_relu, + # conv5_2, conv5_2_bn, conv5_2_relu, + # conv5_3, conv5_3_bn, conv5_3_relu]) + downs.append( + nn.Sequential( + conv5_1, conv5_1_bn, conv5_1_relu, + conv5_2, conv5_2_bn, conv5_2_relu, + conv5_3, conv5_3_bn, conv5_3_relu)) + + return downs, pools diff --git a/post_processing.py b/post_processing.py new file mode 100644 index 0000000..44225bc --- /dev/null +++ b/post_processing.py @@ -0,0 +1,429 @@ +import time + +import cv2 +import math +import numpy as np +import os +import traceback + +def single_channel_to_multi_channel(arr): + arr_c3 = arr + if len(arr.shape) < 3: + arr_c1 = np.expand_dims(arr, axis=2) + arr_c3 = np.concatenate((arr_c1, arr_c1, arr_c1), axis=-1) + return arr_c3 + + +# 获取图像8连通域 +def get_connections(img): + cons = [] + if len(img.shape) > 2: + img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) + _, labels = cv2.connectedComponents(img, connectivity=8) + max_value = labels.max() + 1 + for i in range(max_value)[1:]: + con = (labels == i) + con = con.astype(np.uint8) + cons.append(con) + return cons + + +# 展示各个连通域 +def show_connections(cons): + for con in cons: + con_c3 = single_channel_to_multi_channel(con) + _, con_img = cv2.threshold(con_c3, 0, 255, cv2.THRESH_BINARY) + cv2.imshow('con', con_img) + cv2.waitKey(0) + cv2.destroyAllWindows() + + +# 获取相邻三元组 +def get_triplet_set(mask_cons, iris_cons, pupil_cons, debug = False,chessboard_distance_threshold = 20): + triplet_set = [] + for mask_con in mask_cons: + for iris_con in iris_cons: + try: + d2 = get_chessboard_distance(mask_con, iris_con,debug=debug, chessboard_distance_threshold=chessboard_distance_threshold) + for pupil_con in pupil_cons: + d1 = get_chessboard_distance(mask_con, pupil_con,debug=debug, chessboard_distance_threshold=chessboard_distance_threshold) + # print('mask_pupil:',d1,'mask_iris:',d2) + if d1 <= chessboard_distance_threshold and d2 <=chessboard_distance_threshold: + # if get_chessboard_distance(mask_con, pupil_con) <= 10 \ + # and get_chessboard_distance(mask_con, iris_con) <= 15: + triplet_set.append((mask_con, iris_con, pupil_con)) + except: + error = traceback.format_exc() + print(error) + continue + return triplet_set + +# 计算两个区域的棋盘距离 +def get_chessboard_distance(con1, con2,debug = False, chessboard_distance_threshold = 20): + + _, con1_th = cv2.threshold(con1,0,255,cv2.THRESH_BINARY) + c1, _ = cv2.findContours(con1_th,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + + if debug: + con1_th = single_channel_to_multi_channel(con1_th) + cv2.drawContours(con1_th,c1,-1,(0,0,255),3) + cv2.imshow('con1',con1_th) + cv2.waitKey(0) + + c1 = np.concatenate(c1) + c1 = np.squeeze(c1, axis=1) + + _, con2_th = cv2.threshold(con2, 0, 255, cv2.THRESH_BINARY) + c2, _ = cv2.findContours(con2_th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + if debug: + con2_th = single_channel_to_multi_channel(con2_th) + cv2.drawContours(con2_th,c2,-1,(0,0,255),3) + cv2.imshow('con2',con2_th) + cv2.waitKey(0) + + c2 = np.concatenate(c2) + c2 = np.squeeze(c2, axis=1) + + distance = np.abs(c1[:,None,:] - c2[None,:,:]).max(axis=2).min(axis=1).min() + + # distance = 1000 + # con1_idx = np.where(c1 > 0) + # con2_idx = np.where(c2 > 0) + # print(len(con1_idx[0]), len(con2_idx[0])) + # for i in range(len(con1_idx[0])): + # for j in range(len(con2_idx[0])): + # chessboard_distance = max(abs(con1_idx[0][i] - con2_idx[0][j]), abs(con1_idx[1][i] - con2_idx[1][j])) + # print(len(c1), len(c2)) + # for i in range(len(c1)): + # for j in range(len(c2)): + # chessboard_distance = max(abs(c1[i][0] - c2[j][0]), abs(c1[i][1] - c2[j][1])) + # if chessboard_distance < distance: + # distance = chessboard_distance + # if distance <= chessboard_distance_threshold: + # break + + if debug: + print('distance',distance) + return distance + +# 展示三元组 +def show_triplet(triplet): + all = triplet[0] + triplet[1] + triplet[2] + all_c3 = single_channel_to_multi_channel(all) + _, triplet_img = cv2.threshold(all_c3, 0, 255, cv2.THRESH_BINARY) + cv2.imshow('triplet', triplet_img) + cv2.waitKey(0) + +# 获取最大三元组 +def get_max_triplet(triplet_set): + max_count = 0 + max_index = -1 + for i, triplet in enumerate(triplet_set): + # show_triplet(triplet) + #all = triplet[0] + triplet[1] + triplet[2] + #count = np.count_nonzero(all) + count = np.count_nonzero(triplet[0]) + np.count_nonzero(triplet[1]) + np.count_nonzero(triplet[2]) + # print('count', count) + if count > max_count: + max_count = count + max_index = i + return triplet_set[max_index] + +# 最小二乘法拟合圆 +def least_square_circle_fitting(counter): + + center_x = 0.0 + center_y = 0.0 + radius = 0.0 + + if(len(counter)<=3): + return center_x,center_y,radius + + sum_x, sum_y = 0.0, 0.0 + sum_x2, sum_y2 = 0.0, 0.0 + sum_x3, sum_y3 = 0.0, 0.0 + sum_xy, sum_x1y2, sum_x2y1 = 0.0, 0.0, 0.0 + + for point in counter: + x = point[0] + y = point[1] + x2 = x * x + y2 = y * y + sum_x += x + sum_y += y + sum_x2 += x2 + sum_y2 += y2 + sum_x3 += x2 * x + sum_y3 += y2 * y + sum_xy += x*y + sum_x1y2 += x * y2 + sum_x2y1 += x2 * y + + N = len(counter) + C = N * sum_x2 - sum_x * sum_x + D = N * sum_xy - sum_x * sum_y + E = N * sum_x3 + N * sum_x1y2 - (sum_x2 + sum_y2) * sum_x + G = N * sum_y2 - sum_y * sum_y + H = N * sum_x2y1 + N * sum_y3 - (sum_x2 + sum_y2) * sum_y + a = (H * D - E * G) / (C * G - D * D) + b = (H * C - E * D) / (D * D - G * C) + c = -(a * sum_x + b * sum_y + sum_x2 + sum_y2) / N + + center_x = a / (-2) + center_y = b / (-2) + radius = math.sqrt(a * a + b * b - 4 * c) / 2 + + return center_x, center_y, radius + +def post_processing_image(mask,iris,pupil,debug = False): + iris_x, iris_y, iris_r = 0, 0, 0 + pupil_x, pupil_y, pupil_r = 0, 0, 0 + + # time1 = time.time() + # 1. 二值化 + ret1, mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY) + ret2, iris = cv2.threshold(iris, 90, 255, cv2.THRESH_BINARY) + ret3, pupil = cv2.threshold(pupil, 200, 255, cv2.THRESH_BINARY) + # ret2, iris = cv2.threshold(iris, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + # ret3, pupil = cv2.threshold(pupil, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + + # 对虹膜外圆做闭运算,连通小断点 + size = 5 + kernel = np.ones((size, size), dtype=np.uint8) + iris = cv2.erode(cv2.dilate(iris, kernel), kernel) + + # if debug: + # cv2.imshow('mask',mask) + # cv2.waitKey(0) + # cv2.imshow('iris',iris) + # cv2.waitKey(0) + # cv2.imshow('pupil',pupil) + # cv2.waitKey(0) + # cv2.destroyAllWindows() + + # time2 = time.time() + # 2. 8邻域 + mask_cons = get_connections(mask) + iris_cons = get_connections(iris) + pupil_cons = get_connections(pupil) + + if debug: + show_connections(mask_cons) + show_connections(iris_cons) + show_connections(pupil_cons) + + if len(mask_cons) < 1 or len(iris_cons) < 1 or len(pupil_cons) < 1: + return mask,(iris_y,iris_x,iris_r),(pupil_x,pupil_y,pupil_r) + + # time3 = time.time() + # 3. 形成三元组 + triplet_set = get_triplet_set(mask_cons, iris_cons, pupil_cons,debug=debug) + + if(len(triplet_set) < 1): + return mask,(iris_y,iris_x,iris_r),(pupil_x,pupil_y,pupil_r) + + if debug: + for triplet in triplet_set: + show_triplet(triplet) + + # 4. 选择最大三元组 + # max_triplet = get_max_triplet(triplet_set) + # if debug: + # show_triplet(max_triplet) + # time4 = time.time() + sort_triplet = sorted(triplet_set, key=lambda triplet:(np.count_nonzero(triplet[0]) + np.count_nonzero(triplet[1]) + np.count_nonzero(triplet[2]))) + max_triplet = sort_triplet[-1] + # show_triplet(max_triplet) + + if len(triplet_set) > 1: + sec_triplet = sort_triplet[-2] + # show_triplet(sec_triplet) + + # 5. 轮廓提取 + 最小二乘圆拟合 + # 外圆 + # time5 = time.time() + best_iris = max_triplet[1] + if len(triplet_set) > 1: + best_iris = cv2.bitwise_or( + best_iris, sec_triplet[1]) + _, best_iris = cv2.threshold(best_iris, 0, 255, cv2.THRESH_BINARY) + + # if debug: + # cv2.imshow('best_iris',best_iris) + # cv2.waitKey(0) + + out_counters = np.nonzero(best_iris) + out_points = [] + for i in range(len(out_counters[0])): + out_points.append((out_counters[1][i], out_counters[0][i])) + iris_x, iris_y, iris_r = least_square_circle_fitting(out_points) + iris_x = int(iris_x) + iris_y = int(iris_y) + iris_r = int(iris_r) + # print(iris_x, iris_y, iris_r) + + # cv2.circle(mask, (iris_x, iris_y),iris_r,(0,0,255),1) + # cv2.imshow('outer',mask) + # cv2.waitKey(0) + + # 内圆 + # time6 = time.time() + best_pupil = max_triplet[2] + _, best_pupil = cv2.threshold(best_pupil, 0, 255, cv2.THRESH_BINARY) + counters, _ = cv2.findContours(best_pupil, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + inner_points = np.squeeze(counters[0], axis=1) + pupil_x, pupil_y, pupil_r = least_square_circle_fitting(inner_points) + pupil_x = int(pupil_x) + pupil_y = int(pupil_y) + pupil_r = int(pupil_r) + # print(pupil_x, pupil_y, pupil_r) + + # 绘制轮廓 + # best_pupil_c = single_channel_to_multi_channel(best_pupil) + # cv2.drawContours(best_pupil_c, counters, -1, (0, 0, 255), 3) + # cv2.imshow('inner', best_pupil_c) + # cv2.waitKey(0) + + # 6. 优化mask:必须在内外圆内 + # time7 = time.time() + circle_mask = np.zeros(mask.shape, dtype=np.uint8) + cv2.circle(circle_mask, (iris_x, iris_y), iris_r, (255, 255, 255), -1) + cv2.circle(circle_mask, (pupil_x, pupil_y), pupil_r, (0, 0, 0), -1) + mask = cv2.bitwise_and(mask, circle_mask) + + # time8 = time.time() + # print(time2-time1, time3-time2, time4-time3, time5-time4, time6-time5, time7-time6, time8-time7) + + # cv2.circle(mask, (iris_y, iris_x), iris_r, (0, 0, 255), 1) + # cv2.circle(mask, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 1) + # cv2.imshow('circle_mask', circle_mask) + # cv2.waitKey(0) + # cv2.imshow('mask', mask) + # cv2.waitKey(0) + + return mask,(iris_x,iris_y,iris_r),(pupil_x,pupil_y,pupil_r) + +def normalize_image(image, irisCenterX, irisCenterY, irisR, pupilCenterX, pupilCenterY, pupilR, width, height): + realHeight = height + 2 + angledivisions = width - 1 + rows, cols = image.shape[0:2] + + r = np.arange(0, realHeight, 1) + thetas = np.arange(0, 2*np.pi + 2*np.pi / angledivisions, 2*np.pi / angledivisions) + + ox = pupilCenterX - irisCenterX + oy = pupilCenterY - irisCenterY + + if ox <= 0: + sgn = -1 + elif ox > 0: + sgn = 1 + + if ox == 0 and oy > 0: + sgn = 1 + + a = np.ones((1,width)) * (ox*ox + oy*oy) + + if ox == 0: + phi = np.pi/2 + else: + phi = math.atan(oy/ox) + + b = sgn * np.cos(np.pi - phi - thetas) + + r = np.multiply(np.sqrt(a), b) + np.sqrt(np.multiply(a, np.power(b, 2)) - (a - np.power(irisR, 2))) + r = r - pupilR + + rMatrix = np.transpose(np.ones((1, realHeight))) * r + rMatrix = np.multiply(rMatrix, np.transpose(np.ones((angledivisions+1, 1))*np.arange(0, 1, 1/realHeight))) + rMatrix = rMatrix + pupilR + + rMatrix = rMatrix[1:(realHeight - 1), :] + + xcosMat = np.ones((height, 1)) * np.cos(thetas) + xsinMat = np.ones((height, 1)) * np.sin(thetas) + + xo = np.multiply(rMatrix, xcosMat) + yo = np.multiply(rMatrix, xsinMat) + + xo = pupilCenterX + xo + yo = pupilCenterY - yo + + xo = xo.astype(int) + yo = yo.astype(int) + + normImage = np.empty((0, width), np.uint8) + for i, j in zip(xo, yo): + normImage = np.vstack((normImage, image[j, i])) + + return normImage + +if __name__ == '__main__': + + chessboard_distance_threshold = 20 + debug = False + + image_dir = '/home/ubuntu/iris_image/iris-test/image/' + mask_dir = '/home/ubuntu/iris_image/iris-test/vgg16_unet_multitask_attention/epoch400_mask/' + iris_dir = '/home/ubuntu/iris_image/iris-test/vgg16_unet_multitask_attention/epoch400_iris/' + pupil_dir = '/home/ubuntu/iris_image/iris-test/vgg16_unet_multitask_attention/epoch400_pupil/' + mask_extension = 'bmp' + + file_list = os.listdir(image_dir) + + for filename in file_list: + + print(filename) + + image_path = image_dir + filename + mask_path = mask_dir + os.path.splitext(filename)[0] + '.' + mask_extension + iris_path = iris_dir + os.path.splitext(filename)[0] + '.' + mask_extension + pupil_path = pupil_dir + os.path.splitext(filename)[0] + '.' + mask_extension + + image = cv2.imread(image_path,0) + # image = cv2.resize(image,(int(image.shape[1]/2),int(image.shape[0]/2))) + + mask = cv2.imread(mask_path) + iris = cv2.imread(iris_path, 0) + pupil = cv2.imread(pupil_path, 0) + + mask, iris_circle, pupil_circle = post_processing_image(mask,iris,pupil,debug=debug) + + iris_x, iris_y, iris_r = iris_circle[0], iris_circle[1], iris_circle[2] + pupil_x, pupil_y, pupil_r = pupil_circle[0], pupil_circle[1], pupil_circle[2] + + cv2.circle(image, (iris_x, iris_y), iris_r, (0, 0, 255), 3) + cv2.circle(image, (pupil_x, pupil_y), pupil_r, (0, 0, 255), 3) + cv2.imshow('111', image) + cv2.waitKey(0) + + if pupil_x < iris_x - iris_r or pupil_x > iris_x + iris_r or pupil_y < iris_y - iris_r or pupil_y > iris_y + iris_r: + continue + + width = 256 + height = 64 + mask = mask[:,:,0] + a = normalize_image(image,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + b = normalize_image(mask,iris_x,iris_y,iris_r,pupil_x,pupil_y,pupil_r,width,height) + + # cv2.imshow('normalize_mask', b) + # cv2.waitKey(0) + # cv2.imshow('normalize_image', a) + # cv2.waitKey(0) + + + # ret2, iris = cv2.threshold(iris, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + # cv2.imshow('iris',iris) + # cv2.waitKey(0) + # + # size = 5 + # kernel = np.ones((size, size), dtype=np.uint8) + # iris = cv2.erode(cv2.dilate(iris,kernel),kernel) + # cv2.imshow('iris-close', iris) + # cv2.waitKey(0) + # + # iris_con = get_connections(iris) + # show_connections(iris_con) + +