File size: 4,457 Bytes
205a7af |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
"""Run the TPAMI 2023 Perceptual model.
Run the model of the paper
A Deep Perceptual Measure for Lens and Camera Calibration, TPAMI 2023
https://lvsn.github.io/deepcalib/
through the public Dashboard available at http://rachmaninoff.gel.ulaval.ca:8005.
"""
import argparse
import json
import re
import time
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from tqdm import tqdm
# mypy: ignore-errors
JS_DROP_FILES = "var k=arguments,d=k[0],g=k[1],c=k[2],m=d.ownerDocument||document;for(var e=0;;){var f=d.getBoundingClientRect(),b=f.left+(g||(f.width/2)),a=f.top+(c||(f.height/2)),h=m.elementFromPoint(b,a);if(h&&d.contains(h)){break}if(++e>1){var j=new Error('Element not interactable');j.code=15;throw j}d.scrollIntoView({behavior:'instant',block:'center',inline:'center'})}var l=m.createElement('INPUT');l.setAttribute('type','file');l.setAttribute('multiple','');l.setAttribute('style','position:fixed;z-index:2147483647;left:0;top:0;');l.onchange=function(q){l.parentElement.removeChild(l);q.stopPropagation();var r={constructor:DataTransfer,effectAllowed:'all',dropEffect:'none',types:['Files'],files:l.files,setData:function u(){},getData:function o(){},clearData:function s(){},setDragImage:function i(){}};if(window.DataTransferItemList){r.items=Object.setPrototypeOf(Array.prototype.map.call(l.files,function(x){return{constructor:DataTransferItem,kind:'file',type:x.type,getAsFile:function v(){return x},getAsString:function y(A){var z=new FileReader();z.onload=function(B){A(B.target.result)};z.readAsText(x)},webkitGetAsEntry:function w(){return{constructor:FileSystemFileEntry,name:x.name,fullPath:'/'+x.name,isFile:true,isDirectory:false,file:function z(A){A(x)}}}}}),{constructor:DataTransferItemList,add:function t(){},clear:function p(){},remove:function n(){}})}['dragenter','dragover','drop'].forEach(function(v){var w=m.createEvent('DragEvent');w.initMouseEvent(v,true,true,m.defaultView,0,0,0,b,a,false,false,false,false,0,null);Object.setPrototypeOf(w,null);w.dataTransfer=r;Object.setPrototypeOf(w,DragEvent.prototype);h.dispatchEvent(w)})};m.documentElement.appendChild(l);l.getBoundingClientRect();return l" # noqa E501
def setup_driver():
"""Setup the Selenium browser."""
options = webdriver.FirefoxOptions()
geckodriver_path = "/snap/bin/geckodriver" # specify the path to your geckodriver
driver_service = webdriver.FirefoxService(executable_path=geckodriver_path)
return webdriver.Firefox(options=options, service=driver_service)
def run(args):
"""Run on an image folder."""
driver = setup_driver()
driver.get("http://rachmaninoff.gel.ulaval.ca:8005/")
time.sleep(5)
result_div = driver.find_element(By.ID, "estimated-parameters-display")
def upload_image(path):
path = Path(path).absolute().as_posix()
elem = driver.find_element(By.ID, "dash-uploader")
inp = driver.execute_script(JS_DROP_FILES, elem, 25, 25)
inp._execute("sendKeysToElement", {"value": [path], "text": path})
def run_image(path, prev_result, timeout_seconds=60):
# One main assumption is that subsequent images will have different results
# from each other, otherwise we cannot detect that the inference has completed.
upload_image(path)
started = time.time()
while True:
result = result_div.text
if (result != prev_result) and result:
return result
prev_result = result
if (time.time() - started) > timeout_seconds:
raise TimeoutError
result = str(result_div.text)
number = r"(nan|-?\d*\.?\d*)"
pattern = re.compile(
f"Pitch: {number}° / Roll: {number}° / HFOV : {number}° / Distortion: {number}"
)
paths = sorted(args.images.iterdir())
results = {}
for path in (pbar := tqdm(paths)):
pbar.set_description(path.name)
result = run_image(path, result)
match = pattern.match(result)
if match is None:
print("Error, cannot parse:", result, path)
continue
results[path.name] = tuple(map(float, match.groups()))
args.results.write_text(json.dumps(results))
driver.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("images", type=Path)
parser.add_argument("results", type=Path)
args = parser.parse_args()
run(args)
|