ymp5078 commited on
Commit
e944460
·
verified ·
1 Parent(s): cf1fad8

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +202 -3
README.md CHANGED
@@ -1,3 +1,202 @@
1
- ---
2
- license: cc-by-nc-sa-4.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cc-by-nc-4.0
3
+ tags:
4
+ - ruler-reading
5
+ - image-scale-estimation
6
+ - computer-vision
7
+ - onnx
8
+ - medical-imaging
9
+ ---
10
+
11
+ # RulerNet
12
+
13
+ RulerNet estimates image scale from a visible ruler by detecting centimeter
14
+ marks and fitting them with a geometric progression. It is designed to remain
15
+ robust when a ruler is rotated, viewed in perspective, or partially occluded.
16
+
17
+ This repository accompanies **“RulerNet: Learning Perspective-Invariant Ruler
18
+ Representations for Robust Image Scale Estimation,”** published in
19
+ *Computerized Medical Imaging and Graphics*.
20
+
21
+ Try the interactive CPU demo: [RulerNet-Demo](https://huggingface.co/spaces/ymp5078/RulerNet-Demo).
22
+ For training and evaluation code, see the [GitHub repository](https://github.com/ymp5078/RulerNet).
23
+
24
+ ## Repository contents
25
+
26
+ | Location | Contents | Use |
27
+ | --- | --- | --- |
28
+ | `data/AnyRuler.zip` | AnyRuler images and centimeter-mark annotations (998 MB) | Training and testing |
29
+ | `data/Rulers2023_scale.zip` | Rulers2023 images and centimeter-mark annotations (2.46 GB) | Evaluation |
30
+ | `weights/final_rulernet.zip` | Final RulerNet checkpoint (131 MB) | PyTorch inference, evaluation, or fine-tuning |
31
+ | `weights/final_deepgp.zip` | DeepGP solver checkpoint (112 MB) | Optional faster geometric-progression solving |
32
+ | `weights/pretrained_rulernet.zip` | Synthetic-data pretrained RulerNet checkpoint (158 MB) | Initialize training to reproduce the paper setup |
33
+ | `model.onnx` | CPU-ready ONNX export (57.1 MB) | Lightweight deployment and inference |
34
+
35
+ ## Download files
36
+
37
+ Install the Hugging Face Hub client:
38
+
39
+ ```bash
40
+ pip install -U huggingface_hub
41
+ ```
42
+
43
+ Download individual archives with the CLI:
44
+
45
+ ```bash
46
+ hf download ymp5078/RulerNet data/AnyRuler.zip --local-dir .
47
+ hf download ymp5078/RulerNet data/Rulers2023_scale.zip --local-dir .
48
+ hf download ymp5078/RulerNet weights/final_rulernet.zip --local-dir .
49
+ hf download ymp5078/RulerNet weights/final_deepgp.zip --local-dir .
50
+ hf download ymp5078/RulerNet weights/pretrained_rulernet.zip --local-dir .
51
+ hf download ymp5078/RulerNet model.onnx --local-dir .
52
+ ```
53
+
54
+ Extract an archive before using it:
55
+
56
+ ```bash
57
+ unzip data/AnyRuler.zip -d data/
58
+ unzip weights/final_rulernet.zip -d weights/
59
+ ```
60
+
61
+ ## Datasets
62
+
63
+ ### AnyRuler
64
+
65
+ `AnyRuler.zip` contains 1,416 annotated ruler images. Use it for training or
66
+ for evaluating a model with centimeter-mark labels. After extraction, provide
67
+ the extracted directory to the code repository with `--data-dir`.
68
+
69
+ ```text
70
+ <data-dir>/
71
+ ├── ruler_image/ # input images
72
+ └── cm_marks/ # matching JSON centimeter-mark annotations
73
+ ```
74
+
75
+ ### Rulers2023
76
+
77
+ `Rulers2023_scale.zip` contains the Rulers2023 evaluation images together
78
+ with centimeter-mark annotations. Use it with `--test-dataset ruler2023`.
79
+
80
+ ```text
81
+ <data-dir>/
82
+ ├── real-test/images/ # evaluation images
83
+ └── real-test-marks/ # JSON centimeter-mark annotations
84
+ ```
85
+
86
+ ## PyTorch checkpoints
87
+
88
+ Clone the code repository and install its dependencies before using the
89
+ checkpoints:
90
+
91
+ ```bash
92
+ git clone https://github.com/ymp5078/RulerNet.git
93
+ cd RulerNet
94
+ pip install -r requirements.txt
95
+ ```
96
+
97
+ Use the final RulerNet checkpoint for inference:
98
+
99
+ ```bash
100
+ python inference.py \
101
+ --config configs/config_graphic_gen.yaml \
102
+ --checkpoint <path-to-final_rulernet>/checkpoints/epoch=199-step=20000.ckpt \
103
+ --img-size 768 768 \
104
+ --ruler-mode optimize \
105
+ --image-path <image-or-directory> \
106
+ --result-dir <output-directory>
107
+ ```
108
+
109
+ Append the following option to the inference or evaluation command to use the
110
+ optional learned DeepGP geometric-progression solver:
111
+
112
+ ```bash
113
+ --gp-solver-path <path-to-final_deepgp>/checkpoints/epoch=999-step=1200000.ckpt
114
+ ```
115
+
116
+ To reproduce the pretraining initialization used in the paper, start training
117
+ from the checkpoint in `pretrained_rulernet.zip`:
118
+
119
+ ```bash
120
+ python main.py \
121
+ --config configs/config_pretrain.yaml \
122
+ --data-dir <anyruler-data-dir> \
123
+ --checkpoint <path-to-pretrained_rulernet>/checkpoints/epoch=79-step=128240.ckpt
124
+ ```
125
+
126
+ The synthetic-ruler images used for pretraining are reproducible with
127
+ [`sdxl_inference.py`](https://github.com/ymp5078/RulerNet/blob/main/sdxl_inference.py);
128
+ they are not distributed as a separate archive.
129
+
130
+ ## ONNX inference
131
+
132
+ `model.onnx` is the CPU-ready export used by the [interactive demo](https://huggingface.co/spaces/ymp5078/RulerNet-Demo).
133
+ It expects a float32 tensor named `input` with shape **`(1, 3, 768, 768)`**:
134
+ an RGB image scaled to `[0, 1]`, resized while preserving aspect ratio, and
135
+ zero-padded to 768 × 768.
136
+
137
+ Install the lightweight runtime:
138
+
139
+ ```bash
140
+ pip install -U huggingface_hub onnxruntime numpy pillow
141
+ ```
142
+
143
+ The following example downloads the model, prepares an image exactly as in the
144
+ demo, and runs inference on CPU:
145
+
146
+ ```python
147
+ import numpy as np
148
+ import onnxruntime as ort
149
+ from huggingface_hub import hf_hub_download
150
+ from PIL import Image
151
+
152
+ model_path = hf_hub_download(repo_id="ymp5078/RulerNet", filename="model.onnx")
153
+ session = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
154
+
155
+ def preprocess(image_path):
156
+ image = np.asarray(Image.open(image_path).convert("RGB"), dtype=np.float32) / 255.0
157
+ height, width = image.shape[:2]
158
+ scale = min(768 / width, 768 / height)
159
+ new_width, new_height = int(width * scale), int(height * scale)
160
+
161
+ resized = Image.fromarray((image * 255).astype(np.uint8)).resize((new_width, new_height))
162
+ canvas = np.zeros((768, 768, 3), dtype=np.float32)
163
+ top = (768 - new_height) // 2
164
+ left = (768 - new_width) // 2
165
+ canvas[top:top + new_height, left:left + new_width] = np.asarray(resized) / 255.0
166
+
167
+ return np.transpose(canvas, (2, 0, 1))[None].astype(np.float32), (scale, top, left)
168
+
169
+ input_tensor, transform = preprocess("ruler.jpg")
170
+ init_point, dist, ratio, direction, points_info = session.run(
171
+ None, {"input": input_tensor}
172
+ )
173
+
174
+ print("initial point:", init_point[0])
175
+ print("base distance:", dist[0])
176
+ print("geometric-progression ratio:", ratio[0])
177
+ print("ruler direction:", direction[0])
178
+ print("point count and bounds:", points_info[0])
179
+ ```
180
+
181
+ The five outputs are:
182
+
183
+ | Output | Meaning |
184
+ | --- | --- |
185
+ | `init_point` | Predicted starting ruler-mark location in the 768 × 768 processed image |
186
+ | `dist` | Base distance between generated marks |
187
+ | `ratio` | Geometric-progression ratio between consecutive mark spacings |
188
+ | `direction` | Unit direction vector along the ruler |
189
+ | `points_info` | Number of generated points followed by `[min_x, min_y, max_x, max_y]` valid bounds |
190
+
191
+ To reconstruct the full set of ruler-mark positions and calculate the median
192
+ pixels-per-centimeter value, use the post-processing in the
193
+ [demo implementation](https://huggingface.co/spaces/ymp5078/RulerNet-Demo/blob/main/app.py).
194
+ The resulting coordinates are in the padded 768 × 768 image. To map a point
195
+ `(x, y)` back to the original image, use `(x - left) / scale` and
196
+ `(y - top) / scale`, where `scale`, `top`, and `left` are returned by
197
+ `preprocess`.
198
+
199
+ ## License and commercial use
200
+
201
+ This material is licensed under [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/).
202
+ For commercial-use licensing inquiries, contact [jwang@ist.psu.edu](mailto:jwang@ist.psu.edu).