Spaces:
Running on Zero
Running on Zero
| import cv2 | |
| import numpy as np | |
| import torch | |
| import os | |
| import sys | |
| ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) | |
| sys.path.insert(0, ROOT_DIR) | |
| from superpoint import SuperPoint | |
| def resize(img,resize): | |
| img_h,img_w=img.shape[0],img.shape[1] | |
| cur_size=max(img_h,img_w) | |
| if len(resize)==1: | |
| scale1,scale2=resize[0]/cur_size,resize[0]/cur_size | |
| else: | |
| scale1,scale2=resize[0]/img_h,resize[1]/img_w | |
| new_h,new_w=int(img_h*scale1),int(img_w*scale2) | |
| new_img=cv2.resize(img.astype('float32'),(new_w,new_h)).astype('uint8') | |
| scale=np.asarray([scale2,scale1]) | |
| return new_img,scale | |
| class ExtractSIFT: | |
| def __init__(self,config,root=True): | |
| self.num_kp=config['num_kpt'] | |
| self.contrastThreshold=config['det_th'] | |
| self.resize=config['resize'] | |
| self.root=root | |
| def run(self, img_path): | |
| self.sift = cv2.xfeatures2d.SIFT_create(nfeatures=self.num_kp, contrastThreshold=self.contrastThreshold) | |
| img = cv2.imread(img_path,cv2.IMREAD_GRAYSCALE) | |
| scale=[1,1] | |
| if self.resize[0]!=-1: | |
| img,scale=resize(img,self.resize) | |
| cv_kp, desc = self.sift.detectAndCompute(img, None) | |
| kp = np.array([[_kp.pt[0]/scale[1], _kp.pt[1]/scale[0], _kp.response] for _kp in cv_kp]) # N*3 | |
| index=np.flip(np.argsort(kp[:,2])) | |
| kp,desc=kp[index],desc[index] | |
| if self.root: | |
| desc=np.sqrt(abs(desc/(np.linalg.norm(desc,axis=-1,ord=1)[:,np.newaxis]+1e-8))) | |
| return kp[:self.num_kp], desc[:self.num_kp] | |
| class ExtractSuperpoint(object): | |
| def __init__(self,config): | |
| default_config = { | |
| 'descriptor_dim': 256, | |
| 'nms_radius': 4, | |
| 'detection_threshold': config['det_th'], | |
| 'max_keypoints': config['num_kpt'], | |
| 'remove_borders': 4, | |
| 'model_path':'../weights/sp/superpoint_v1.pth' | |
| } | |
| self.superpoint_extractor=SuperPoint(default_config) | |
| self.superpoint_extractor.eval(),self.superpoint_extractor.cuda() | |
| self.num_kp=config['num_kpt'] | |
| if 'padding' in config.keys(): | |
| self.padding=config['padding'] | |
| else: | |
| self.padding=False | |
| self.resize=config['resize'] | |
| def run(self,img_path): | |
| img = cv2.imread(img_path,cv2.IMREAD_GRAYSCALE) | |
| scale=1 | |
| if self.resize[0]!=-1: | |
| img,scale=resize(img,self.resize) | |
| with torch.no_grad(): | |
| result=self.superpoint_extractor(torch.from_numpy(img/255.).float()[None, None].cuda()) | |
| score,kpt,desc=result['scores'][0],result['keypoints'][0],result['descriptors'][0] | |
| score,kpt,desc=score.cpu().numpy(),kpt.cpu().numpy(),desc.cpu().numpy().T | |
| kpt=np.concatenate([kpt/scale,score[:,np.newaxis]],axis=-1) | |
| #padding randomly | |
| if self.padding: | |
| if len(kpt)<self.num_kp: | |
| res=int(self.num_kp-len(kpt)) | |
| pad_x,pad_desc=np.random.uniform(size=[res,2])*(img.shape[0]+img.shape[1])/2,np.random.uniform(size=[res,256]) | |
| pad_kpt,pad_desc=np.concatenate([pad_x,np.zeros([res,1])],axis=-1),pad_desc/np.linalg.norm(pad_desc,axis=-1)[:,np.newaxis] | |
| kpt,desc=np.concatenate([kpt,pad_kpt],axis=0),np.concatenate([desc,pad_desc],axis=0) | |
| return kpt,desc | |