Hoangthanh commited on
Commit
d8b9fcc
·
1 Parent(s): a46fe5e
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +0 -28
  2. assets/demo.gif +0 -3
  3. assets/gui.jpg +0 -3
  4. assets/logo.webp +0 -0
  5. test_app_cli.py +0 -114
  6. third_party/ALIKE/LICENSE +0 -29
  7. third_party/ALIKE/README.md +0 -131
  8. third_party/ALIKE/alike.py +0 -198
  9. third_party/ALIKE/alnet.py +0 -194
  10. third_party/ALIKE/assets/ALIKE_code.zip +0 -3
  11. third_party/ALIKE/assets/alike.png +0 -3
  12. third_party/ALIKE/assets/kitti.gif +0 -3
  13. third_party/ALIKE/assets/kitti/000100.png +0 -3
  14. third_party/ALIKE/assets/kitti/000101.png +0 -3
  15. third_party/ALIKE/assets/kitti/000102.png +0 -3
  16. third_party/ALIKE/assets/kitti/000103.png +0 -3
  17. third_party/ALIKE/assets/kitti/000104.png +0 -3
  18. third_party/ALIKE/assets/kitti/000105.png +0 -3
  19. third_party/ALIKE/assets/kitti/000106.png +0 -3
  20. third_party/ALIKE/assets/kitti/000107.png +0 -3
  21. third_party/ALIKE/assets/kitti/000108.png +0 -3
  22. third_party/ALIKE/assets/kitti/000109.png +0 -3
  23. third_party/ALIKE/assets/kitti/000110.png +0 -3
  24. third_party/ALIKE/assets/kitti/000111.png +0 -3
  25. third_party/ALIKE/assets/kitti/000112.png +0 -3
  26. third_party/ALIKE/assets/kitti/000113.png +0 -3
  27. third_party/ALIKE/assets/kitti/000114.png +0 -3
  28. third_party/ALIKE/assets/kitti/000115.png +0 -3
  29. third_party/ALIKE/assets/kitti/000116.png +0 -3
  30. third_party/ALIKE/assets/kitti/000117.png +0 -3
  31. third_party/ALIKE/assets/kitti/000118.png +0 -3
  32. third_party/ALIKE/assets/kitti/000119.png +0 -3
  33. third_party/ALIKE/assets/tum.gif +0 -3
  34. third_party/ALIKE/assets/tum/1311868169.163498.png +0 -3
  35. third_party/ALIKE/assets/tum/1311868169.263274.png +0 -3
  36. third_party/ALIKE/assets/tum/1311868169.363470.png +0 -3
  37. third_party/ALIKE/assets/tum/1311868169.463229.png +0 -3
  38. third_party/ALIKE/assets/tum/1311868169.563501.png +0 -3
  39. third_party/ALIKE/assets/tum/1311868169.663240.png +0 -3
  40. third_party/ALIKE/assets/tum/1311868169.763417.png +0 -3
  41. third_party/ALIKE/assets/tum/1311868169.863396.png +0 -3
  42. third_party/ALIKE/assets/tum/1311868169.963415.png +0 -3
  43. third_party/ALIKE/assets/tum/1311868170.063469.png +0 -3
  44. third_party/ALIKE/assets/tum/1311868170.163416.png +0 -3
  45. third_party/ALIKE/assets/tum/1311868170.263521.png +0 -3
  46. third_party/ALIKE/assets/tum/1311868170.363400.png +0 -3
  47. third_party/ALIKE/assets/tum/1311868170.463383.png +0 -3
  48. third_party/ALIKE/assets/tum/1311868170.563345.png +0 -3
  49. third_party/ALIKE/assets/tum/1311868170.663430.png +0 -3
  50. third_party/ALIKE/assets/tum/1311868170.763453.png +0 -3
app.py DELETED
@@ -1,28 +0,0 @@
1
- import argparse
2
- from pathlib import Path
3
- from common.app_class import ImageMatchingApp
4
-
5
- if __name__ == "__main__":
6
- parser = argparse.ArgumentParser()
7
- parser.add_argument(
8
- "--server_name",
9
- type=str,
10
- default="0.0.0.0",
11
- help="server name",
12
- )
13
- parser.add_argument(
14
- "--server_port",
15
- type=int,
16
- default=7860,
17
- help="server port",
18
- )
19
- parser.add_argument(
20
- "--config",
21
- type=str,
22
- default=Path(__file__).parent / "common/config.yaml",
23
- help="config file",
24
- )
25
- args = parser.parse_args()
26
- ImageMatchingApp(
27
- args.server_name, args.server_port, config=args.config
28
- ).run()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/demo.gif DELETED

Git LFS Details

  • SHA256: 3f163c0e2699181897c81c68e01c60fa4289e886a2a40932d53dd529262d3735
  • Pointer size: 132 Bytes
  • Size of remote file: 8.91 MB
assets/gui.jpg DELETED

Git LFS Details

  • SHA256: a783162639d05631f34e8e3e9a7df682197a76f675265ebbaa639927e08473f7
  • Pointer size: 132 Bytes
  • Size of remote file: 1.67 MB
assets/logo.webp DELETED
Binary file (404 kB)
 
