Spaces:
Sleeping
Sleeping
| #%% | |
| import gradio as gr | |
| from PIL import Image | |
| from torchvision import transforms | |
| from siamese_nn import Siamese_nn | |
| import torch, os | |
| import torch.nn.functional as F | |
| model = Siamese_nn() | |
| weights = torch.load('trained_model', map_location=torch.device('cpu')) | |
| model.load_state_dict(weights) | |
| model.eval() | |
| file_list = os.listdir("data") | |
| examples = [] | |
| usersIndexes = [] | |
| for x in file_list: | |
| if x[0:2] not in usersIndexes: | |
| usersIndexes.append(x[0:2]) | |
| for user in usersIndexes: | |
| usersImages = [x for x in file_list if str(user) in x] | |
| notUsersImages = [x for x in file_list if str(user) not in x] | |
| for userImage in usersImages: | |
| for userImageCopy in usersImages: | |
| examples.append([userImage, userImageCopy, 0]) | |
| for notUser in notUsersImages: | |
| examples.append([userImage, notUser, 1]) | |
| def predict(input1, input2, label=None): | |
| img1_PIL = Image.open(f'data/{input1}') | |
| img2_PIL = Image.open(f'data/{input2}') | |
| img1 = transforms.ToTensor()(img1_PIL).unsqueeze(0) | |
| img2 = transforms.ToTensor()(img2_PIL).unsqueeze(0) | |
| for el in examples: | |
| if input1 == el[0] and input2 == el[1] and el[2] == 0: | |
| label = 'Scans of the same finger' | |
| break | |
| if input1 == el[0] and input2 == el[1] and el[2] == 1: | |
| label = 'Scans of different fingers' | |
| with torch.no_grad(): | |
| out1, out2 = model(img1, img2) | |
| pred = F.pairwise_distance(out1, out2) | |
| if pred < 0.6: | |
| decision = f'Access granted, confidence: {pred.item():4f}' | |
| else: | |
| decision = f'Access denied, confidence: {pred.item():4f}' | |
| return img1_PIL, img2_PIL, decision, label | |
| #%% | |
| css = """ | |
| .gradio-container { | |
| height: 100vh; | |
| max-width: 1024px !important; | |
| } | |
| .my_img { | |
| max-height: 288px !important; | |
| object-fit: cover !important; | |
| } | |
| .img-select div.secondary-wrap { | |
| position: relative; | |
| } | |
| .img-select div.icon-wrap { | |
| position: absolute; | |
| pointer-events: none; | |
| right: 0; | |
| } | |
| #res div h2 { color: #07ef03; } | |
| """ | |
| js = """ | |
| () => { | |
| label = document.querySelector("#res div h2"); | |
| txt = label.textContent.split(",")[0] | |
| if (txt === 'Access granted') { | |
| label.style.color = "#07ef03"; | |
| } | |
| if (txt === 'Access denied') { | |
| label.style.color = "red"; | |
| } | |
| } | |
| """ | |
| dropdowns = """ | |
| () => { | |
| input_el = document.querySelectorAll(".img-select input"); | |
| input_el[0].type = "button"; | |
| input_el[1].type = "button"; | |
| /* | |
| svg = document.querySelectorAll(".img-select div.icon-wrap"); | |
| ul = document.querySelectorAll(".img-select ul.options); | |
| for (let i = 0; i < input_el.length; i++){ | |
| input_el[i].addEventListener("click", () => { | |
| svg[i].style.transform = "rotate(180deg)"; | |
| }) | |
| }*/ | |
| } | |
| """ | |
| def refresh(): | |
| image = Image.open(f'data/{file_list[0]}') | |
| return image, image | |
| with gr.Blocks(css=css, js=dropdowns, elem_classes=['container']) as demo: | |
| md = gr.Markdown(value="""# Follow the steps | |
| - To check model performance choose first and second image from available examples. | |
| - You can pair up images of the same or different fingerprints. The result from model will be automatically calculated. | |
| - Additionally displayed confidence shows the similarity between images. The closer to 0, the more similar - more confident model | |
| - Access is granted if value of confidence is below certain threshold found during model testing.""") | |
| with gr.Row(): | |
| with gr.Row(): | |
| drop1 = gr.Dropdown(value=file_list[0], | |
| choices=file_list, | |
| label='Select first image', | |
| scale=1, | |
| elem_classes='img-select', | |
| ) | |
| drop2 = gr.Dropdown(value=file_list[0], | |
| choices=file_list, | |
| label='Select second image', | |
| scale=1, | |
| elem_classes='img-select', | |
| ) | |
| label = gr.Label(value='Scans of the same finger', show_label=False) | |
| with gr.Row(): | |
| img1 = gr.Image(height=288, # unfortunately value doesn't work properly | |
| width=256, | |
| interactive=False, | |
| scale=1, | |
| label='first image', | |
| show_download_button=False, | |
| show_share_button=False, | |
| elem_classes=['my-img']) | |
| img2 = gr.Image(height=288, | |
| width=256, | |
| interactive=False, | |
| scale=1, | |
| label='second image', | |
| show_download_button=False, | |
| show_share_button=False, | |
| elem_classes=['my-img']) | |
| output = gr.Label(value=predict(*examples[0])[2], elem_id='res', show_label=False) | |
| drop1.change(fn=predict, inputs=[drop1, drop2], outputs=[img1, img2, output, label]) | |
| drop2.change(fn=predict, inputs=[drop1, drop2], outputs=[img1, img2, output, label]) | |
| output.change(fn=None, inputs=None, js=js) | |
| # initial img load workaround | |
| demo.load(fn=refresh, inputs=None, outputs=[img1, img2]) | |
| demo.launch() | |
| # %% | |