test_app_cli.py DELETED
@@ -1,114 +0,0 @@
1
- import cv2
2
- import warnings
3
- import numpy as np
4
- from pathlib import Path
5
- from hloc import logger
6
- from common.utils import (
7
- get_matcher_zoo,
8
- load_config,
9
- DEVICE,
10
- ROOT,
11
- )
12
- from common.api import ImageMatchingAPI
13
-
14
-
15
- def test_all(config: dict = None):
16
- img_path1 = ROOT / "datasets/sacre_coeur/mapping/02928139_3448003521.jpg"
17
- img_path2 = ROOT / "datasets/sacre_coeur/mapping/17295357_9106075285.jpg"
18
- image0 = cv2.imread(str(img_path1))[:, :, ::-1] # RGB
19
- image1 = cv2.imread(str(img_path2))[:, :, ::-1] # RGB
20
-
21
- matcher_zoo_restored = get_matcher_zoo(config["matcher_zoo"])
22
- for k, v in matcher_zoo_restored.items():
23
- if image0 is None or image1 is None:
24
- logger.error("Error: No images found! Please upload two images.")
25
- enable = config["matcher_zoo"][k].get("enable", True)
26
- skip_ci = config["matcher_zoo"][k].get("skip_ci", False)
27
- if enable and not skip_ci:
28
- logger.info(f"Testing {k} ...")
29
- api = ImageMatchingAPI(conf=v, device=DEVICE)
30
- api(image0, image1)
31
- log_path = ROOT / "experiments" / "all"
32
- log_path.mkdir(exist_ok=True, parents=True)
33
- api.visualize(log_path=log_path)
34
- else:
35
- logger.info(f"Skipping {k} ...")
36
- return 0
37
-
38
-
39
- def test_one():
40
- img_path1 = ROOT / "datasets/sacre_coeur/mapping/02928139_3448003521.jpg"
41
- img_path2 = ROOT / "datasets/sacre_coeur/mapping/17295357_9106075285.jpg"
42
- image0 = cv2.imread(str(img_path1))[:, :, ::-1] # RGB
43
- image1 = cv2.imread(str(img_path2))[:, :, ::-1] # RGB
44
- # sparse
45
- conf = {
46
- "feature": {
47
- "output": "feats-superpoint-n4096-rmax1600",
48
- "model": {
49
- "name": "superpoint",
50
- "nms_radius": 3,
51
- "max_keypoints": 4096,
52
- "keypoint_threshold": 0.005,
53
- },
54
- "preprocessing": {
55
- "grayscale": True,
56
- "force_resize": True,
57
- "resize_max": 1600,
58
- "width": 640,
59
- "height": 480,
60
- "dfactor": 8,
61
- },
62
- },
63
- "matcher": {
64
- "output": "matches-NN-mutual",
65
- "model": {
66
- "name": "nearest_neighbor",
67
- "do_mutual_check": True,
68
- "match_threshold": 0.2,
69
- },
70
- },
71
- "dense": False,
72
- }
73
- api = ImageMatchingAPI(conf=conf, device=DEVICE)
74
- api(image0, image1)
75
- log_path = ROOT / "experiments" / "one"
76
- log_path.mkdir(exist_ok=True, parents=True)
77
- api.visualize(log_path=log_path)
78
-
79
- # dense
80
- conf = {
81
- "matcher": {
82
- "output": "matches-loftr",
83
- "model": {
84
- "name": "loftr",
85
- "weights": "outdoor",
86
- "max_keypoints": 2000,
87
- "match_threshold": 0.2,
88
- },
89
- "preprocessing": {
90
- "grayscale": True,
91
- "resize_max": 1024,
92
- "dfactor": 8,
93
- "width": 640,
94
- "height": 480,
95
- "force_resize": True,
96
- },
97
- "max_error": 1,
98
- "cell_size": 1,
99
- },
100
- "dense": True,
101
- }
102
-
103
- api = ImageMatchingAPI(conf=conf, device=DEVICE)
104
- api(image0, image1)
105
- log_path = ROOT / "experiments" / "one"
106
- log_path.mkdir(exist_ok=True, parents=True)
107
- api.visualize(log_path=log_path)
108
- return 0
109
-
110
-
111
- if __name__ == "__main__":
112
- config = load_config(ROOT / "common/config.yaml")
113
- test_one()
114
- test_all(config)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
third_party/ALIKE/LICENSE DELETED
@@ -1,29 +0,0 @@
1
- BSD 3-Clause License
2
-
3
- Copyright (c) 2022, Zhao Xiaoming
4
- All rights reserved.
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted provided that the following conditions are met:
8
-
9
- 1. Redistributions of source code must retain the above copyright notice, this
10
- list of conditions and the following disclaimer.
11
-
12
- 2. Redistributions in binary form must reproduce the above copyright notice,
13
- this list of conditions and the following disclaimer in the documentation
14
- and/or other materials provided with the distribution.
15
-
16
- 3. Neither the name of the copyright holder nor the names of its
17
- contributors may be used to endorse or promote products derived from
18
- this software without specific prior written permission.
19
-
20
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
third_party/ALIKE/README.md DELETED
@@ -1,131 +0,0 @@
1
- # News
2
-
3
- - The [ALIKED](https://github.com/Shiaoming/ALIKED) is released.
4
- - The [ALIKE training code](https://github.com/Shiaoming/ALIKE/raw/main/assets/ALIKE_code.zip) is released.
5
-
6
- # ALIKE: Accurate and Lightweight Keypoint Detection and Descriptor Extraction
7
-
8
- ALIKE applies a differentiable keypoint detection module to detect accurate sub-pixel keypoints. The network can run at 95 frames per second for 640 x 480 images on NVIDIA Titan X (Pascal) GPU and achieve equivalent performance with the state-of-the-arts. ALIKE benefits real-time applications in resource-limited platforms/devices. Technical details are described in [this paper](https://arxiv.org/pdf/2112.02906.pdf).
9
-
10
- > ```
11
- > Xiaoming Zhao, Xingming Wu, Jinyu Miao, Weihai Chen, Peter C. Y. Chen, Zhengguo Li, "ALIKE: Accurate and Lightweight Keypoint
12
- > Detection and Descriptor Extraction," IEEE Transactions on Multimedia, 2022.
13
- > ```
14
-
15
- ![](./assets/alike.png)
16
-
17
-
18
- If you use ALIKE in an academic work, please cite:
19
-
20
- ```
21
- @article{Zhao2023ALIKED,
22
- title = {ALIKED: A Lighter Keypoint and Descriptor Extraction Network via Deformable Transformation},
23
- url = {https://arxiv.org/pdf/2304.03608.pdf},
24
- doi = {10.1109/TIM.2023.3271000},
25
- journal = {IEEE Transactions on Instrumentation & Measurement},
26
- author = {Zhao, Xiaoming and Wu, Xingming and Chen, Weihai and Chen, Peter C. Y. and Xu, Qingsong and Li, Zhengguo},
27
- year = {2023},
28
- volume = {72},
29
- pages = {1-16},
30
- }
31
-
32
- @article{Zhao2022ALIKE,
33
- title = {ALIKE: Accurate and Lightweight Keypoint Detection and Descriptor Extraction},
34
- url = {http://arxiv.org/abs/2112.02906},
35
- doi = {10.1109/TMM.2022.3155927},
36
- journal = {IEEE Transactions on Multimedia},
37
- author = {Zhao, Xiaoming and Wu, Xingming and Miao, Jinyu and Chen, Weihai and Chen, Peter C. Y. and Li, Zhengguo},
38
- month = march,
39
- year = {2022},
40
- }
41
- ```
42
-
43
-
44
-
45
- ## 1. Prerequisites
46
-
47
- The required packages are listed in the `requirements.txt` :
48
-
49
- ```shell
50
- pip install -r requirements.txt
51
- ```
52
-
53
-
54
-
55
- ## 2. Models
56
-
57
- The off-the-shelf weights of four variant ALIKE models are provided in `models/` .
58
-
59
-
60
-
61
- ## 3. Run demo
62
-
63
- ```shell
64
- $ python demo.py -h
65
- usage: demo.py [-h] [--model {alike-t,alike-s,alike-n,alike-l}]
66
- [--device DEVICE] [--top_k TOP_K] [--scores_th SCORES_TH]
67
- [--n_limit N_LIMIT] [--no_display] [--no_sub_pixel]
68
- input
69
-
70
- ALike Demo.
71
-
72
- positional arguments:
73
- input Image directory or movie file or "camera0" (for
74
- webcam0).
75
-
76
- optional arguments:
77
- -h, --help show this help message and exit
78
- --model {alike-t,alike-s,alike-n,alike-l}
79
- The model configuration
80
- --device DEVICE Running device (default: cuda).
81
- --top_k TOP_K Detect top K keypoints. -1 for threshold based mode,
82
- >0 for top K mode. (default: -1)
83
- --scores_th SCORES_TH
84
- Detector score threshold (default: 0.2).
85
- --n_limit N_LIMIT Maximum number of keypoints to be detected (default:
86
- 5000).
87
- --no_display Do not display images to screen. Useful if running
88
- remotely (default: False).
89
- --no_sub_pixel Do not detect sub-pixel keypoints (default: False).
90
- ```
91
-
92
-
93
-
94
- ## 4. Examples
95
-
96
- ### KITTI example
97
- ```shell
98
- python demo.py assets/kitti
99
- ```
100
- ![](./assets/kitti.gif)
101
-
102
- ### TUM example
103
- ```shell
104
- python demo.py assets/tum
105
- ```
106
- ![](./assets/tum.gif)
107
-
108
- ## 5. Efficiency and performance
109
-
110
- | Models | Parameters | GFLOPs(640x480) | MHA@3 on Hpatches | mAA(10°) on [IMW2020-test](https://www.cs.ubc.ca/research/image-matching-challenge/2021/leaderboard) (Stereo) |
111
- |:---:|:---:|:---:|:-----------------:|:-------------------------------------------------------------------------------------------------------------:|
112
- | D2-Net(MS) | 7653KB | 889.40 | 38.33% | 12.27% |
113
- | LF-Net(MS) | 2642KB | 24.37 | 57.78% | 23.44% |
114
- | SuperPoint | 1301KB | 26.11 | 70.19% | 28.97% |
115
- | R2D2(MS) | 484KB | 464.55 | 71.48% | 39.02% |
116
- | ASLFeat(MS) | 823KB | 77.58 | 73.52% | 33.65% |
117
- | DISK | 1092KB | 98.97 | 70.56% | 51.22% |
118
- | ALike-N | 318KB | 7.909 | 75.74% | 47.18% |
119
- | ALike-L | 653KB | 19.685 | 76.85% | 49.58% |
120
-
121
- ### Evaluation on Hpatches
122
-
123
- - Download [hpatches-sequences-release](https://hpatches.github.io/) and put it into `hseq/hpatches-sequences-release`.
124
- - Remove the unreliable sequences as D2-Net.
125
- - Run the following command to evaluate the performance:
126
- ```shell
127
- python hseq/eval.py
128
- ```
129
-
130
-
131
- For more details, please refer to the [paper](https://arxiv.org/abs/2112.02906).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
third_party/ALIKE/alike.py DELETED
@@ -1,198 +0,0 @@
1
- import logging
2
- import os
3
- import cv2
4
- import torch
5
- from copy import deepcopy
6
- import torch.nn.functional as F
7
- from torchvision.transforms import ToTensor
8
- import math
9
-
10
- from alnet import ALNet
11
- from soft_detect import DKD
12
- import time
13
-
14
- configs = {
15
- "alike-t": {
16
- "c1": 8,
17
- "c2": 16,
18
- "c3": 32,
19
- "c4": 64,
20
- "dim": 64,
21
- "single_head": True,
22
- "radius": 2,
23
- "model_path": os.path.join(os.path.split(__file__)[0], "models", "alike-t.pth"),
24
- },
25
- "alike-s": {
26
- "c1": 8,
27
- "c2": 16,
28
- "c3": 48,
29
- "c4": 96,
30
- "dim": 96,
31
- "single_head": True,
32
- "radius": 2,
33
- "model_path": os.path.join(os.path.split(__file__)[0], "models", "alike-s.pth"),
34
- },
35
- "alike-n": {
36
- "c1": 16,
37
- "c2": 32,
38
- "c3": 64,
39
- "c4": 128,
40
- "dim": 128,
41
- "single_head": True,
42
- "radius": 2,
43
- "model_path": os.path.join(os.path.split(__file__)[0], "models", "alike-n.pth"),
44
- },
45
- "alike-l": {
46
- "c1": 32,
47
- "c2": 64,
48
- "c3": 128,
49
- "c4": 128,
50
- "dim": 128,
51
- "single_head": False,
52
- "radius": 2,
53
- "model_path": os.path.join(os.path.split(__file__)[0], "models", "alike-l.pth"),
54
- },
55
- }
56
-
57
-
58
- class ALike(ALNet):
59
- def __init__(
60
- self,
61
- # ================================== feature encoder
62
- c1: int = 32,
63
- c2: int = 64,
64
- c3: int = 128,
65
- c4: int = 128,
66
- dim: int = 128,
67
- single_head: bool = False,
68
- # ================================== detect parameters
69
- radius: int = 2,
70
- top_k: int = 500,
71
- scores_th: float = 0.5,
72
- n_limit: int = 5000,
73
- device: str = "cpu",
74
- model_path: str = "",
75
- ):
76
- super().__init__(c1, c2, c3, c4, dim, single_head)
77
- self.radius = radius
78
- self.top_k = top_k
79
- self.n_limit = n_limit
80
- self.scores_th = scores_th
81
- self.dkd = DKD(
82
- radius=self.radius,
83
- top_k=self.top_k,
84
- scores_th=self.scores_th,
85
- n_limit=self.n_limit,
86
- )
87
- self.device = device
88
-
89
- if model_path != "":
90
- state_dict = torch.load(model_path, self.device)
91
- self.load_state_dict(state_dict)
92
- self.to(self.device)
93
- self.eval()
94
- logging.info(f"Loaded model parameters from {model_path}")
95
- logging.info(
96
- f"Number of model parameters: {sum(p.numel() for p in self.parameters() if p.requires_grad) / 1e3}KB"
97
- )
98
-
99
- def extract_dense_map(self, image, ret_dict=False):
100
- # ====================================================
101
- # check image size, should be integer multiples of 2^5
102
- # if it is not a integer multiples of 2^5, padding zeros
103
- device = image.device
104
- b, c, h, w = image.shape
105
- h_ = math.ceil(h / 32) * 32 if h % 32 != 0 else h
106
- w_ = math.ceil(w / 32) * 32 if w % 32 != 0 else w
107
- if h_ != h:
108
- h_padding = torch.zeros(b, c, h_ - h, w, device=device)
109
- image = torch.cat([image, h_padding], dim=2)
110
- if w_ != w:
111
- w_padding = torch.zeros(b, c, h_, w_ - w, device=device)
112
- image = torch.cat([image, w_padding], dim=3)
113
- # ====================================================
114
-
115
- scores_map, descriptor_map = super().forward(image)
116
-
117
- # ====================================================
118
- if h_ != h or w_ != w:
119
- descriptor_map = descriptor_map[:, :, :h, :w]
120
- scores_map = scores_map[:, :, :h, :w] # Bx1xHxW
121
- # ====================================================
122
-
123
- # BxCxHxW
124
- descriptor_map = torch.nn.functional.normalize(descriptor_map, p=2, dim=1)
125
-
126
- if ret_dict:
127
- return {
128
- "descriptor_map": descriptor_map,
129
- "scores_map": scores_map,
130
- }
131
- else:
132
- return descriptor_map, scores_map
133
-
134
- def forward(self, img, image_size_max=99999, sort=False, sub_pixel=False):
135
- """
136
- :param img: np.array HxWx3, RGB
137
- :param image_size_max: maximum image size, otherwise, the image will be resized
138
- :param sort: sort keypoints by scores
139
- :param sub_pixel: whether to use sub-pixel accuracy
140
- :return: a dictionary with 'keypoints', 'descriptors', 'scores', and 'time'
141
- """
142
- H, W, three = img.shape
143
- assert three == 3, "input image shape should be [HxWx3]"
144
-
145
- # ==================== image size constraint
146
- image = deepcopy(img)
147
- max_hw = max(H, W)
148
- if max_hw > image_size_max:
149
- ratio = float(image_size_max / max_hw)
150
- image = cv2.resize(image, dsize=None, fx=ratio, fy=ratio)
151
-
152
- # ==================== convert image to tensor
153
- image = (
154
- torch.from_numpy(image)
155
- .to(self.device)
156
- .to(torch.float32)
157
- .permute(2, 0, 1)[None]
158
- / 255.0
159
- )
160
-
161
- # ==================== extract keypoints
162
- start = time.time()
163
-
164
- with torch.no_grad():
165
- descriptor_map, scores_map = self.extract_dense_map(image)
166
- keypoints, descriptors, scores, _ = self.dkd(
167
- scores_map, descriptor_map, sub_pixel=sub_pixel
168
- )
169
- keypoints, descriptors, scores = keypoints[0], descriptors[0], scores[0]
170
- keypoints = (keypoints + 1) / 2 * keypoints.new_tensor([[W - 1, H - 1]])
171
-
172
- if sort:
173
- indices = torch.argsort(scores, descending=True)
174
- keypoints = keypoints[indices]
175
- descriptors = descriptors[indices]
176
- scores = scores[indices]
177
-
178
- end = time.time()
179
-
180
- return {
181
- "keypoints": keypoints.cpu().numpy(),
182
- "descriptors": descriptors.cpu().numpy(),
183
- "scores": scores.cpu().numpy(),
184
- "scores_map": scores_map.cpu().numpy(),
185
- "time": end - start,
186
- }
187
-
188
-
189
- if __name__ == "__main__":
190
- import numpy as np
191
- from thop import profile
192
-
193
- net = ALike(c1=32, c2=64, c3=128, c4=128, dim=128, single_head=False)
194
-
195
- image = np.random.random((640, 480, 3)).astype(np.float32)
196
- flops, params = profile(net, inputs=(image, 9999, False), verbose=False)
197
- print("{:<30} {:<8} GFLops".format("Computational complexity: ", flops / 1e9))
198
- print("{:<30} {:<8} KB".format("Number of parameters: ", params / 1e3))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
third_party/ALIKE/alnet.py DELETED
@@ -1,194 +0,0 @@
1
- import torch
2
- from torch import nn
3
- from torchvision.models import resnet
4
- from typing import Optional, Callable
5
-
6
-
7
- class ConvBlock(nn.Module):
8
- def __init__(
9
- self,
10
- in_channels,
11
- out_channels,
12
- gate: Optional[Callable[..., nn.Module]] = None,
13
- norm_layer: Optional[Callable[..., nn.Module]] = None,
14
- ):
15
- super().__init__()
16
- if gate is None:
17
- self.gate = nn.ReLU(inplace=True)
18
- else:
19
- self.gate = gate
20
- if norm_layer is None:
21
- norm_layer = nn.BatchNorm2d
22
- self.conv1 = resnet.conv3x3(in_channels, out_channels)
23
- self.bn1 = norm_layer(out_channels)
24
- self.conv2 = resnet.conv3x3(out_channels, out_channels)
25
- self.bn2 = norm_layer(out_channels)
26
-
27
- def forward(self, x):
28
- x = self.gate(self.bn1(self.conv1(x))) # B x in_channels x H x W
29
- x = self.gate(self.bn2(self.conv2(x))) # B x out_channels x H x W
30
- return x
31
-
32
-
33
- # copied from torchvision\models\resnet.py#27->BasicBlock
34
- class ResBlock(nn.Module):
35
- expansion: int = 1
36
-
37
- def __init__(
38
- self,
39
- inplanes: int,
40
- planes: int,
41
- stride: int = 1,
42
- downsample: Optional[nn.Module] = None,
43
- groups: int = 1,
44
- base_width: int = 64,
45
- dilation: int = 1,
46
- gate: Optional[Callable[..., nn.Module]] = None,
47
- norm_layer: Optional[Callable[..., nn.Module]] = None,
48
- ) -> None:
49
- super(ResBlock, self).__init__()
50
- if gate is None:
51
- self.gate = nn.ReLU(inplace=True)
52
- else:
53
- self.gate = gate
54
- if norm_layer is None:
55
- norm_layer = nn.BatchNorm2d
56
- if groups != 1 or base_width != 64:
57
- raise ValueError("ResBlock only supports groups=1 and base_width=64")
58
- if dilation > 1:
59
- raise NotImplementedError("Dilation > 1 not supported in ResBlock")
60
- # Both self.conv1 and self.downsample layers downsample the input when stride != 1
61
- self.conv1 = resnet.conv3x3(inplanes, planes, stride)
62
- self.bn1 = norm_layer(planes)
63
- self.conv2 = resnet.conv3x3(planes, planes)
64
- self.bn2 = norm_layer(planes)
65
- self.downsample = downsample
66
- self.stride = stride
67
-
68
- def forward(self, x: torch.Tensor) -> torch.Tensor:
69
- identity = x
70
-
71
- out = self.conv1(x)
72
- out = self.bn1(out)
73
- out = self.gate(out)
74
-
75
- out = self.conv2(out)
76
- out = self.bn2(out)
77
-
78
- if self.downsample is not None:
79
- identity = self.downsample(x)
80
-
81
- out += identity
82
- out = self.gate(out)
83
-
84
- return out
85
-
86
-
87
- class ALNet(nn.Module):
88
- def __init__(
89
- self,
90
- c1: int = 32,
91
- c2: int = 64,
92
- c3: int = 128,
93
- c4: int = 128,
94
- dim: int = 128,
95
- single_head: bool = True,
96
- ):
97
- super().__init__()
98
-
99
- self.gate = nn.ReLU(inplace=True)
100
-
101
- self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
102
- self.pool4 = nn.MaxPool2d(kernel_size=4, stride=4)
103
-
104
- self.block1 = ConvBlock(3, c1, self.gate, nn.BatchNorm2d)
105
-
106
- self.block2 = ResBlock(
107
- inplanes=c1,
108
- planes=c2,
109
- stride=1,
110
- downsample=nn.Conv2d(c1, c2, 1),
111
- gate=self.gate,
112
- norm_layer=nn.BatchNorm2d,
113
- )
114
- self.block3 = ResBlock(
115
- inplanes=c2,
116
- planes=c3,
117
- stride=1,
118
- downsample=nn.Conv2d(c2, c3, 1),
119
- gate=self.gate,
120
- norm_layer=nn.BatchNorm2d,
121
- )
122
- self.block4 = ResBlock(
123
- inplanes=c3,
124
- planes=c4,
125
- stride=1,
126
- downsample=nn.Conv2d(c3, c4, 1),
127
- gate=self.gate,
128
- norm_layer=nn.BatchNorm2d,
129
- )
130
-
131
- # ================================== feature aggregation
132
- self.conv1 = resnet.conv1x1(c1, dim // 4)
133
- self.conv2 = resnet.conv1x1(c2, dim // 4)
134
- self.conv3 = resnet.conv1x1(c3, dim // 4)
135
- self.conv4 = resnet.conv1x1(dim, dim // 4)
136
- self.upsample2 = nn.Upsample(
137
- scale_factor=2, mode="bilinear", align_corners=True
138
- )
139
- self.upsample4 = nn.Upsample(
140
- scale_factor=4, mode="bilinear", align_corners=True
141
- )
142
- self.upsample8 = nn.Upsample(
143
- scale_factor=8, mode="bilinear", align_corners=True
144
- )
145
- self.upsample32 = nn.Upsample(
146
- scale_factor=32, mode="bilinear", align_corners=True
147
- )
148
-
149
- # ================================== detector and descriptor head
150
- self.single_head = single_head
151
- if not self.single_head:
152
- self.convhead1 = resnet.conv1x1(dim, dim)
153
- self.convhead2 = resnet.conv1x1(dim, dim + 1)
154
-
155
- def forward(self, image):
156
- # ================================== feature encoder
157
- x1 = self.block1(image) # B x c1 x H x W
158
- x2 = self.pool2(x1)
159
- x2 = self.block2(x2) # B x c2 x H/2 x W/2
160
- x3 = self.pool4(x2)
161
- x3 = self.block3(x3) # B x c3 x H/8 x W/8
162
- x4 = self.pool4(x3)
163
- x4 = self.block4(x4) # B x dim x H/32 x W/32
164
-
165
- # ================================== feature aggregation
166
- x1 = self.gate(self.conv1(x1)) # B x dim//4 x H x W
167
- x2 = self.gate(self.conv2(x2)) # B x dim//4 x H//2 x W//2
168
- x3 = self.gate(self.conv3(x3)) # B x dim//4 x H//8 x W//8
169
- x4 = self.gate(self.conv4(x4)) # B x dim//4 x H//32 x W//32
170
- x2_up = self.upsample2(x2) # B x dim//4 x H x W
171
- x3_up = self.upsample8(x3) # B x dim//4 x H x W
172
- x4_up = self.upsample32(x4) # B x dim//4 x H x W
173
- x1234 = torch.cat([x1, x2_up, x3_up, x4_up], dim=1)
174
-
175
- # ================================== detector and descriptor head
176
- if not self.single_head:
177
- x1234 = self.gate(self.convhead1(x1234))
178
- x = self.convhead2(x1234) # B x dim+1 x H x W
179
-
180
- descriptor_map = x[:, :-1, :, :]
181
- scores_map = torch.sigmoid(x[:, -1, :, :]).unsqueeze(1)
182
-
183
- return scores_map, descriptor_map
184
-
185
-
186
- if __name__ == "__main__":
187
- from thop import profile
188
-
189
- net = ALNet(c1=16, c2=32, c3=64, c4=128, dim=128, single_head=True)
190
-
191
- image = torch.randn(1, 3, 640, 480)
192
- flops, params = profile(net, inputs=(image,), verbose=False)
193
- print("{:<30} {:<8} GFLops".format("Computational complexity: ", flops / 1e9))
194
- print("{:<30} {:<8} KB".format("Number of parameters: ", params / 1e3))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
third_party/ALIKE/assets/ALIKE_code.zip DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:891e8431c047e7aeed77c9e5f64ffeed262d92389d8ae6235dde0964a9048a08
3
- size 62774
 
 
 
 
third_party/ALIKE/assets/alike.png DELETED

Git LFS Details

  • SHA256: d35e59f8e4d9c34b0e2686ecd5ca5414fe975b81553e4968eccc4bff1535c2d4
  • Pointer size: 131 Bytes
  • Size of remote file: 162 kB
third_party/ALIKE/assets/kitti.gif DELETED

Git LFS Details

  • SHA256: 0b05e4dc0000b9abf53183a3ebdfc0b95a92513952e235ea24f27f2945389ea1
  • Pointer size: 132 Bytes
  • Size of remote file: 7.03 MB
third_party/ALIKE/assets/kitti/000100.png DELETED

Git LFS Details

  • SHA256: c8d4a81ad91c7945cabd15de286aacf27ab661163b5eee0177128721782d5405
  • Pointer size: 131 Bytes
  • Size of remote file: 273 kB
third_party/ALIKE/assets/kitti/000101.png DELETED

Git LFS Details

  • SHA256: 539c684432726e903191a2471c8dae8c4b0012b88e1b3af7590de08c24890327
  • Pointer size: 131 Bytes
  • Size of remote file: 272 kB
third_party/ALIKE/assets/kitti/000102.png DELETED

Git LFS Details

  • SHA256: 5bbc9a5b04bd425a5e146f3ba114027041086477a5fa123a50463932ab62617e
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
third_party/ALIKE/assets/kitti/000103.png DELETED

Git LFS Details

  • SHA256: 2041e633aeb85022b1222277cace17132bed09ca19856d1e6787984b05d61339
  • Pointer size: 131 Bytes
  • Size of remote file: 271 kB
third_party/ALIKE/assets/kitti/000104.png DELETED

Git LFS Details

  • SHA256: 6ca8a30c0edb7d2c6d6e5c2f5317bdffdae2269157d69e71f9602e0bbf2090ab
  • Pointer size: 131 Bytes
  • Size of remote file: 271 kB
third_party/ALIKE/assets/kitti/000105.png DELETED

Git LFS Details

  • SHA256: b8bca67672e8b2181b193f0577a9a3b42b64df9bb57d98608dbdbb54e79925bd
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
third_party/ALIKE/assets/kitti/000106.png DELETED

Git LFS Details

  • SHA256: 2ccc83d57703afdcda4afd746dd99458b425fbc11ce3155583abde25e988e389
  • Pointer size: 131 Bytes
  • Size of remote file: 269 kB
third_party/ALIKE/assets/kitti/000107.png DELETED

Git LFS Details

  • SHA256: 980f4c74ac9117020f954cc75718cf0a09baeb30894aea123db59f9e4555ecef
  • Pointer size: 131 Bytes
  • Size of remote file: 269 kB
third_party/ALIKE/assets/kitti/000108.png DELETED

Git LFS Details

  • SHA256: c7c2234c8ba8c056c452a0d625db6eac09c8963b0c5e8a5d0b1c3af15a4b7516
  • Pointer size: 131 Bytes
  • Size of remote file: 271 kB
third_party/ALIKE/assets/kitti/000109.png DELETED

Git LFS Details

  • SHA256: 6a34b9639806e7deefe1cb24ae7b376343d394d2d032f95e763e4b6921cd61c7
  • Pointer size: 131 Bytes
  • Size of remote file: 276 kB
third_party/ALIKE/assets/kitti/000110.png DELETED

Git LFS Details

  • SHA256: 6af1b3e55b9c1eac208c887c44592f93e8ae7cc0196acaa2639c265f8bf959e3
  • Pointer size: 131 Bytes
  • Size of remote file: 275 kB
third_party/ALIKE/assets/kitti/000111.png DELETED

Git LFS Details

  • SHA256: 215ed5306f4976458110836a620dcf55030d8dd20618e6365d60176988c1cfa6
  • Pointer size: 131 Bytes
  • Size of remote file: 276 kB
third_party/ALIKE/assets/kitti/000112.png DELETED

Git LFS Details

  • SHA256: 8a265252457871d4dd2f17c42eafa1c0da99df90d103c653c8097aad26073d22
  • Pointer size: 131 Bytes
  • Size of remote file: 276 kB
third_party/ALIKE/assets/kitti/000113.png DELETED

Git LFS Details

  • SHA256: c83f220b29b5d04ead44c9304f9eccde3a4ff4e60627d7014f8fe424afb873f4
  • Pointer size: 131 Bytes
  • Size of remote file: 276 kB
third_party/ALIKE/assets/kitti/000114.png DELETED

Git LFS Details

  • SHA256: 1abad021db35c21f2e9ac0ce7e54a5721eec3ff32bc4ce820f5b7091af4d6fac
  • Pointer size: 131 Bytes
  • Size of remote file: 276 kB
third_party/ALIKE/assets/kitti/000115.png DELETED

Git LFS Details

  • SHA256: 6be815b2b0aa8aa3dc47e314ed6645eeb474996e9a920fab2abe8a35fb3ea089
  • Pointer size: 131 Bytes
  • Size of remote file: 274 kB
third_party/ALIKE/assets/kitti/000116.png DELETED

Git LFS Details

  • SHA256: 96b8df04ee570d877a04e43f1f4c30abc7e7383b24ce70a1a83a82dcbd863293
  • Pointer size: 131 Bytes
  • Size of remote file: 271 kB
third_party/ALIKE/assets/kitti/000117.png DELETED

Git LFS Details

  • SHA256: f32567394c096442df0c768822af1e21f2163f373eec94b7a36f2941ae08b199
  • Pointer size: 131 Bytes
  • Size of remote file: 267 kB
third_party/ALIKE/assets/kitti/000118.png DELETED

Git LFS Details

  • SHA256: b76476a8856d33960302b29cbd339c8bc513c52e7b81b21ba7d9f07dd0e4b096
  • Pointer size: 131 Bytes
  • Size of remote file: 268 kB
third_party/ALIKE/assets/kitti/000119.png DELETED

Git LFS Details

  • SHA256: c818d19b8a1ce7051b006361bc14f638d8df2989b0bba8a96472e8551e02e5d1
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
third_party/ALIKE/assets/tum.gif DELETED

Git LFS Details

  • SHA256: df6ecf9666386bfa5925c8e57d196f15c077d550eb84dd392f5f49b90e86a5dc
  • Pointer size: 132 Bytes
  • Size of remote file: 4.04 MB
third_party/ALIKE/assets/tum/1311868169.163498.png DELETED

Git LFS Details

  • SHA256: 20bc06c1249727c16efc812082454bc8305438f756bcc95f913b9f79819f08e3
  • Pointer size: 131 Bytes
  • Size of remote file: 512 kB
third_party/ALIKE/assets/tum/1311868169.263274.png DELETED

Git LFS Details

  • SHA256: 0954d005c8f9ab146718f52601136c513b96a4414b0a0cbc02a01184686fb01e
  • Pointer size: 131 Bytes
  • Size of remote file: 516 kB
third_party/ALIKE/assets/tum/1311868169.363470.png DELETED

Git LFS Details

  • SHA256: 1d2681bb2b8a907d53469d9e67f6d1809b9ec435ec210622bf255c66c8918efd
  • Pointer size: 131 Bytes
  • Size of remote file: 506 kB
third_party/ALIKE/assets/tum/1311868169.463229.png DELETED

Git LFS Details

  • SHA256: ba2cd89601523665d0bee9dd3ea2117d9249e7ea4c7b43753298c1bab74cd532
  • Pointer size: 131 Bytes
  • Size of remote file: 509 kB
third_party/ALIKE/assets/tum/1311868169.563501.png DELETED

Git LFS Details

  • SHA256: 0a0239c7cb08fefbe4f5ec87f1c5e5fd5a32be11349744dc45158caa7d403744
  • Pointer size: 131 Bytes
  • Size of remote file: 526 kB
third_party/ALIKE/assets/tum/1311868169.663240.png DELETED

Git LFS Details

  • SHA256: 6e538c9dbaf4242072949920b3105ccdcfac68af955d623a701b9eea0e6e0f6f
  • Pointer size: 131 Bytes
  • Size of remote file: 521 kB
third_party/ALIKE/assets/tum/1311868169.763417.png DELETED

Git LFS Details

  • SHA256: 22a4fadfc031c36efd4cee5f70d0b501557bf820fa4b39a1c77f4268d0c12e86
  • Pointer size: 131 Bytes
  • Size of remote file: 544 kB
third_party/ALIKE/assets/tum/1311868169.863396.png DELETED

Git LFS Details

  • SHA256: eae0ee5be82b14aa1ed19e0b20a72bc37964c64732c7016739a5b30158453049
  • Pointer size: 131 Bytes
  • Size of remote file: 549 kB
third_party/ALIKE/assets/tum/1311868169.963415.png DELETED

Git LFS Details

  • SHA256: a590b6fdb98c4a4ee8e13aafcd9d2392c78a7881b4cc7fd1109231adc3cc8b91
  • Pointer size: 131 Bytes
  • Size of remote file: 541 kB
third_party/ALIKE/assets/tum/1311868170.063469.png DELETED

Git LFS Details

  • SHA256: 3d2d6058e036b307efa7d6008a02103b9c31ed8d0edd4b2f1e9ad49717b89684
  • Pointer size: 131 Bytes
  • Size of remote file: 550 kB
third_party/ALIKE/assets/tum/1311868170.163416.png DELETED

Git LFS Details

  • SHA256: 741d1e0ede775dd4b7054314c1a95ed3e5116792245b9eb1a5e2492ffe4d935c
  • Pointer size: 131 Bytes
  • Size of remote file: 550 kB
third_party/ALIKE/assets/tum/1311868170.263521.png DELETED

Git LFS Details

  • SHA256: 04ce12ed16c6fa89a9fdb3b64e7471335d13b82b84c7a554b3f9fd08f6e254a0
  • Pointer size: 131 Bytes
  • Size of remote file: 546 kB
third_party/ALIKE/assets/tum/1311868170.363400.png DELETED

Git LFS Details

  • SHA256: fb6be184df6fd2ca2e287bc64ada937ce2cec3f5d90e15c244fffa8aa44b11b1
  • Pointer size: 131 Bytes
  • Size of remote file: 545 kB
third_party/ALIKE/assets/tum/1311868170.463383.png DELETED

Git LFS Details

  • SHA256: d82953d4580894111f15a5b57e0059dca0baf02e788e0726a2849647cf570b63
  • Pointer size: 131 Bytes
  • Size of remote file: 542 kB
third_party/ALIKE/assets/tum/1311868170.563345.png DELETED

Git LFS Details

  • SHA256: d498847d7b8bc2389550941b01e95b1bf6459c70ff645d9893637d59e129ae29
  • Pointer size: 131 Bytes
  • Size of remote file: 549 kB
third_party/ALIKE/assets/tum/1311868170.663430.png DELETED

Git LFS Details

  • SHA256: b299c55e430afecb9f5d0ff6e1485ce72d90f5ddf1ec1a186fbcb2b110e035f2
  • Pointer size: 131 Bytes
  • Size of remote file: 541 kB
third_party/ALIKE/assets/tum/1311868170.763453.png DELETED

Git LFS Details

  • SHA256: 8073cc59711d6bea5038b698fb74eaa72eeca663dcc35850e0b334e234605385
  • Pointer size: 131 Bytes
  • Size of remote file: 541 kB