├── .gitignore
├── LICENSE
├── README.md
├── app.py
├── assets
├── axis.obj
├── axis.png
└── demo.png
├── inference.py
├── paths.py
├── render
├── __init__.py
├── canvas.py
├── core.py
├── model.py
└── speedup.py
├── requirements.txt
├── utils.py
└── vision_tower.py
/.gitignore:
--------------------------------------------------------------------------------
1 | **/__pycache__
2 | .gradio
3 | .locks
4 | models*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution 4.0 International Public License
58 |
59 | By exercising the Licensed Rights (defined below), You accept and agree
60 | to be bound by the terms and conditions of this Creative Commons
61 | Attribution 4.0 International Public License ("Public License"). To the
62 | extent this Public License may be interpreted as a contract, You are
63 | granted the Licensed Rights in consideration of Your acceptance of
64 | these terms and conditions, and the Licensor grants You such rights in
65 | consideration of benefits the Licensor receives from making the
66 | Licensed Material available under these terms and conditions.
67 |
68 |
69 | Section 1 -- Definitions.
70 |
71 | a. Adapted Material means material subject to Copyright and Similar
72 | Rights that is derived from or based upon the Licensed Material
73 | and in which the Licensed Material is translated, altered,
74 | arranged, transformed, or otherwise modified in a manner requiring
75 | permission under the Copyright and Similar Rights held by the
76 | Licensor. For purposes of this Public License, where the Licensed
77 | Material is a musical work, performance, or sound recording,
78 | Adapted Material is always produced where the Licensed Material is
79 | synched in timed relation with a moving image.
80 |
81 | b. Adapter's License means the license You apply to Your Copyright
82 | and Similar Rights in Your contributions to Adapted Material in
83 | accordance with the terms and conditions of this Public License.
84 |
85 | c. Copyright and Similar Rights means copyright and/or similar rights
86 | closely related to copyright including, without limitation,
87 | performance, broadcast, sound recording, and Sui Generis Database
88 | Rights, without regard to how the rights are labeled or
89 | categorized. For purposes of this Public License, the rights
90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
91 | Rights.
92 |
93 | d. Effective Technological Measures means those measures that, in the
94 | absence of proper authority, may not be circumvented under laws
95 | fulfilling obligations under Article 11 of the WIPO Copyright
96 | Treaty adopted on December 20, 1996, and/or similar international
97 | agreements.
98 |
99 | e. Exceptions and Limitations means fair use, fair dealing, and/or
100 | any other exception or limitation to Copyright and Similar Rights
101 | that applies to Your use of the Licensed Material.
102 |
103 | f. Licensed Material means the artistic or literary work, database,
104 | or other material to which the Licensor applied this Public
105 | License.
106 |
107 | g. Licensed Rights means the rights granted to You subject to the
108 | terms and conditions of this Public License, which are limited to
109 | all Copyright and Similar Rights that apply to Your use of the
110 | Licensed Material and that the Licensor has authority to license.
111 |
112 | h. Licensor means the individual(s) or entity(ies) granting rights
113 | under this Public License.
114 |
115 | i. Share means to provide material to the public by any means or
116 | process that requires permission under the Licensed Rights, such
117 | as reproduction, public display, public performance, distribution,
118 | dissemination, communication, or importation, and to make material
119 | available to the public including in ways that members of the
120 | public may access the material from a place and at a time
121 | individually chosen by them.
122 |
123 | j. Sui Generis Database Rights means rights other than copyright
124 | resulting from Directive 96/9/EC of the European Parliament and of
125 | the Council of 11 March 1996 on the legal protection of databases,
126 | as amended and/or succeeded, as well as other essentially
127 | equivalent rights anywhere in the world.
128 |
129 | k. You means the individual or entity exercising the Licensed Rights
130 | under this Public License. Your has a corresponding meaning.
131 |
132 |
133 | Section 2 -- Scope.
134 |
135 | a. License grant.
136 |
137 | 1. Subject to the terms and conditions of this Public License,
138 | the Licensor hereby grants You a worldwide, royalty-free,
139 | non-sublicensable, non-exclusive, irrevocable license to
140 | exercise the Licensed Rights in the Licensed Material to:
141 |
142 | a. reproduce and Share the Licensed Material, in whole or
143 | in part; and
144 |
145 | b. produce, reproduce, and Share Adapted Material.
146 |
147 | 2. Exceptions and Limitations. For the avoidance of doubt, where
148 | Exceptions and Limitations apply to Your use, this Public
149 | License does not apply, and You do not need to comply with
150 | its terms and conditions.
151 |
152 | 3. Term. The term of this Public License is specified in Section
153 | 6(a).
154 |
155 | 4. Media and formats; technical modifications allowed. The
156 | Licensor authorizes You to exercise the Licensed Rights in
157 | all media and formats whether now known or hereafter created,
158 | and to make technical modifications necessary to do so. The
159 | Licensor waives and/or agrees not to assert any right or
160 | authority to forbid You from making technical modifications
161 | necessary to exercise the Licensed Rights, including
162 | technical modifications necessary to circumvent Effective
163 | Technological Measures. For purposes of this Public License,
164 | simply making modifications authorized by this Section 2(a)
165 | (4) never produces Adapted Material.
166 |
167 | 5. Downstream recipients.
168 |
169 | a. Offer from the Licensor -- Licensed Material. Every
170 | recipient of the Licensed Material automatically
171 | receives an offer from the Licensor to exercise the
172 | Licensed Rights under the terms and conditions of this
173 | Public License.
174 |
175 | b. No downstream restrictions. You may not offer or impose
176 | any additional or different terms or conditions on, or
177 | apply any Effective Technological Measures to, the
178 | Licensed Material if doing so restricts exercise of the
179 | Licensed Rights by any recipient of the Licensed
180 | Material.
181 |
182 | 6. No endorsement. Nothing in this Public License constitutes or
183 | may be construed as permission to assert or imply that You
184 | are, or that Your use of the Licensed Material is, connected
185 | with, or sponsored, endorsed, or granted official status by,
186 | the Licensor or others designated to receive attribution as
187 | provided in Section 3(a)(1)(A)(i).
188 |
189 | b. Other rights.
190 |
191 | 1. Moral rights, such as the right of integrity, are not
192 | licensed under this Public License, nor are publicity,
193 | privacy, and/or other similar personality rights; however, to
194 | the extent possible, the Licensor waives and/or agrees not to
195 | assert any such rights held by the Licensor to the limited
196 | extent necessary to allow You to exercise the Licensed
197 | Rights, but not otherwise.
198 |
199 | 2. Patent and trademark rights are not licensed under this
200 | Public License.
201 |
202 | 3. To the extent possible, the Licensor waives any right to
203 | collect royalties from You for the exercise of the Licensed
204 | Rights, whether directly or through a collecting society
205 | under any voluntary or waivable statutory or compulsory
206 | licensing scheme. In all other cases the Licensor expressly
207 | reserves any right to collect such royalties.
208 |
209 |
210 | Section 3 -- License Conditions.
211 |
212 | Your exercise of the Licensed Rights is expressly made subject to the
213 | following conditions.
214 |
215 | a. Attribution.
216 |
217 | 1. If You Share the Licensed Material (including in modified
218 | form), You must:
219 |
220 | a. retain the following if it is supplied by the Licensor
221 | with the Licensed Material:
222 |
223 | i. identification of the creator(s) of the Licensed
224 | Material and any others designated to receive
225 | attribution, in any reasonable manner requested by
226 | the Licensor (including by pseudonym if
227 | designated);
228 |
229 | ii. a copyright notice;
230 |
231 | iii. a notice that refers to this Public License;
232 |
233 | iv. a notice that refers to the disclaimer of
234 | warranties;
235 |
236 | v. a URI or hyperlink to the Licensed Material to the
237 | extent reasonably practicable;
238 |
239 | b. indicate if You modified the Licensed Material and
240 | retain an indication of any previous modifications; and
241 |
242 | c. indicate the Licensed Material is licensed under this
243 | Public License, and include the text of, or the URI or
244 | hyperlink to, this Public License.
245 |
246 | 2. You may satisfy the conditions in Section 3(a)(1) in any
247 | reasonable manner based on the medium, means, and context in
248 | which You Share the Licensed Material. For example, it may be
249 | reasonable to satisfy the conditions by providing a URI or
250 | hyperlink to a resource that includes the required
251 | information.
252 |
253 | 3. If requested by the Licensor, You must remove any of the
254 | information required by Section 3(a)(1)(A) to the extent
255 | reasonably practicable.
256 |
257 | 4. If You Share Adapted Material You produce, the Adapter's
258 | License You apply must not prevent recipients of the Adapted
259 | Material from complying with this Public License.
260 |
261 |
262 | Section 4 -- Sui Generis Database Rights.
263 |
264 | Where the Licensed Rights include Sui Generis Database Rights that
265 | apply to Your use of the Licensed Material:
266 |
267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
268 | to extract, reuse, reproduce, and Share all or a substantial
269 | portion of the contents of the database;
270 |
271 | b. if You include all or a substantial portion of the database
272 | contents in a database in which You have Sui Generis Database
273 | Rights, then the database in which You have Sui Generis Database
274 | Rights (but not its individual contents) is Adapted Material; and
275 |
276 | c. You must comply with the conditions in Section 3(a) if You Share
277 | all or a substantial portion of the contents of the database.
278 |
279 | For the avoidance of doubt, this Section 4 supplements and does not
280 | replace Your obligations under this Public License where the Licensed
281 | Rights include other Copyright and Similar Rights.
282 |
283 |
284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
285 |
286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
296 |
297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
306 |
307 | c. The disclaimer of warranties and limitation of liability provided
308 | above shall be interpreted in a manner that, to the extent
309 | possible, most closely approximates an absolute disclaimer and
310 | waiver of all liability.
311 |
312 |
313 | Section 6 -- Term and Termination.
314 |
315 | a. This Public License applies for the term of the Copyright and
316 | Similar Rights licensed here. However, if You fail to comply with
317 | this Public License, then Your rights under this Public License
318 | terminate automatically.
319 |
320 | b. Where Your right to use the Licensed Material has terminated under
321 | Section 6(a), it reinstates:
322 |
323 | 1. automatically as of the date the violation is cured, provided
324 | it is cured within 30 days of Your discovery of the
325 | violation; or
326 |
327 | 2. upon express reinstatement by the Licensor.
328 |
329 | For the avoidance of doubt, this Section 6(b) does not affect any
330 | right the Licensor may have to seek remedies for Your violations
331 | of this Public License.
332 |
333 | c. For the avoidance of doubt, the Licensor may also offer the
334 | Licensed Material under separate terms or conditions or stop
335 | distributing the Licensed Material at any time; however, doing so
336 | will not terminate this Public License.
337 |
338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
339 | License.
340 |
341 |
342 | Section 7 -- Other Terms and Conditions.
343 |
344 | a. The Licensor shall not be bound by any additional or different
345 | terms or conditions communicated by You unless expressly agreed.
346 |
347 | b. Any arrangements, understandings, or agreements regarding the
348 | Licensed Material not stated herein are separate from and
349 | independent of the terms and conditions of this Public License.
350 |
351 |
352 | Section 8 -- Interpretation.
353 |
354 | a. For the avoidance of doubt, this Public License does not, and
355 | shall not be interpreted to, reduce, limit, restrict, or impose
356 | conditions on any use of the Licensed Material that could lawfully
357 | be made without permission under this Public License.
358 |
359 | b. To the extent possible, if any provision of this Public License is
360 | deemed unenforceable, it shall be automatically reformed to the
361 | minimum extent necessary to make it enforceable. If the provision
362 | cannot be reformed, it shall be severed from this Public License
363 | without affecting the enforceability of the remaining terms and
364 | conditions.
365 |
366 | c. No term or condition of this Public License will be waived and no
367 | failure to comply consented to unless expressly agreed to by the
368 | Licensor.
369 |
370 | d. Nothing in this Public License constitutes or may be interpreted
371 | as a limitation upon, or waiver of, any privileges and immunities
372 | that apply to the Licensor or You, including from the legal
373 | processes of any jurisdiction or authority.
374 |
375 |
376 | =======================================================================
377 |
378 | Creative Commons is not a party to its public
379 | licenses. Notwithstanding, Creative Commons may elect to apply one of
380 | its public licenses to material it publishes and in those instances
381 | will be considered the “Licensor.” The text of the Creative Commons
382 | public licenses is dedicated to the public domain under the CC0 Public
383 | Domain Dedication. Except for the limited purpose of indicating that
384 | material is shared under a Creative Commons public license or as
385 | otherwise permitted by the Creative Commons policies published at
386 | creativecommons.org/policies, Creative Commons does not authorize the
387 | use of the trademark "Creative Commons" or any other trademark or logo
388 | of Creative Commons without its prior written consent including,
389 | without limitation, in connection with any unauthorized modifications
390 | to any of its public licenses or any other arrangements,
391 | understandings, or agreements concerning use of licensed material. For
392 | the avoidance of doubt, this paragraph does not form part of the
393 | public licenses.
394 |
395 | Creative Commons may be contacted at creativecommons.org.
396 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Orient Anything: Learning Robust Object Orientation Estimation from Rendering 3D Models
3 |
4 | [**Zehan Wang**](https://scholar.google.com/citations?user=euXK0lkAAAAJ&hl=zh-CN)
1* · [**Ziang Zhang**](https://scholar.google.com/citations?hl=zh-CN&user=DptGMnYAAAAJ)
1* · [**Tianyu Pang**](https://scholar.google.com/citations?hl=zh-CN&user=wYDbtFsAAAAJ)
2 · [**Du Chao**](https://scholar.google.com/citations?hl=zh-CN&user=QOp7xW0AAAAJ)
2 · [**Hengshuang Zhao**](https://scholar.google.com/citations?user=4uE10I0AAAAJ&hl&oi=ao)
3 · [**Zhou Zhao**](https://scholar.google.com/citations?user=IIoFY90AAAAJ&hl&oi=ao)
1
5 |
6 |
1Zhejiang University
2SEA AI Lab
3HKU
7 |
8 | *Equal Contribution
9 |
10 |
11 |

12 |

13 |

14 |

15 |
16 |
17 | **Orient Anything**, a robust image-based object orientation estimation model. By training on 2M rendered labeled images, it achieves strong zero-shot generalization ability for images in the wild.
18 |
19 | 
20 |
21 | ## News
22 | * **2025-05-01:** Orient Anything is accepted by ICML 2025!
23 | * **2024-12-24:** [Paper](https://arxiv.org/abs/2412.18605), [Project Page](https://orient-anything.github.io), [Code](https://github.com/SpatialVision/Orient-Anything), Models, and [Demo](https://huggingface.co/spaces/Viglong/Orient-Anything) are released.
24 |
25 |
26 |
27 | ## Pre-trained models
28 |
29 | We provide **three models** of varying scales for robust object orientation estimation in images:
30 |
31 | | Model | Params | Checkpoint |
32 | |:-|-:|:-:|
33 | | Orient-Anything-Small | 23.3 M | [Download](https://huggingface.co/Viglong/OriNet/blob/main/cropsmallEx03/dino_weight.pt) |
34 | | Orient-Anything-Base | 87.8 M | [Download](https://huggingface.co/Viglong/OriNet/blob/main/cropbaseEx032/dino_weight.pt) |
35 | | Orient-Anything-Large | 305 M | [Download](https://huggingface.co/Viglong/OriNet/blob/main/croplargeEX2/dino_weight.pt) |
36 |
37 | ## Usage
38 |
39 | ### 1 Prepraration
40 |
41 | ```bash
42 | pip install -r requirements.txt
43 | ```
44 |
45 | ### 2 Use our models
46 | #### 2.1 In Gradio app
47 | Start gradio by executing the following script:
48 |
49 | ```bash
50 | python app.py
51 | ```
52 | then open GUI page(default is https://127.0.0.1:7860) in web browser.
53 |
54 | or, you can try it in our [Huggingface-Space](https://huggingface.co/spaces/Viglong/Orient-Anything)
55 |
56 | #### 2.2 In Python Scripts
57 | ```python
58 | from paths import *
59 | from vision_tower import DINOv2_MLP
60 | from transformers import AutoImageProcessor
61 | import torch
62 | from PIL import Image
63 |
64 | import torch.nn.functional as F
65 | from utils import *
66 | from inference import *
67 |
68 | from huggingface_hub import hf_hub_download
69 | ckpt_path = hf_hub_download(repo_id="Viglong/Orient-Anything", filename="croplargeEX2/dino_weight.pt", repo_type="model", cache_dir='./', resume_download=True)
70 | print(ckpt_path)
71 |
72 | save_path = './'
73 | device = 'cuda' if torch.cuda.is_available() else 'cpu'
74 | dino = DINOv2_MLP(
75 | dino_mode = 'large',
76 | in_dim = 1024,
77 | out_dim = 360+180+180+2,
78 | evaluate = True,
79 | mask_dino = False,
80 | frozen_back = False
81 | )
82 |
83 | dino.eval()
84 | print('model create')
85 | dino.load_state_dict(torch.load(ckpt_path, map_location='cpu'))
86 | dino = dino.to(device)
87 | print('weight loaded')
88 | val_preprocess = AutoImageProcessor.from_pretrained(DINO_LARGE, cache_dir='./')
89 |
90 | image_path = '/path/to/image'
91 | origin_image = Image.open(image_path).convert('RGB')
92 | angles = get_3angle(origin_image, dino, val_preprocess, device)
93 | azimuth = float(angles[0])
94 | polar = float(angles[1])
95 | rotation = float(angles[2])
96 | confidence = float(angles[3])
97 |
98 |
99 | ```
100 |
101 |
102 | ### Best Practice
103 | To avoid ambiguity, our model only supports inputs that contain images of a single object. For daily images that usually contain multiple objects, it is a good choice to isolate each object with DINO-grounding and predict the orientation separately.
104 | ```python
105 | [ToDo]
106 | ```
107 | ### Test-Time Augmentation
108 | In order to further enhance the robustness of the model,We further propose the test-time ensemble strategy. The input images will be randomly cropped into different variants, and the predicted orientation of different variants will be voted as the final prediction result. We implement this strategy in functions `get_3angle_infer_aug()` and `get_crop_images()`.
109 |
110 | ## Citation
111 |
112 | If you find this project useful, please consider citing:
113 |
114 | ```bibtex
115 | @article{orient_anything,
116 | title={Orient Anything: Learning Robust Object Orientation Estimation from Rendering 3D Models},
117 | author={Wang, Zehan and Zhang, Ziang and Pang, Tianyu and Du, Chao and Zhao, Hengshuang and Zhao, Zhou},
118 | journal={arXiv:2412.18605},
119 | year={2024}
120 | }
121 | ```
122 |
123 | ## Acknowledgement
124 | Thanks to the open source of the following projects: [Grounded-Segment-Anything](https://github.com/IDEA-Research/Grounded-Segment-Anything), [render-py](https://github.com/tvytlx/render-py)
125 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import gradio as gr
2 | from paths import *
3 |
4 | from vision_tower import DINOv2_MLP
5 | from transformers import AutoImageProcessor
6 | import torch
7 | from inference import *
8 | from utils import *
9 |
10 | from huggingface_hub import hf_hub_download
11 | ckpt_path = hf_hub_download(repo_id="Viglong/Orient-Anything", filename="croplargeEX2/dino_weight.pt", repo_type="model", cache_dir='./', resume_download=True)
12 | print(ckpt_path)
13 |
14 | save_path = './'
15 | device = 'cpu'
16 | dino = DINOv2_MLP(
17 | dino_mode = 'large',
18 | in_dim = 1024,
19 | out_dim = 360+180+180+2,
20 | evaluate = True,
21 | mask_dino = False,
22 | frozen_back = False
23 | )
24 |
25 | dino.eval()
26 | print('model create')
27 | dino.load_state_dict(torch.load(ckpt_path, map_location='cpu'))
28 | dino = dino.to(device)
29 | print('weight loaded')
30 | val_preprocess = AutoImageProcessor.from_pretrained(DINO_LARGE, cache_dir='./')
31 |
32 | def infer_func(img, do_rm_bkg, do_infer_aug):
33 | origin_img = Image.fromarray(img)
34 | if do_infer_aug:
35 | rm_bkg_img = background_preprocess(origin_img, True)
36 | angles = get_3angle_infer_aug(origin_img, rm_bkg_img, dino, val_preprocess, device)
37 | else:
38 | rm_bkg_img = background_preprocess(origin_img, do_rm_bkg)
39 | angles = get_3angle(rm_bkg_img, dino, val_preprocess, device)
40 |
41 | phi = np.radians(angles[0])
42 | theta = np.radians(angles[1])
43 | gamma = angles[2]
44 | confidence = float(angles[3])
45 | if confidence > 0.5:
46 | render_axis = render_3D_axis(phi, theta, gamma)
47 | res_img = overlay_images_with_scaling(render_axis, rm_bkg_img)
48 | else:
49 | res_img = img
50 |
51 | # axis_model = "axis.obj"
52 | return [res_img, round(float(angles[0]), 2), round(float(angles[1]), 2), round(float(angles[2]), 2), round(float(angles[3]), 2)]
53 |
54 | server = gr.Interface(
55 | flagging_mode='never',
56 | fn=infer_func,
57 | inputs=[
58 | gr.Image(height=512, width=512, label="upload your image"),
59 | gr.Checkbox(label="Remove Background", value=True),
60 | gr.Checkbox(label="Inference time augmentation", value=False)
61 | ],
62 | outputs=[
63 | gr.Image(height=512, width=512, label="result image"),
64 | # gr.Model3D(clear_color=[0.0, 0.0, 0.0, 0.0], label="3D Model"),
65 | gr.Textbox(lines=1, label='Azimuth(0~360°)'),
66 | gr.Textbox(lines=1, label='Polar(-90~90°)'),
67 | gr.Textbox(lines=1, label='Rotation(-90~90°)'),
68 | gr.Textbox(lines=1, label='Confidence(0~1)')
69 | ]
70 | )
71 |
72 | server.launch()
73 |
--------------------------------------------------------------------------------
/assets/axis.obj:
--------------------------------------------------------------------------------
1 | # Blender 4.2.1 LTS
2 | # www.blender.org
3 | mtllib axis.mtl
4 | o X
5 | v 28.000000 0.000000 0.000000
6 | v 22.000000 0.292636 -1.471178
7 | v 22.000000 0.574025 -1.385819
8 | v 22.000000 0.833355 -1.247204
9 | v 22.000000 1.060660 -1.060660
10 | v 22.000000 1.247205 -0.833355
11 | v 22.000000 1.385819 -0.574025
12 | v 22.000000 1.471178 -0.292636
13 | v 22.000000 1.500000 -0.000000
14 | v 22.000000 1.471178 0.292636
15 | v 22.000000 1.385819 0.574025
16 | v 22.000000 1.247205 0.833355
17 | v 22.000000 1.060660 1.060660
18 | v 22.000000 0.833355 1.247204
19 | v 22.000000 0.574025 1.385819
20 | v 22.000000 0.292636 1.471178
21 | v 22.000000 0.000000 1.500000
22 | v 22.000000 -0.292635 1.471178
23 | v 22.000000 -0.574025 1.385819
24 | v 22.000000 -0.833355 1.247204
25 | v 22.000000 -1.060660 1.060660
26 | v 22.000000 -1.247204 0.833355
27 | v 22.000000 -1.385819 0.574025
28 | v 22.000000 -1.471178 0.292636
29 | v 22.000000 -1.500000 0.000000
30 | v 22.000000 -1.471178 -0.292636
31 | v 22.000000 -1.385819 -0.574025
32 | v 22.000000 -1.247204 -0.833355
33 | v 22.000000 -1.060660 -1.060660
34 | v 22.000000 -0.833355 -1.247204
35 | v 22.000000 -0.574025 -1.385819
36 | v 22.000000 -0.292635 -1.471178
37 | v 22.000000 -0.000000 -1.500000
38 | vn -1.0000 -0.0000 -0.0000
39 | vn -1.0000 0.0001 -0.0000
40 | vn -1.0000 -0.0001 -0.0000
41 | vn 0.2414 0.0951 -0.9657
42 | vn 0.2414 0.2817 -0.9286
43 | vn 0.2414 0.4575 -0.8558
44 | vn 0.2414 0.6156 -0.7501
45 | vn 0.2414 0.7501 -0.6156
46 | vn 0.2414 0.8558 -0.4574
47 | vn 0.2414 0.9286 -0.2817
48 | vn 0.2414 0.9657 -0.0951
49 | vn 0.2414 0.9657 0.0951
50 | vn 0.2414 0.9286 0.2817
51 | vn 0.2414 0.8558 0.4574
52 | vn 0.2414 0.7501 0.6156
53 | vn 0.2414 0.6156 0.7501
54 | vn 0.2414 0.4575 0.8558
55 | vn 0.2414 0.2817 0.9286
56 | vn 0.2414 0.0951 0.9657
57 | vn 0.2414 -0.0951 0.9657
58 | vn 0.2414 -0.2817 0.9286
59 | vn 0.2414 -0.4575 0.8558
60 | vn 0.2414 -0.6156 0.7501
61 | vn 0.2414 -0.7501 0.6156
62 | vn 0.2414 -0.8558 0.4575
63 | vn 0.2414 -0.9286 0.2817
64 | vn 0.2414 -0.9657 0.0951
65 | vn 0.2414 -0.9657 -0.0951
66 | vn 0.2414 -0.9286 -0.2817
67 | vn 0.2414 -0.8558 -0.4575
68 | vn 0.2414 -0.7501 -0.6156
69 | vn 0.2414 -0.6156 -0.7501
70 | vn 0.2414 -0.4575 -0.8558
71 | vn 0.2414 -0.2817 -0.9286
72 | vn 0.2414 -0.0951 -0.9657
73 | vt 0.597858 0.736041
74 | vt 0.735114 0.644330
75 | vt 0.643402 0.507074
76 | vt 0.506147 0.598785
77 | vt 0.523575 0.686407
78 | vt 0.555780 0.524503
79 | vt 0.717685 0.556707
80 | vt 0.685480 0.718612
81 | vt 0.555780 0.718612
82 | vt 0.506147 0.644330
83 | vt 0.523575 0.556707
84 | vt 0.597858 0.507074
85 | vt 0.685480 0.524503
86 | vt 0.735114 0.598785
87 | vt 0.717685 0.686407
88 | vt 0.643402 0.736041
89 | vt 0.575961 0.729399
90 | vt 0.538092 0.704096
91 | vt 0.512789 0.666227
92 | vt 0.503903 0.621557
93 | vt 0.512789 0.576888
94 | vt 0.538092 0.539019
95 | vt 0.575961 0.513716
96 | vt 0.620630 0.504831
97 | vt 0.665299 0.513716
98 | vt 0.703168 0.539019
99 | vt 0.728471 0.576888
100 | vt 0.737357 0.621557
101 | vt 0.728471 0.666227
102 | vt 0.703168 0.704096
103 | vt 0.665299 0.729399
104 | vt 0.620630 0.738284
105 | vt 0.354677 0.736041
106 | vt 0.377450 0.621557
107 | vt 0.377450 0.738284
108 | vt 0.332780 0.729399
109 | vt 0.312600 0.718612
110 | vt 0.294911 0.704096
111 | vt 0.280395 0.686407
112 | vt 0.269608 0.666227
113 | vt 0.262966 0.644330
114 | vt 0.260723 0.621557
115 | vt 0.262966 0.598785
116 | vt 0.269608 0.576888
117 | vt 0.280395 0.556707
118 | vt 0.294911 0.539019
119 | vt 0.312600 0.524503
120 | vt 0.332780 0.513716
121 | vt 0.354677 0.507074
122 | vt 0.377450 0.504831
123 | vt 0.400222 0.507074
124 | vt 0.422119 0.513716
125 | vt 0.442299 0.524503
126 | vt 0.459988 0.539019
127 | vt 0.474504 0.556707
128 | vt 0.485291 0.576888
129 | vt 0.491933 0.598785
130 | vt 0.494176 0.621557
131 | vt 0.491933 0.644330
132 | vt 0.485291 0.666227
133 | vt 0.474504 0.686407
134 | vt 0.459988 0.704096
135 | vt 0.442299 0.718612
136 | vt 0.422119 0.729399
137 | vt 0.400222 0.736041
138 | s 0
139 | usemtl MI_YamahaMSP3_MatteBlack.004
140 | f 2/1/1 26/2/1 18/3/1
141 | f 10/4/1 6/5/1 2/1/1
142 | f 18/3/1 14/6/1 10/4/1
143 | f 26/2/1 22/7/1 18/3/1
144 | f 2/1/1 30/8/1 26/2/1
145 | f 6/5/1 4/9/1 2/1/1
146 | f 10/4/1 8/10/1 6/5/1
147 | f 14/6/1 12/11/1 10/4/1
148 | f 18/3/1 16/12/1 14/6/1
149 | f 22/7/1 20/13/1 18/3/1
150 | f 26/2/1 24/14/1 22/7/1
151 | f 30/8/1 28/15/1 26/2/1
152 | f 2/1/1 32/16/1 30/8/1
153 | f 4/9/1 3/17/1 2/1/1
154 | f 6/5/2 5/18/2 4/9/2
155 | f 8/10/3 7/19/3 6/5/3
156 | f 10/4/1 9/20/1 8/10/1
157 | f 12/11/3 11/21/3 10/4/3
158 | f 14/6/2 13/22/2 12/11/2
159 | f 16/12/1 15/23/1 14/6/1
160 | f 18/3/1 17/24/1 16/12/1
161 | f 20/13/1 19/25/1 18/3/1
162 | f 22/7/3 21/26/3 20/13/3
163 | f 24/14/2 23/27/2 22/7/2
164 | f 26/2/1 25/28/1 24/14/1
165 | f 28/15/2 27/29/2 26/2/2
166 | f 30/8/3 29/30/3 28/15/3
167 | f 32/16/1 31/31/1 30/8/1
168 | f 2/1/1 33/32/1 32/16/1
169 | f 2/33/4 1/34/4 33/35/4
170 | f 3/36/5 1/34/5 2/33/5
171 | f 18/3/1 10/4/1 2/1/1
172 | f 4/37/6 1/34/6 3/36/6
173 | f 5/38/7 1/34/7 4/37/7
174 | f 6/39/8 1/34/8 5/38/8
175 | f 7/40/9 1/34/9 6/39/9
176 | f 8/41/10 1/34/10 7/40/10
177 | f 9/42/11 1/34/11 8/41/11
178 | f 10/43/12 1/34/12 9/42/12
179 | f 11/44/13 1/34/13 10/43/13
180 | f 12/45/14 1/34/14 11/44/14
181 | f 13/46/15 1/34/15 12/45/15
182 | f 14/47/16 1/34/16 13/46/16
183 | f 15/48/17 1/34/17 14/47/17
184 | f 16/49/18 1/34/18 15/48/18
185 | f 17/50/19 1/34/19 16/49/19
186 | f 18/51/20 1/34/20 17/50/20
187 | f 19/52/21 1/34/21 18/51/21
188 | f 20/53/22 1/34/22 19/52/22
189 | f 21/54/23 1/34/23 20/53/23
190 | f 22/55/24 1/34/24 21/54/24
191 | f 23/56/25 1/34/25 22/55/25
192 | f 24/57/26 1/34/26 23/56/26
193 | f 25/58/27 1/34/27 24/57/27
194 | f 26/59/28 1/34/28 25/58/28
195 | f 27/60/29 1/34/29 26/59/29
196 | f 28/61/30 1/34/30 27/60/30
197 | f 29/62/31 1/34/31 28/61/31
198 | f 30/63/32 1/34/32 29/62/32
199 | f 31/64/33 1/34/33 30/63/33
200 | f 32/65/34 1/34/34 31/64/34
201 | f 33/35/35 1/34/35 32/65/35
202 | o Xzhu
203 | v 24.000000 0.097545 -0.490393
204 | v 0.000000 0.097546 -0.490393
205 | v 24.000000 0.191341 -0.461940
206 | v 0.000000 0.191342 -0.461940
207 | v 24.000000 0.277785 -0.415735
208 | v 0.000000 0.277786 -0.415735
209 | v 24.000000 0.353553 -0.353553
210 | v 0.000000 0.353554 -0.353553
211 | v 24.000000 0.415734 -0.277785
212 | v 0.000000 0.415735 -0.277785
213 | v 24.000000 0.461939 -0.191342
214 | v 0.000000 0.461940 -0.191342
215 | v 24.000000 0.490392 -0.097545
216 | v 0.000000 0.490393 -0.097545
217 | v 24.000000 0.499999 -0.000000
218 | v 0.000000 0.500001 -0.000000
219 | v 24.000000 0.490392 0.097545
220 | v 0.000000 0.490393 0.097545
221 | v 24.000000 0.461939 0.191342
222 | v 0.000000 0.461940 0.191342
223 | v 24.000000 0.415734 0.277785
224 | v 0.000000 0.415735 0.277785
225 | v 24.000000 0.353553 0.353553
226 | v 0.000000 0.353554 0.353553
227 | v 24.000000 0.277785 0.415735
228 | v 0.000000 0.277786 0.415735
229 | v 24.000000 0.191341 0.461940
230 | v 0.000000 0.191342 0.461940
231 | v 24.000000 0.097545 0.490393
232 | v 0.000000 0.097546 0.490393
233 | v 24.000000 -0.000001 0.500000
234 | v 0.000000 0.000001 0.500000
235 | v 24.000000 -0.097546 0.490393
236 | v 0.000000 -0.097545 0.490393
237 | v 24.000000 -0.191342 0.461940
238 | v 0.000000 -0.191341 0.461940
239 | v 24.000000 -0.277786 0.415735
240 | v 0.000000 -0.277785 0.415735
241 | v 24.000000 -0.353554 0.353553
242 | v 0.000000 -0.353553 0.353553
243 | v 24.000000 -0.415735 0.277785
244 | v 0.000000 -0.415734 0.277785
245 | v 24.000000 -0.461940 0.191342
246 | v 0.000000 -0.461939 0.191342
247 | v 24.000000 -0.490393 0.097545
248 | v 0.000000 -0.490392 0.097545
249 | v 24.000000 -0.500001 0.000000
250 | v 0.000000 -0.499999 0.000000
251 | v 24.000000 -0.490393 -0.097545
252 | v 0.000000 -0.490392 -0.097545
253 | v 24.000000 -0.461940 -0.191342
254 | v 0.000000 -0.461939 -0.191342
255 | v 24.000000 -0.415735 -0.277785
256 | v 0.000000 -0.415734 -0.277785
257 | v 24.000000 -0.353554 -0.353553
258 | v 0.000000 -0.353553 -0.353553
259 | v 24.000000 -0.277786 -0.415735
260 | v 0.000000 -0.277785 -0.415735
261 | v 24.000000 -0.191342 -0.461940
262 | v 0.000000 -0.191341 -0.461940
263 | v 24.000000 -0.097546 -0.490393
264 | v 0.000000 -0.097545 -0.490393
265 | v 24.000000 -0.000001 -0.500000
266 | v 0.000000 0.000001 -0.500000
267 | vn -1.0000 -0.0000 -0.0000
268 | vn -0.0000 0.0980 -0.9952
269 | vn -0.0000 0.2903 -0.9569
270 | vn 1.0000 -0.0000 -0.0000
271 | vn -0.0000 0.4714 -0.8819
272 | vn -0.0000 0.6344 -0.7730
273 | vn -0.0000 0.7730 -0.6344
274 | vn -0.0000 0.8819 -0.4714
275 | vn -0.0000 0.9569 -0.2903
276 | vn -0.0000 0.9952 -0.0980
277 | vn -0.0000 0.9952 0.0980
278 | vn -0.0000 0.9569 0.2903
279 | vn -0.0000 0.8819 0.4714
280 | vn -0.0000 0.7730 0.6344
281 | vn -0.0000 0.6344 0.7730
282 | vn -0.0000 0.4714 0.8819
283 | vn -0.0000 0.2903 0.9569
284 | vn -0.0000 0.0980 0.9952
285 | vn -0.0000 -0.0980 0.9952
286 | vn -0.0000 -0.2903 0.9569
287 | vn -0.0000 -0.4714 0.8819
288 | vn -0.0000 -0.6344 0.7730
289 | vn -0.0000 -0.7730 0.6344
290 | vn -0.0000 -0.8819 0.4714
291 | vn -0.0000 -0.9569 0.2903
292 | vn -0.0000 -0.9952 0.0980
293 | vn -0.0000 -0.9952 -0.0980
294 | vn -0.0000 -0.9569 -0.2903
295 | vn -0.0000 -0.8819 -0.4714
296 | vn -0.0000 -0.7730 -0.6344
297 | vn -0.0000 -0.6344 -0.7730
298 | vn -0.0000 -0.4714 -0.8819
299 | vn -0.0000 -0.2903 -0.9569
300 | vn -0.0000 -0.0980 -0.9952
301 | vt 0.597858 0.736041
302 | vt 0.735114 0.644330
303 | vt 0.643402 0.507074
304 | vt 0.506147 0.598785
305 | vt 0.523575 0.686407
306 | vt 0.555780 0.524503
307 | vt 0.717685 0.556707
308 | vt 0.685480 0.718612
309 | vt 0.555780 0.718612
310 | vt 0.506147 0.644330
311 | vt 0.523575 0.556707
312 | vt 0.597858 0.507074
313 | vt 0.685480 0.524503
314 | vt 0.735114 0.598785
315 | vt 0.717685 0.686407
316 | vt 0.643402 0.736041
317 | vt 0.575961 0.729399
318 | vt 0.538092 0.704096
319 | vt 0.512789 0.666227
320 | vt 0.503903 0.621557
321 | vt 0.512789 0.576888
322 | vt 0.538092 0.539019
323 | vt 0.575961 0.513716
324 | vt 0.620630 0.504831
325 | vt 0.665299 0.513716
326 | vt 0.703168 0.539019
327 | vt 0.728471 0.576888
328 | vt 0.737357 0.621557
329 | vt 0.728471 0.666227
330 | vt 0.703168 0.704096
331 | vt 0.665299 0.729399
332 | vt 0.620630 0.738284
333 | vt 0.271058 0.986328
334 | vt 0.255859 0.986328
335 | vt 0.255859 0.743148
336 | vt 0.286257 0.986328
337 | vt 0.271058 0.743148
338 | vt 0.422119 0.729399
339 | vt 0.269608 0.666227
340 | vt 0.332780 0.513716
341 | vt 0.485291 0.576888
342 | vt 0.485291 0.666227
343 | vt 0.422119 0.513716
344 | vt 0.269608 0.576888
345 | vt 0.332780 0.729399
346 | vt 0.459988 0.704096
347 | vt 0.494176 0.621557
348 | vt 0.459988 0.539019
349 | vt 0.377450 0.504831
350 | vt 0.294911 0.539019
351 | vt 0.260723 0.621557
352 | vt 0.294911 0.704096
353 | vt 0.377450 0.738284
354 | vt 0.442299 0.718612
355 | vt 0.474504 0.686407
356 | vt 0.491933 0.644330
357 | vt 0.491933 0.598785
358 | vt 0.474504 0.556707
359 | vt 0.442299 0.524503
360 | vt 0.400222 0.507074
361 | vt 0.354677 0.507074
362 | vt 0.312600 0.524503
363 | vt 0.280395 0.556707
364 | vt 0.262966 0.598785
365 | vt 0.262966 0.644330
366 | vt 0.280395 0.686407
367 | vt 0.312600 0.718612
368 | vt 0.354677 0.736041
369 | vt 0.400222 0.736041
370 | vt 0.301456 0.986328
371 | vt 0.286257 0.743148
372 | vt 0.316654 0.986328
373 | vt 0.301456 0.743148
374 | vt 0.331853 0.986328
375 | vt 0.316654 0.743148
376 | vt 0.347052 0.986328
377 | vt 0.331853 0.743148
378 | vt 0.362251 0.986328
379 | vt 0.347052 0.743148
380 | vt 0.377450 0.986328
381 | vt 0.362251 0.743148
382 | vt 0.392648 0.986328
383 | vt 0.377450 0.743148
384 | vt 0.407847 0.986328
385 | vt 0.392648 0.743148
386 | vt 0.423046 0.986328
387 | vt 0.407847 0.743148
388 | vt 0.438245 0.986328
389 | vt 0.423046 0.743148
390 | vt 0.453443 0.986328
391 | vt 0.438245 0.743148
392 | vt 0.468642 0.986328
393 | vt 0.453443 0.743148
394 | vt 0.483841 0.986328
395 | vt 0.468642 0.743148
396 | vt 0.499040 0.986328
397 | vt 0.483841 0.743148
398 | vt 0.514239 0.986328
399 | vt 0.499040 0.743148
400 | vt 0.529437 0.986328
401 | vt 0.514239 0.743148
402 | vt 0.544636 0.986328
403 | vt 0.529437 0.743148
404 | vt 0.559835 0.986328
405 | vt 0.544636 0.743148
406 | vt 0.575034 0.986328
407 | vt 0.559835 0.743148
408 | vt 0.590232 0.986328
409 | vt 0.575034 0.743148
410 | vt 0.605431 0.986328
411 | vt 0.590232 0.743148
412 | vt 0.620630 0.986328
413 | vt 0.605431 0.743148
414 | vt 0.635829 0.986328
415 | vt 0.620630 0.743148
416 | vt 0.651028 0.986328
417 | vt 0.635829 0.743148
418 | vt 0.666226 0.986328
419 | vt 0.651028 0.743148
420 | vt 0.681425 0.986328
421 | vt 0.666226 0.743148
422 | vt 0.696624 0.986328
423 | vt 0.681425 0.743148
424 | vt 0.711823 0.986328
425 | vt 0.696624 0.743148
426 | vt 0.727022 0.986328
427 | vt 0.711823 0.743148
428 | vt 0.742220 0.986328
429 | vt 0.727022 0.743148
430 | vt 0.742220 0.743148
431 | s 0
432 | usemtl MI_YamahaMSP3_MatteBlack.004
433 | f 35/66/36 83/67/36 67/68/36
434 | f 51/69/36 43/70/36 35/66/36
435 | f 67/68/36 59/71/36 51/69/36
436 | f 83/67/36 75/72/36 67/68/36
437 | f 35/66/36 91/73/36 83/67/36
438 | f 43/70/36 39/74/36 35/66/36
439 | f 51/69/36 47/75/36 43/70/36
440 | f 59/71/36 55/76/36 51/69/36
441 | f 67/68/36 63/77/36 59/71/36
442 | f 75/72/36 71/78/36 67/68/36
443 | f 83/67/36 79/79/36 75/72/36
444 | f 91/73/36 87/80/36 83/67/36
445 | f 35/66/36 95/81/36 91/73/36
446 | f 39/74/36 37/82/36 35/66/36
447 | f 43/70/36 41/83/36 39/74/36
448 | f 47/75/36 45/84/36 43/70/36
449 | f 51/69/36 49/85/36 47/75/36
450 | f 55/76/36 53/86/36 51/69/36
451 | f 59/71/36 57/87/36 55/76/36
452 | f 63/77/36 61/88/36 59/71/36
453 | f 67/68/36 65/89/36 63/77/36
454 | f 71/78/36 69/90/36 67/68/36
455 | f 75/72/36 73/91/36 71/78/36
456 | f 79/79/36 77/92/36 75/72/36
457 | f 83/67/36 81/93/36 79/79/36
458 | f 87/80/36 85/94/36 83/67/36
459 | f 91/73/36 89/95/36 87/80/36
460 | f 95/81/36 93/96/36 91/73/36
461 | f 35/66/36 97/97/36 95/81/36
462 | f 34/98/37 96/99/37 97/100/37
463 | f 36/101/38 34/98/38 35/102/38
464 | f 92/103/39 44/104/39 60/105/39
465 | f 76/106/39 84/107/39 92/103/39
466 | f 60/105/39 68/108/39 76/106/39
467 | f 44/104/39 52/109/39 60/105/39
468 | f 92/103/39 36/110/39 44/104/39
469 | f 84/107/39 88/111/39 92/103/39
470 | f 76/106/39 80/112/39 84/107/39
471 | f 68/108/39 72/113/39 76/106/39
472 | f 60/105/39 64/114/39 68/108/39
473 | f 52/109/39 56/115/39 60/105/39
474 | f 44/104/39 48/116/39 52/109/39
475 | f 36/110/39 40/117/39 44/104/39
476 | f 92/103/39 96/118/39 36/110/39
477 | f 88/111/39 90/119/39 92/103/39
478 | f 84/107/39 86/120/39 88/111/39
479 | f 80/112/39 82/121/39 84/107/39
480 | f 76/106/39 78/122/39 80/112/39
481 | f 72/113/39 74/123/39 76/106/39
482 | f 68/108/39 70/124/39 72/113/39
483 | f 64/114/39 66/125/39 68/108/39
484 | f 60/105/39 62/126/39 64/114/39
485 | f 56/115/39 58/127/39 60/105/39
486 | f 52/109/39 54/128/39 56/115/39
487 | f 48/116/39 50/129/39 52/109/39
488 | f 44/104/39 46/130/39 48/116/39
489 | f 40/117/39 42/131/39 44/104/39
490 | f 36/110/39 38/132/39 40/117/39
491 | f 96/118/39 34/133/39 36/110/39
492 | f 92/103/39 94/134/39 96/118/39
493 | f 38/135/40 36/101/40 37/136/40
494 | f 40/137/41 38/135/41 39/138/41
495 | f 42/139/42 40/137/42 41/140/42
496 | f 44/141/43 42/139/43 43/142/43
497 | f 46/143/44 44/141/44 45/144/44
498 | f 48/145/45 46/143/45 47/146/45
499 | f 50/147/46 48/145/46 49/148/46
500 | f 52/149/47 50/147/47 51/150/47
501 | f 54/151/48 52/149/48 53/152/48
502 | f 56/153/49 54/151/49 55/154/49
503 | f 58/155/50 56/153/50 57/156/50
504 | f 60/157/51 58/155/51 59/158/51
505 | f 62/159/52 60/157/52 61/160/52
506 | f 64/161/53 62/159/53 63/162/53
507 | f 66/163/54 64/161/54 65/164/54
508 | f 68/165/55 66/163/55 67/166/55
509 | f 70/167/56 68/165/56 69/168/56
510 | f 72/169/57 70/167/57 71/170/57
511 | f 74/171/58 72/169/58 73/172/58
512 | f 76/173/59 74/171/59 75/174/59
513 | f 78/175/60 76/173/60 77/176/60
514 | f 80/177/61 78/175/61 79/178/61
515 | f 82/179/62 80/177/62 81/180/62
516 | f 84/181/63 82/179/63 83/182/63
517 | f 86/183/64 84/181/64 85/184/64
518 | f 88/185/65 86/183/65 87/186/65
519 | f 90/187/66 88/185/66 89/188/66
520 | f 92/189/67 90/187/67 91/190/67
521 | f 94/191/68 92/189/68 93/192/68
522 | f 96/193/69 94/191/69 95/194/69
523 | f 67/68/36 51/69/36 35/66/36
524 | f 34/98/37 97/100/37 35/102/37
525 | f 36/101/38 35/102/38 37/136/38
526 | f 60/105/39 76/106/39 92/103/39
527 | f 38/135/40 37/136/40 39/138/40
528 | f 40/137/41 39/138/41 41/140/41
529 | f 42/139/42 41/140/42 43/142/42
530 | f 44/141/43 43/142/43 45/144/43
531 | f 46/143/44 45/144/44 47/146/44
532 | f 48/145/45 47/146/45 49/148/45
533 | f 50/147/46 49/148/46 51/150/46
534 | f 52/149/47 51/150/47 53/152/47
535 | f 54/151/48 53/152/48 55/154/48
536 | f 56/153/49 55/154/49 57/156/49
537 | f 58/155/50 57/156/50 59/158/50
538 | f 60/157/51 59/158/51 61/160/51
539 | f 62/159/52 61/160/52 63/162/52
540 | f 64/161/53 63/162/53 65/164/53
541 | f 66/163/54 65/164/54 67/166/54
542 | f 68/165/55 67/166/55 69/168/55
543 | f 70/167/56 69/168/56 71/170/56
544 | f 72/169/57 71/170/57 73/172/57
545 | f 74/171/58 73/172/58 75/174/58
546 | f 76/173/59 75/174/59 77/176/59
547 | f 78/175/60 77/176/60 79/178/60
548 | f 80/177/61 79/178/61 81/180/61
549 | f 82/179/62 81/180/62 83/182/62
550 | f 84/181/63 83/182/63 85/184/63
551 | f 86/183/64 85/184/64 87/186/64
552 | f 88/185/65 87/186/65 89/188/65
553 | f 90/187/66 89/188/66 91/190/66
554 | f 92/189/67 91/190/67 93/192/67
555 | f 94/191/68 93/192/68 95/194/68
556 | f 96/193/69 95/194/69 97/195/69
557 | o Y
558 | v 0.000000 -0.000002 -28.000000
559 | v -0.292636 -1.471180 -22.000000
560 | v -0.574025 -1.385821 -22.000000
561 | v -0.833355 -1.247206 -22.000000
562 | v -1.060660 -1.060662 -22.000000
563 | v -1.247204 -0.833357 -22.000000
564 | v -1.385819 -0.574027 -22.000000
565 | v -1.471178 -0.292637 -22.000000
566 | v -1.500000 -0.000002 -22.000000
567 | v -1.471178 0.292634 -22.000000
568 | v -1.385819 0.574023 -22.000000
569 | v -1.247204 0.833353 -22.000000
570 | v -1.060660 1.060658 -22.000000
571 | v -0.833355 1.247203 -22.000000
572 | v -0.574025 1.385817 -22.000000
573 | v -0.292636 1.471176 -22.000000
574 | v 0.000000 1.499998 -22.000000
575 | v 0.292636 1.471176 -22.000000
576 | v 0.574025 1.385817 -22.000000
577 | v 0.833355 1.247203 -22.000000
578 | v 1.060660 1.060658 -22.000000
579 | v 1.247204 0.833353 -22.000000
580 | v 1.385819 0.574023 -22.000000
581 | v 1.471178 0.292634 -22.000000
582 | v 1.500000 -0.000002 -22.000000
583 | v 1.471178 -0.292637 -22.000000
584 | v 1.385819 -0.574027 -22.000000
585 | v 1.247204 -0.833357 -22.000000
586 | v 1.060660 -1.060662 -22.000000
587 | v 0.833355 -1.247206 -22.000000
588 | v 0.574025 -1.385821 -22.000000
589 | v 0.292636 -1.471180 -22.000000
590 | v 0.000000 -1.500002 -22.000000
591 | vn -0.0000 -0.0000 1.0000
592 | vn -0.0001 -0.0000 1.0000
593 | vn 0.0001 -0.0000 1.0000
594 | vn -0.0951 -0.9657 -0.2414
595 | vn -0.2817 -0.9286 -0.2414
596 | vn -0.4575 -0.8558 -0.2414
597 | vn -0.6156 -0.7501 -0.2414
598 | vn -0.7501 -0.6156 -0.2414
599 | vn -0.8558 -0.4575 -0.2414
600 | vn -0.9286 -0.2817 -0.2414
601 | vn -0.9657 -0.0951 -0.2414
602 | vn -0.9657 0.0951 -0.2414
603 | vn -0.9286 0.2817 -0.2414
604 | vn -0.8558 0.4575 -0.2414
605 | vn -0.7501 0.6156 -0.2414
606 | vn -0.6156 0.7501 -0.2414
607 | vn -0.4574 0.8558 -0.2414
608 | vn -0.2817 0.9286 -0.2414
609 | vn -0.0951 0.9657 -0.2414
610 | vn 0.0951 0.9657 -0.2414
611 | vn 0.2817 0.9286 -0.2414
612 | vn 0.4574 0.8558 -0.2414
613 | vn 0.6156 0.7501 -0.2414
614 | vn 0.7501 0.6156 -0.2414
615 | vn 0.8558 0.4575 -0.2414
616 | vn 0.9286 0.2817 -0.2414
617 | vn 0.9657 0.0951 -0.2414
618 | vn 0.9657 -0.0951 -0.2414
619 | vn 0.9286 -0.2817 -0.2414
620 | vn 0.8558 -0.4575 -0.2414
621 | vn 0.7501 -0.6156 -0.2414
622 | vn 0.6156 -0.7501 -0.2414
623 | vn 0.4575 -0.8558 -0.2414
624 | vn 0.2817 -0.9286 -0.2414
625 | vn 0.0951 -0.9657 -0.2414
626 | vt 0.847703 0.234951
627 | vt 0.974738 0.150069
628 | vt 0.889856 0.023035
629 | vt 0.762822 0.107916
630 | vt 0.778953 0.189013
631 | vt 0.808759 0.039165
632 | vt 0.958607 0.068972
633 | vt 0.928801 0.218820
634 | vt 0.808759 0.218820
635 | vt 0.762822 0.150069
636 | vt 0.778953 0.068972
637 | vt 0.847703 0.023035
638 | vt 0.928801 0.039165
639 | vt 0.974738 0.107916
640 | vt 0.958607 0.189013
641 | vt 0.889856 0.234951
642 | vt 0.827437 0.228803
643 | vt 0.792388 0.205385
644 | vt 0.768969 0.170336
645 | vt 0.760746 0.128993
646 | vt 0.768969 0.087650
647 | vt 0.792388 0.052601
648 | vt 0.827437 0.029182
649 | vt 0.868780 0.020959
650 | vt 0.910123 0.029182
651 | vt 0.945172 0.052601
652 | vt 0.968590 0.087650
653 | vt 0.976814 0.128993
654 | vt 0.968590 0.170336
655 | vt 0.945172 0.205385
656 | vt 0.910123 0.228803
657 | vt 0.868780 0.237027
658 | vt 0.622632 0.234951
659 | vt 0.643709 0.128993
660 | vt 0.643709 0.237027
661 | vt 0.602366 0.228803
662 | vt 0.583688 0.218820
663 | vt 0.567317 0.205385
664 | vt 0.553881 0.189013
665 | vt 0.543898 0.170336
666 | vt 0.537751 0.150069
667 | vt 0.535675 0.128993
668 | vt 0.537751 0.107916
669 | vt 0.543898 0.087650
670 | vt 0.553881 0.068972
671 | vt 0.567317 0.052601
672 | vt 0.583688 0.039165
673 | vt 0.602366 0.029182
674 | vt 0.622632 0.023035
675 | vt 0.643709 0.020959
676 | vt 0.664785 0.023035
677 | vt 0.685052 0.029182
678 | vt 0.703729 0.039165
679 | vt 0.720101 0.052601
680 | vt 0.733536 0.068972
681 | vt 0.743519 0.087650
682 | vt 0.749667 0.107916
683 | vt 0.751743 0.128993
684 | vt 0.749667 0.150069
685 | vt 0.743519 0.170336
686 | vt 0.733536 0.189013
687 | vt 0.720101 0.205385
688 | vt 0.703729 0.218820
689 | vt 0.685052 0.228803
690 | vt 0.664785 0.234951
691 | s 0
692 | usemtl MI_YamahaMSP3_MatteBlack.003
693 | f 99/196/70 123/197/70 115/198/70
694 | f 107/199/70 103/200/70 99/196/70
695 | f 115/198/70 111/201/70 107/199/70
696 | f 123/197/70 119/202/70 115/198/70
697 | f 99/196/70 127/203/70 123/197/70
698 | f 103/200/70 101/204/70 99/196/70
699 | f 107/199/70 105/205/70 103/200/70
700 | f 111/201/70 109/206/70 107/199/70
701 | f 115/198/70 113/207/70 111/201/70
702 | f 119/202/70 117/208/70 115/198/70
703 | f 123/197/70 121/209/70 119/202/70
704 | f 127/203/70 125/210/70 123/197/70
705 | f 99/196/70 129/211/70 127/203/70
706 | f 101/204/70 100/212/70 99/196/70
707 | f 103/200/71 102/213/71 101/204/71
708 | f 105/205/71 104/214/71 103/200/71
709 | f 107/199/72 106/215/72 105/205/72
710 | f 109/206/72 108/216/72 107/199/72
711 | f 111/201/71 110/217/71 109/206/71
712 | f 113/207/70 112/218/70 111/201/70
713 | f 115/198/70 114/219/70 113/207/70
714 | f 117/208/70 116/220/70 115/198/70
715 | f 119/202/72 118/221/72 117/208/72
716 | f 121/209/71 120/222/71 119/202/71
717 | f 123/197/71 122/223/71 121/209/71
718 | f 125/210/72 124/224/72 123/197/72
719 | f 127/203/72 126/225/72 125/210/72
720 | f 129/211/70 128/226/70 127/203/70
721 | f 99/196/70 130/227/70 129/211/70
722 | f 99/228/73 98/229/73 130/230/73
723 | f 100/231/74 98/229/74 99/228/74
724 | f 115/198/70 107/199/70 99/196/70
725 | f 101/232/75 98/229/75 100/231/75
726 | f 102/233/76 98/229/76 101/232/76
727 | f 103/234/77 98/229/77 102/233/77
728 | f 104/235/78 98/229/78 103/234/78
729 | f 105/236/79 98/229/79 104/235/79
730 | f 106/237/80 98/229/80 105/236/80
731 | f 107/238/81 98/229/81 106/237/81
732 | f 108/239/82 98/229/82 107/238/82
733 | f 109/240/83 98/229/83 108/239/83
734 | f 110/241/84 98/229/84 109/240/84
735 | f 111/242/85 98/229/85 110/241/85
736 | f 112/243/86 98/229/86 111/242/86
737 | f 113/244/87 98/229/87 112/243/87
738 | f 114/245/88 98/229/88 113/244/88
739 | f 115/246/89 98/229/89 114/245/89
740 | f 116/247/90 98/229/90 115/246/90
741 | f 117/248/91 98/229/91 116/247/91
742 | f 118/249/92 98/229/92 117/248/92
743 | f 119/250/93 98/229/93 118/249/93
744 | f 120/251/94 98/229/94 119/250/94
745 | f 121/252/95 98/229/95 120/251/95
746 | f 122/253/96 98/229/96 121/252/96
747 | f 123/254/97 98/229/97 122/253/97
748 | f 124/255/98 98/229/98 123/254/98
749 | f 125/256/99 98/229/99 124/255/99
750 | f 126/257/100 98/229/100 125/256/100
751 | f 127/258/101 98/229/101 126/257/101
752 | f 128/259/102 98/229/102 127/258/102
753 | f 129/260/103 98/229/103 128/259/103
754 | f 130/230/104 98/229/104 129/260/104
755 | o Yzhu
756 | v -0.097545 0.490392 -0.000000
757 | v -0.097545 0.490391 -24.000000
758 | v -0.191342 0.461939 -0.000000
759 | v -0.191342 0.461938 -24.000000
760 | v -0.277785 0.415734 -0.000000
761 | v -0.277785 0.415733 -24.000000
762 | v -0.353553 0.353553 -0.000000
763 | v -0.353553 0.353552 -24.000000
764 | v -0.415735 0.277785 -0.000000
765 | v -0.415735 0.277784 -24.000000
766 | v -0.461940 0.191341 -0.000000
767 | v -0.461940 0.191340 -24.000000
768 | v -0.490393 0.097545 -0.000000
769 | v -0.490393 0.097544 -24.000000
770 | v -0.500000 -0.000001 0.000000
771 | v -0.500000 -0.000001 -24.000000
772 | v -0.490393 -0.097546 0.000000
773 | v -0.490393 -0.097547 -24.000000
774 | v -0.461940 -0.191342 0.000000
775 | v -0.461940 -0.191343 -24.000000
776 | v -0.415735 -0.277786 0.000000
777 | v -0.415735 -0.277787 -24.000000
778 | v -0.353553 -0.353554 0.000000
779 | v -0.353553 -0.353555 -24.000000
780 | v -0.277785 -0.415735 0.000000
781 | v -0.277785 -0.415736 -24.000000
782 | v -0.191342 -0.461940 0.000000
783 | v -0.191342 -0.461941 -24.000000
784 | v -0.097545 -0.490393 0.000000
785 | v -0.097545 -0.490394 -24.000000
786 | v 0.000000 -0.500001 0.000000
787 | v 0.000000 -0.500001 -24.000000
788 | v 0.097545 -0.490393 0.000000
789 | v 0.097545 -0.490394 -24.000000
790 | v 0.191342 -0.461940 0.000000
791 | v 0.191342 -0.461941 -24.000000
792 | v 0.277785 -0.415735 0.000000
793 | v 0.277785 -0.415736 -24.000000
794 | v 0.353553 -0.353554 0.000000
795 | v 0.353553 -0.353555 -24.000000
796 | v 0.415735 -0.277786 0.000000
797 | v 0.415735 -0.277787 -24.000000
798 | v 0.461940 -0.191342 0.000000
799 | v 0.461940 -0.191343 -24.000000
800 | v 0.490393 -0.097546 0.000000
801 | v 0.490393 -0.097547 -24.000000
802 | v 0.500000 -0.000001 0.000000
803 | v 0.500000 -0.000001 -24.000000
804 | v 0.490393 0.097545 -0.000000
805 | v 0.490393 0.097544 -24.000000
806 | v 0.461940 0.191341 -0.000000
807 | v 0.461940 0.191340 -24.000000
808 | v 0.415735 0.277785 -0.000000
809 | v 0.415735 0.277784 -24.000000
810 | v 0.353553 0.353553 -0.000000
811 | v 0.353553 0.353552 -24.000000
812 | v 0.277785 0.415734 -0.000000
813 | v 0.277785 0.415733 -24.000000
814 | v 0.191342 0.461939 -0.000000
815 | v 0.191342 0.461938 -24.000000
816 | v 0.097545 0.490392 -0.000000
817 | v 0.097545 0.490391 -24.000000
818 | v 0.000000 0.499999 -0.000000
819 | v 0.000000 0.499999 -24.000000
820 | vn -0.0000 -0.0000 -1.0000
821 | vn -0.0001 -0.0000 -1.0000
822 | vn 0.0001 -0.0000 -1.0000
823 | vn -0.0980 0.9952 -0.0000
824 | vn -0.2903 0.9569 -0.0000
825 | vn -0.0000 -0.0000 1.0000
826 | vn -0.4714 0.8819 -0.0000
827 | vn -0.6344 0.7730 -0.0000
828 | vn -0.7730 0.6344 -0.0000
829 | vn -0.8819 0.4714 -0.0000
830 | vn -0.9569 0.2903 -0.0000
831 | vn -0.9952 0.0980 -0.0000
832 | vn -0.9952 -0.0980 -0.0000
833 | vn -0.9569 -0.2903 -0.0000
834 | vn -0.8819 -0.4714 -0.0000
835 | vn -0.7730 -0.6344 -0.0000
836 | vn -0.6344 -0.7730 -0.0000
837 | vn -0.4714 -0.8819 -0.0000
838 | vn -0.2903 -0.9569 -0.0000
839 | vn -0.0980 -0.9952 -0.0000
840 | vn 0.0980 -0.9952 -0.0000
841 | vn 0.2903 -0.9569 -0.0000
842 | vn 0.4714 -0.8819 -0.0000
843 | vn 0.6344 -0.7730 -0.0000
844 | vn 0.7730 -0.6344 -0.0000
845 | vn 0.8819 -0.4714 -0.0000
846 | vn 0.9569 -0.2903 -0.0000
847 | vn 0.9952 -0.0980 -0.0000
848 | vn 0.9952 0.0980 -0.0000
849 | vn 0.9569 0.2903 -0.0000
850 | vn 0.8819 0.4714 -0.0000
851 | vn 0.7730 0.6344 -0.0000
852 | vn 0.6344 0.7730 -0.0000
853 | vn 0.4714 0.8819 -0.0000
854 | vn 0.2903 0.9569 -0.0000
855 | vn 0.0980 0.9952 -0.0000
856 | vt 0.847703 0.234951
857 | vt 0.974738 0.150069
858 | vt 0.889856 0.023035
859 | vt 0.762822 0.107916
860 | vt 0.778953 0.189013
861 | vt 0.808759 0.039165
862 | vt 0.958607 0.068972
863 | vt 0.928801 0.218820
864 | vt 0.808759 0.218820
865 | vt 0.762822 0.150069
866 | vt 0.778953 0.068972
867 | vt 0.847703 0.023035
868 | vt 0.928801 0.039165
869 | vt 0.974738 0.107916
870 | vt 0.958607 0.189013
871 | vt 0.889856 0.234951
872 | vt 0.827437 0.228803
873 | vt 0.792388 0.205385
874 | vt 0.768969 0.170336
875 | vt 0.760746 0.128993
876 | vt 0.768969 0.087650
877 | vt 0.792388 0.052601
878 | vt 0.827437 0.029182
879 | vt 0.868780 0.020959
880 | vt 0.910123 0.029182
881 | vt 0.945172 0.052601
882 | vt 0.968590 0.087650
883 | vt 0.976814 0.128993
884 | vt 0.968590 0.170336
885 | vt 0.945172 0.205385
886 | vt 0.910123 0.228803
887 | vt 0.868780 0.237027
888 | vt 0.545240 0.466600
889 | vt 0.531173 0.466600
890 | vt 0.531173 0.241528
891 | vt 0.559307 0.466600
892 | vt 0.545240 0.241528
893 | vt 0.685052 0.228803
894 | vt 0.543898 0.170336
895 | vt 0.602366 0.029182
896 | vt 0.743519 0.087650
897 | vt 0.743519 0.170336
898 | vt 0.685052 0.029182
899 | vt 0.543898 0.087650
900 | vt 0.602366 0.228803
901 | vt 0.720101 0.205385
902 | vt 0.751743 0.128993
903 | vt 0.720101 0.052601
904 | vt 0.643709 0.020959
905 | vt 0.567317 0.052601
906 | vt 0.535675 0.128993
907 | vt 0.567317 0.205385
908 | vt 0.643709 0.237027
909 | vt 0.703729 0.218820
910 | vt 0.733536 0.189013
911 | vt 0.749667 0.150069
912 | vt 0.749667 0.107916
913 | vt 0.733536 0.068972
914 | vt 0.703729 0.039165
915 | vt 0.664785 0.023035
916 | vt 0.622632 0.023035
917 | vt 0.583688 0.039165
918 | vt 0.553881 0.068972
919 | vt 0.537751 0.107916
920 | vt 0.537751 0.150069
921 | vt 0.553881 0.189013
922 | vt 0.583688 0.218820
923 | vt 0.622632 0.234951
924 | vt 0.664785 0.234951
925 | vt 0.573374 0.466600
926 | vt 0.559307 0.241528
927 | vt 0.587441 0.466600
928 | vt 0.573374 0.241528
929 | vt 0.601508 0.466600
930 | vt 0.587441 0.241528
931 | vt 0.615575 0.466600
932 | vt 0.601508 0.241528
933 | vt 0.629642 0.466600
934 | vt 0.615575 0.241528
935 | vt 0.643709 0.466600
936 | vt 0.629642 0.241528
937 | vt 0.657776 0.466600
938 | vt 0.643709 0.241528
939 | vt 0.671843 0.466600
940 | vt 0.657776 0.241528
941 | vt 0.685910 0.466600
942 | vt 0.671843 0.241528
943 | vt 0.699977 0.466600
944 | vt 0.685910 0.241528
945 | vt 0.714043 0.466600
946 | vt 0.699977 0.241528
947 | vt 0.728110 0.466600
948 | vt 0.714043 0.241528
949 | vt 0.742177 0.466600
950 | vt 0.728110 0.241528
951 | vt 0.756244 0.466600
952 | vt 0.742177 0.241528
953 | vt 0.770311 0.466600
954 | vt 0.756244 0.241528
955 | vt 0.784378 0.466600
956 | vt 0.770311 0.241528
957 | vt 0.798445 0.466600
958 | vt 0.784378 0.241528
959 | vt 0.812512 0.466600
960 | vt 0.798445 0.241528
961 | vt 0.826579 0.466600
962 | vt 0.812512 0.241528
963 | vt 0.840646 0.466600
964 | vt 0.826579 0.241528
965 | vt 0.854713 0.466600
966 | vt 0.840646 0.241528
967 | vt 0.868780 0.466600
968 | vt 0.854713 0.241528
969 | vt 0.882847 0.466600
970 | vt 0.868780 0.241528
971 | vt 0.896914 0.466600
972 | vt 0.882847 0.241528
973 | vt 0.910981 0.466600
974 | vt 0.896914 0.241528
975 | vt 0.925048 0.466600
976 | vt 0.910981 0.241528
977 | vt 0.939115 0.466600
978 | vt 0.925048 0.241528
979 | vt 0.953182 0.466600
980 | vt 0.939115 0.241528
981 | vt 0.967249 0.466600
982 | vt 0.953182 0.241528
983 | vt 0.981316 0.466600
984 | vt 0.967249 0.241528
985 | vt 0.981316 0.241528
986 | s 0
987 | usemtl MI_YamahaMSP3_MatteBlack.003
988 | f 132/261/105 180/262/105 164/263/105
989 | f 148/264/105 140/265/105 132/261/105
990 | f 164/263/105 156/266/105 148/264/105
991 | f 180/262/105 172/267/105 164/263/105
992 | f 132/261/105 188/268/105 180/262/105
993 | f 140/265/105 136/269/105 132/261/105
994 | f 148/264/106 144/270/106 140/265/106
995 | f 156/266/105 152/271/105 148/264/105
996 | f 164/263/105 160/272/105 156/266/105
997 | f 172/267/105 168/273/105 164/263/105
998 | f 180/262/107 176/274/107 172/267/107
999 | f 188/268/105 184/275/105 180/262/105
1000 | f 132/261/105 192/276/105 188/268/105
1001 | f 136/269/105 134/277/105 132/261/105
1002 | f 140/265/105 138/278/105 136/269/105
1003 | f 144/270/107 142/279/107 140/265/107
1004 | f 148/264/106 146/280/106 144/270/106
1005 | f 152/271/105 150/281/105 148/264/105
1006 | f 156/266/105 154/282/105 152/271/105
1007 | f 160/272/105 158/283/105 156/266/105
1008 | f 164/263/105 162/284/105 160/272/105
1009 | f 168/273/105 166/285/105 164/263/105
1010 | f 172/267/105 170/286/105 168/273/105
1011 | f 176/274/105 174/287/105 172/267/105
1012 | f 180/262/107 178/288/107 176/274/107
1013 | f 184/275/106 182/289/106 180/262/106
1014 | f 188/268/105 186/290/105 184/275/105
1015 | f 192/276/105 190/291/105 188/268/105
1016 | f 132/261/105 194/292/105 192/276/105
1017 | f 131/293/108 193/294/108 194/295/108
1018 | f 133/296/109 131/293/109 132/297/109
1019 | f 189/298/110 141/299/110 157/300/110
1020 | f 173/301/110 181/302/110 189/298/110
1021 | f 157/300/110 165/303/110 173/301/110
1022 | f 141/299/110 149/304/110 157/300/110
1023 | f 189/298/110 133/305/110 141/299/110
1024 | f 181/302/110 185/306/110 189/298/110
1025 | f 173/301/110 177/307/110 181/302/110
1026 | f 165/303/110 169/308/110 173/301/110
1027 | f 157/300/110 161/309/110 165/303/110
1028 | f 149/304/110 153/310/110 157/300/110
1029 | f 141/299/110 145/311/110 149/304/110
1030 | f 133/305/110 137/312/110 141/299/110
1031 | f 189/298/110 193/313/110 133/305/110
1032 | f 185/306/110 187/314/110 189/298/110
1033 | f 181/302/110 183/315/110 185/306/110
1034 | f 177/307/110 179/316/110 181/302/110
1035 | f 173/301/110 175/317/110 177/307/110
1036 | f 169/308/110 171/318/110 173/301/110
1037 | f 165/303/110 167/319/110 169/308/110
1038 | f 161/309/110 163/320/110 165/303/110
1039 | f 157/300/110 159/321/110 161/309/110
1040 | f 153/310/110 155/322/110 157/300/110
1041 | f 149/304/110 151/323/110 153/310/110
1042 | f 145/311/110 147/324/110 149/304/110
1043 | f 141/299/110 143/325/110 145/311/110
1044 | f 137/312/110 139/326/110 141/299/110
1045 | f 133/305/110 135/327/110 137/312/110
1046 | f 193/313/110 131/328/110 133/305/110
1047 | f 189/298/110 191/329/110 193/313/110
1048 | f 135/330/111 133/296/111 134/331/111
1049 | f 137/332/112 135/330/112 136/333/112
1050 | f 139/334/113 137/332/113 138/335/113
1051 | f 141/336/114 139/334/114 140/337/114
1052 | f 143/338/115 141/336/115 142/339/115
1053 | f 145/340/116 143/338/116 144/341/116
1054 | f 147/342/117 145/340/117 146/343/117
1055 | f 149/344/118 147/342/118 148/345/118
1056 | f 151/346/119 149/344/119 150/347/119
1057 | f 153/348/120 151/346/120 152/349/120
1058 | f 155/350/121 153/348/121 154/351/121
1059 | f 157/352/122 155/350/122 156/353/122
1060 | f 159/354/123 157/352/123 158/355/123
1061 | f 161/356/124 159/354/124 160/357/124
1062 | f 163/358/125 161/356/125 162/359/125
1063 | f 165/360/126 163/358/126 164/361/126
1064 | f 167/362/127 165/360/127 166/363/127
1065 | f 169/364/128 167/362/128 168/365/128
1066 | f 171/366/129 169/364/129 170/367/129
1067 | f 173/368/130 171/366/130 172/369/130
1068 | f 175/370/131 173/368/131 174/371/131
1069 | f 177/372/132 175/370/132 176/373/132
1070 | f 179/374/133 177/372/133 178/375/133
1071 | f 181/376/134 179/374/134 180/377/134
1072 | f 183/378/135 181/376/135 182/379/135
1073 | f 185/380/136 183/378/136 184/381/136
1074 | f 187/382/137 185/380/137 186/383/137
1075 | f 189/384/138 187/382/138 188/385/138
1076 | f 191/386/139 189/384/139 190/387/139
1077 | f 193/388/140 191/386/140 192/389/140
1078 | f 164/263/105 148/264/105 132/261/105
1079 | f 131/293/108 194/295/108 132/297/108
1080 | f 133/296/109 132/297/109 134/331/109
1081 | f 157/300/110 173/301/110 189/298/110
1082 | f 135/330/111 134/331/111 136/333/111
1083 | f 137/332/112 136/333/112 138/335/112
1084 | f 139/334/113 138/335/113 140/337/113
1085 | f 141/336/114 140/337/114 142/339/114
1086 | f 143/338/115 142/339/115 144/341/115
1087 | f 145/340/116 144/341/116 146/343/116
1088 | f 147/342/117 146/343/117 148/345/117
1089 | f 149/344/118 148/345/118 150/347/118
1090 | f 151/346/119 150/347/119 152/349/119
1091 | f 153/348/120 152/349/120 154/351/120
1092 | f 155/350/121 154/351/121 156/353/121
1093 | f 157/352/122 156/353/122 158/355/122
1094 | f 159/354/123 158/355/123 160/357/123
1095 | f 161/356/124 160/357/124 162/359/124
1096 | f 163/358/125 162/359/125 164/361/125
1097 | f 165/360/126 164/361/126 166/363/126
1098 | f 167/362/127 166/363/127 168/365/127
1099 | f 169/364/128 168/365/128 170/367/128
1100 | f 171/366/129 170/367/129 172/369/129
1101 | f 173/368/130 172/369/130 174/371/130
1102 | f 175/370/131 174/371/131 176/373/131
1103 | f 177/372/132 176/373/132 178/375/132
1104 | f 179/374/133 178/375/133 180/377/133
1105 | f 181/376/134 180/377/134 182/379/134
1106 | f 183/378/135 182/379/135 184/381/135
1107 | f 185/380/136 184/381/136 186/383/136
1108 | f 187/382/137 186/383/137 188/385/137
1109 | f 189/384/138 188/385/138 190/387/138
1110 | f 191/386/139 190/387/139 192/389/139
1111 | f 193/388/140 192/389/140 194/390/140
1112 | o Z
1113 | v 0.000000 28.000000 -0.000002
1114 | v -0.292636 22.000000 -1.471180
1115 | v -0.574025 22.000000 -1.385821
1116 | v -0.833355 22.000000 -1.247206
1117 | v -1.060660 22.000000 -1.060662
1118 | v -1.247204 22.000000 -0.833357
1119 | v -1.385819 22.000000 -0.574027
1120 | v -1.471178 22.000000 -0.292638
1121 | v -1.500000 22.000000 -0.000002
1122 | v -1.471178 22.000000 0.292634
1123 | v -1.385819 22.000000 0.574023
1124 | v -1.247204 22.000000 0.833353
1125 | v -1.060660 22.000000 1.060658
1126 | v -0.833355 22.000000 1.247202
1127 | v -0.574025 22.000000 1.385817
1128 | v -0.292636 22.000000 1.471176
1129 | v 0.000000 22.000000 1.499998
1130 | v 0.292636 22.000000 1.471176
1131 | v 0.574025 22.000000 1.385817
1132 | v 0.833355 22.000000 1.247202
1133 | v 1.060660 22.000000 1.060658
1134 | v 1.247204 22.000000 0.833353
1135 | v 1.385819 22.000000 0.574023
1136 | v 1.471178 22.000000 0.292634
1137 | v 1.500000 22.000000 -0.000002
1138 | v 1.471178 22.000000 -0.292638
1139 | v 1.385819 22.000000 -0.574027
1140 | v 1.247204 22.000000 -0.833357
1141 | v 1.060660 22.000000 -1.060662
1142 | v 0.833355 22.000000 -1.247206
1143 | v 0.574025 22.000000 -1.385821
1144 | v 0.292636 22.000000 -1.471180
1145 | v 0.000000 22.000000 -1.500002
1146 | vn -0.0000 -1.0000 -0.0000
1147 | vn -0.0000 -1.0000 0.0001
1148 | vn -0.0000 -1.0000 -0.0001
1149 | vn -0.0951 0.2414 -0.9657
1150 | vn -0.2817 0.2414 -0.9286
1151 | vn -0.4575 0.2414 -0.8558
1152 | vn -0.6156 0.2414 -0.7501
1153 | vn -0.7501 0.2414 -0.6156
1154 | vn -0.8558 0.2414 -0.4575
1155 | vn -0.9286 0.2414 -0.2817
1156 | vn -0.9657 0.2414 -0.0951
1157 | vn -0.9657 0.2414 0.0951
1158 | vn -0.9286 0.2414 0.2817
1159 | vn -0.8558 0.2414 0.4575
1160 | vn -0.7501 0.2414 0.6156
1161 | vn -0.6156 0.2414 0.7501
1162 | vn -0.4575 0.2414 0.8558
1163 | vn -0.2817 0.2414 0.9286
1164 | vn -0.0951 0.2414 0.9657
1165 | vn 0.0951 0.2414 0.9657
1166 | vn 0.2817 0.2414 0.9286
1167 | vn 0.4575 0.2414 0.8558
1168 | vn 0.6156 0.2414 0.7501
1169 | vn 0.7501 0.2414 0.6156
1170 | vn 0.8558 0.2414 0.4575
1171 | vn 0.9286 0.2414 0.2817
1172 | vn 0.9657 0.2414 0.0951
1173 | vn 0.9657 0.2414 -0.0951
1174 | vn 0.9286 0.2414 -0.2817
1175 | vn 0.8558 0.2414 -0.4575
1176 | vn 0.7501 0.2414 -0.6156
1177 | vn 0.6156 0.2414 -0.7501
1178 | vn 0.4575 0.2414 -0.8558
1179 | vn 0.2817 0.2414 -0.9286
1180 | vn 0.0951 0.2414 -0.9657
1181 | vt 0.344619 0.232996
1182 | vt 0.473521 0.146867
1183 | vt 0.387392 0.017966
1184 | vt 0.258490 0.104095
1185 | vt 0.274858 0.186384
1186 | vt 0.305103 0.034334
1187 | vt 0.457153 0.064579
1188 | vt 0.426908 0.216629
1189 | vt 0.305103 0.216629
1190 | vt 0.258490 0.146867
1191 | vt 0.274858 0.064579
1192 | vt 0.344619 0.017966
1193 | vt 0.426908 0.034334
1194 | vt 0.473521 0.104095
1195 | vt 0.457153 0.186384
1196 | vt 0.387392 0.232996
1197 | vt 0.324055 0.226758
1198 | vt 0.288491 0.202996
1199 | vt 0.264728 0.167432
1200 | vt 0.256384 0.125481
1201 | vt 0.264728 0.083531
1202 | vt 0.288491 0.047967
1203 | vt 0.324055 0.024204
1204 | vt 0.366006 0.015859
1205 | vt 0.407956 0.024204
1206 | vt 0.443520 0.047967
1207 | vt 0.467283 0.083531
1208 | vt 0.475627 0.125481
1209 | vt 0.467283 0.167432
1210 | vt 0.443520 0.202996
1211 | vt 0.407956 0.226758
1212 | vt 0.366006 0.235103
1213 | vt 0.116241 0.232996
1214 | vt 0.137627 0.125481
1215 | vt 0.137627 0.235103
1216 | vt 0.095676 0.226758
1217 | vt 0.076724 0.216629
1218 | vt 0.060112 0.202996
1219 | vt 0.046480 0.186384
1220 | vt 0.036350 0.167432
1221 | vt 0.030112 0.146867
1222 | vt 0.028005 0.125481
1223 | vt 0.030112 0.104095
1224 | vt 0.036350 0.083531
1225 | vt 0.046480 0.064579
1226 | vt 0.060112 0.047967
1227 | vt 0.076724 0.034334
1228 | vt 0.095676 0.024204
1229 | vt 0.116241 0.017966
1230 | vt 0.137627 0.015859
1231 | vt 0.159013 0.017966
1232 | vt 0.179577 0.024204
1233 | vt 0.198530 0.034334
1234 | vt 0.215141 0.047967
1235 | vt 0.228774 0.064579
1236 | vt 0.238904 0.083531
1237 | vt 0.245142 0.104095
1238 | vt 0.247249 0.125481
1239 | vt 0.245142 0.146867
1240 | vt 0.238904 0.167432
1241 | vt 0.228774 0.186384
1242 | vt 0.215141 0.202996
1243 | vt 0.198530 0.216629
1244 | vt 0.179577 0.226758
1245 | vt 0.159013 0.232996
1246 | s 0
1247 | usemtl MI_YamahaMSP3_MatteBlack.010
1248 | f 196/391/141 220/392/141 212/393/141
1249 | f 204/394/141 200/395/141 196/391/141
1250 | f 212/393/141 208/396/141 204/394/141
1251 | f 220/392/141 216/397/141 212/393/141
1252 | f 196/391/141 224/398/141 220/392/141
1253 | f 200/395/141 198/399/141 196/391/141
1254 | f 204/394/141 202/400/141 200/395/141
1255 | f 208/396/141 206/401/141 204/394/141
1256 | f 212/393/141 210/402/141 208/396/141
1257 | f 216/397/141 214/403/141 212/393/141
1258 | f 220/392/141 218/404/141 216/397/141
1259 | f 224/398/141 222/405/141 220/392/141
1260 | f 196/391/141 226/406/141 224/398/141
1261 | f 198/399/142 197/407/142 196/391/142
1262 | f 200/395/143 199/408/143 198/399/143
1263 | f 202/400/141 201/409/141 200/395/141
1264 | f 204/394/141 203/410/141 202/400/141
1265 | f 206/401/141 205/411/141 204/394/141
1266 | f 208/396/142 207/412/142 206/401/142
1267 | f 210/402/143 209/413/143 208/396/143
1268 | f 212/393/141 211/414/141 210/402/141
1269 | f 214/403/143 213/415/143 212/393/143
1270 | f 216/397/142 215/416/142 214/403/142
1271 | f 218/404/141 217/417/141 216/397/141
1272 | f 220/392/141 219/418/141 218/404/141
1273 | f 222/405/141 221/419/141 220/392/141
1274 | f 224/398/143 223/420/143 222/405/143
1275 | f 226/406/142 225/421/142 224/398/142
1276 | f 196/391/141 227/422/141 226/406/141
1277 | f 196/423/144 195/424/144 227/425/144
1278 | f 197/426/145 195/424/145 196/423/145
1279 | f 212/393/141 204/394/141 196/391/141
1280 | f 198/427/146 195/424/146 197/426/146
1281 | f 199/428/147 195/424/147 198/427/147
1282 | f 200/429/148 195/424/148 199/428/148
1283 | f 201/430/149 195/424/149 200/429/149
1284 | f 202/431/150 195/424/150 201/430/150
1285 | f 203/432/151 195/424/151 202/431/151
1286 | f 204/433/152 195/424/152 203/432/152
1287 | f 205/434/153 195/424/153 204/433/153
1288 | f 206/435/154 195/424/154 205/434/154
1289 | f 207/436/155 195/424/155 206/435/155
1290 | f 208/437/156 195/424/156 207/436/156
1291 | f 209/438/157 195/424/157 208/437/157
1292 | f 210/439/158 195/424/158 209/438/158
1293 | f 211/440/159 195/424/159 210/439/159
1294 | f 212/441/160 195/424/160 211/440/160
1295 | f 213/442/161 195/424/161 212/441/161
1296 | f 214/443/162 195/424/162 213/442/162
1297 | f 215/444/163 195/424/163 214/443/163
1298 | f 216/445/164 195/424/164 215/444/164
1299 | f 217/446/165 195/424/165 216/445/165
1300 | f 218/447/166 195/424/166 217/446/166
1301 | f 219/448/167 195/424/167 218/447/167
1302 | f 220/449/168 195/424/168 219/448/168
1303 | f 221/450/169 195/424/169 220/449/169
1304 | f 222/451/170 195/424/170 221/450/170
1305 | f 223/452/171 195/424/171 222/451/171
1306 | f 224/453/172 195/424/172 223/452/172
1307 | f 225/454/173 195/424/173 224/453/173
1308 | f 226/455/174 195/424/174 225/454/174
1309 | f 227/425/175 195/424/175 226/455/175
1310 | o Zzhu
1311 | v -0.097545 24.000000 -0.490395
1312 | v -0.097545 -0.000000 -0.490393
1313 | v -0.191342 24.000000 -0.461942
1314 | v -0.191342 -0.000000 -0.461940
1315 | v -0.277785 24.000000 -0.415737
1316 | v -0.277785 -0.000000 -0.415735
1317 | v -0.353553 24.000000 -0.353555
1318 | v -0.353553 -0.000000 -0.353553
1319 | v -0.415735 24.000000 -0.277787
1320 | v -0.415735 -0.000000 -0.277785
1321 | v -0.461940 24.000000 -0.191344
1322 | v -0.461940 -0.000000 -0.191342
1323 | v -0.490393 24.000000 -0.097547
1324 | v -0.490393 -0.000000 -0.097545
1325 | v -0.500000 24.000000 -0.000002
1326 | v -0.500000 0.000000 0.000000
1327 | v -0.490393 24.000000 0.097543
1328 | v -0.490393 0.000000 0.097545
1329 | v -0.461940 24.000000 0.191340
1330 | v -0.461940 0.000000 0.191342
1331 | v -0.415735 24.000000 0.277783
1332 | v -0.415735 0.000000 0.277785
1333 | v -0.353553 24.000000 0.353551
1334 | v -0.353553 0.000000 0.353553
1335 | v -0.277785 24.000000 0.415733
1336 | v -0.277785 0.000000 0.415735
1337 | v -0.191342 24.000000 0.461938
1338 | v -0.191342 0.000000 0.461940
1339 | v -0.097545 24.000000 0.490391
1340 | v -0.097545 0.000000 0.490393
1341 | v 0.000000 24.000000 0.499998
1342 | v 0.000000 0.000000 0.500000
1343 | v 0.097545 24.000000 0.490391
1344 | v 0.097545 0.000000 0.490393
1345 | v 0.191342 24.000000 0.461938
1346 | v 0.191342 0.000000 0.461940
1347 | v 0.277785 24.000000 0.415733
1348 | v 0.277785 0.000000 0.415735
1349 | v 0.353553 24.000000 0.353551
1350 | v 0.353553 0.000000 0.353553
1351 | v 0.415735 24.000000 0.277783
1352 | v 0.415735 0.000000 0.277785
1353 | v 0.461940 24.000000 0.191340
1354 | v 0.461940 0.000000 0.191342
1355 | v 0.490393 24.000000 0.097543
1356 | v 0.490393 0.000000 0.097545
1357 | v 0.500000 24.000000 -0.000002
1358 | v 0.500000 0.000000 0.000000
1359 | v 0.490393 24.000000 -0.097547
1360 | v 0.490393 -0.000000 -0.097545
1361 | v 0.461940 24.000000 -0.191344
1362 | v 0.461940 -0.000000 -0.191342
1363 | v 0.415735 24.000000 -0.277787
1364 | v 0.415735 -0.000000 -0.277785
1365 | v 0.353553 24.000000 -0.353555
1366 | v 0.353553 -0.000000 -0.353553
1367 | v 0.277785 24.000000 -0.415737
1368 | v 0.277785 -0.000000 -0.415735
1369 | v 0.191342 24.000000 -0.461942
1370 | v 0.191342 -0.000000 -0.461940
1371 | v 0.097545 24.000000 -0.490395
1372 | v 0.097545 -0.000000 -0.490393
1373 | v 0.000000 24.000000 -0.500002
1374 | v 0.000000 -0.000000 -0.500000
1375 | vn -0.0000 -1.0000 -0.0000
1376 | vn -0.0980 -0.0000 -0.9952
1377 | vn -0.2903 -0.0000 -0.9569
1378 | vn -0.0000 1.0000 -0.0000
1379 | vn -0.4714 -0.0000 -0.8819
1380 | vn -0.6344 -0.0000 -0.7730
1381 | vn -0.7730 -0.0000 -0.6344
1382 | vn -0.8819 -0.0000 -0.4714
1383 | vn -0.9569 -0.0000 -0.2903
1384 | vn -0.9952 -0.0000 -0.0980
1385 | vn -0.9952 -0.0000 0.0980
1386 | vn -0.9569 -0.0000 0.2903
1387 | vn -0.8819 -0.0000 0.4714
1388 | vn -0.7730 -0.0000 0.6344
1389 | vn -0.6344 -0.0000 0.7730
1390 | vn -0.4714 -0.0000 0.8819
1391 | vn -0.2903 -0.0000 0.9569
1392 | vn -0.0980 -0.0000 0.9952
1393 | vn 0.0980 -0.0000 0.9952
1394 | vn 0.2903 -0.0000 0.9569
1395 | vn 0.4714 -0.0000 0.8819
1396 | vn 0.6344 -0.0000 0.7730
1397 | vn 0.7730 -0.0000 0.6344
1398 | vn 0.8819 -0.0000 0.4714
1399 | vn 0.9569 -0.0000 0.2903
1400 | vn 0.9952 -0.0000 0.0980
1401 | vn 0.9952 -0.0000 -0.0980
1402 | vn 0.9569 -0.0000 -0.2903
1403 | vn 0.8819 -0.0000 -0.4714
1404 | vn 0.7730 -0.0000 -0.6344
1405 | vn 0.6344 -0.0000 -0.7730
1406 | vn 0.4714 -0.0000 -0.8819
1407 | vn 0.2903 -0.0000 -0.9569
1408 | vn 0.0980 -0.0000 -0.9952
1409 | vt 0.344619 0.232996
1410 | vt 0.473521 0.146867
1411 | vt 0.387392 0.017966
1412 | vt 0.258490 0.104095
1413 | vt 0.274858 0.186384
1414 | vt 0.305103 0.034334
1415 | vt 0.457153 0.064579
1416 | vt 0.426908 0.216629
1417 | vt 0.305103 0.216629
1418 | vt 0.258490 0.146867
1419 | vt 0.274858 0.064579
1420 | vt 0.344619 0.017966
1421 | vt 0.426908 0.034334
1422 | vt 0.473521 0.104095
1423 | vt 0.457153 0.186384
1424 | vt 0.387392 0.232996
1425 | vt 0.324055 0.226758
1426 | vt 0.288491 0.202996
1427 | vt 0.264728 0.167432
1428 | vt 0.256384 0.125481
1429 | vt 0.264728 0.083531
1430 | vt 0.288491 0.047967
1431 | vt 0.324055 0.024204
1432 | vt 0.366006 0.015859
1433 | vt 0.407956 0.024204
1434 | vt 0.443520 0.047967
1435 | vt 0.467283 0.083531
1436 | vt 0.475627 0.125481
1437 | vt 0.467283 0.167432
1438 | vt 0.443520 0.202996
1439 | vt 0.407956 0.226758
1440 | vt 0.366006 0.235103
1441 | vt 0.037711 0.468049
1442 | vt 0.023437 0.468049
1443 | vt 0.023437 0.239671
1444 | vt 0.051985 0.468049
1445 | vt 0.037711 0.239671
1446 | vt 0.179577 0.226758
1447 | vt 0.036350 0.167432
1448 | vt 0.095676 0.024204
1449 | vt 0.238904 0.083531
1450 | vt 0.238904 0.167432
1451 | vt 0.179577 0.024204
1452 | vt 0.036350 0.083531
1453 | vt 0.095676 0.226758
1454 | vt 0.215141 0.202996
1455 | vt 0.247249 0.125481
1456 | vt 0.215141 0.047967
1457 | vt 0.137627 0.015859
1458 | vt 0.060112 0.047967
1459 | vt 0.028005 0.125481
1460 | vt 0.060112 0.202996
1461 | vt 0.137627 0.235103
1462 | vt 0.198530 0.216629
1463 | vt 0.228774 0.186384
1464 | vt 0.245142 0.146867
1465 | vt 0.245142 0.104095
1466 | vt 0.228774 0.064579
1467 | vt 0.198530 0.034334
1468 | vt 0.159013 0.017966
1469 | vt 0.116241 0.017966
1470 | vt 0.076724 0.034334
1471 | vt 0.046480 0.064579
1472 | vt 0.030112 0.104095
1473 | vt 0.030112 0.146867
1474 | vt 0.046480 0.186384
1475 | vt 0.076724 0.216629
1476 | vt 0.116241 0.232996
1477 | vt 0.159013 0.232996
1478 | vt 0.066259 0.468049
1479 | vt 0.051985 0.239671
1480 | vt 0.080532 0.468049
1481 | vt 0.066259 0.239671
1482 | vt 0.094806 0.468049
1483 | vt 0.080532 0.239671
1484 | vt 0.109080 0.468049
1485 | vt 0.094806 0.239671
1486 | vt 0.123353 0.468049
1487 | vt 0.109080 0.239671
1488 | vt 0.137627 0.468049
1489 | vt 0.123353 0.239671
1490 | vt 0.151901 0.468049
1491 | vt 0.137627 0.239671
1492 | vt 0.166174 0.468049
1493 | vt 0.151901 0.239671
1494 | vt 0.180448 0.468049
1495 | vt 0.166174 0.239671
1496 | vt 0.194722 0.468049
1497 | vt 0.180448 0.239671
1498 | vt 0.208995 0.468049
1499 | vt 0.194722 0.239671
1500 | vt 0.223269 0.468049
1501 | vt 0.208995 0.239671
1502 | vt 0.237543 0.468049
1503 | vt 0.223269 0.239671
1504 | vt 0.251816 0.468049
1505 | vt 0.237543 0.239671
1506 | vt 0.266090 0.468049
1507 | vt 0.251816 0.239671
1508 | vt 0.280364 0.468049
1509 | vt 0.266090 0.239671
1510 | vt 0.294637 0.468049
1511 | vt 0.280364 0.239671
1512 | vt 0.308911 0.468049
1513 | vt 0.294637 0.239671
1514 | vt 0.323185 0.468049
1515 | vt 0.308911 0.239671
1516 | vt 0.337458 0.468049
1517 | vt 0.323185 0.239671
1518 | vt 0.351732 0.468049
1519 | vt 0.337458 0.239671
1520 | vt 0.366006 0.468049
1521 | vt 0.351732 0.239671
1522 | vt 0.380279 0.468049
1523 | vt 0.366006 0.239671
1524 | vt 0.394553 0.468049
1525 | vt 0.380279 0.239671
1526 | vt 0.408827 0.468049
1527 | vt 0.394553 0.239671
1528 | vt 0.423100 0.468049
1529 | vt 0.408827 0.239671
1530 | vt 0.437374 0.468049
1531 | vt 0.423100 0.239671
1532 | vt 0.451648 0.468049
1533 | vt 0.437374 0.239671
1534 | vt 0.465921 0.468049
1535 | vt 0.451648 0.239671
1536 | vt 0.480195 0.468049
1537 | vt 0.465921 0.239671
1538 | vt 0.480195 0.239671
1539 | s 0
1540 | usemtl MI_YamahaMSP3_MatteBlack.010
1541 | f 229/456/176 277/457/176 261/458/176
1542 | f 245/459/176 237/460/176 229/456/176
1543 | f 261/458/176 253/461/176 245/459/176
1544 | f 277/457/176 269/462/176 261/458/176
1545 | f 229/456/176 285/463/176 277/457/176
1546 | f 237/460/176 233/464/176 229/456/176
1547 | f 245/459/176 241/465/176 237/460/176
1548 | f 253/461/176 249/466/176 245/459/176
1549 | f 261/458/176 257/467/176 253/461/176
1550 | f 269/462/176 265/468/176 261/458/176
1551 | f 277/457/176 273/469/176 269/462/176
1552 | f 285/463/176 281/470/176 277/457/176
1553 | f 229/456/176 289/471/176 285/463/176
1554 | f 233/464/176 231/472/176 229/456/176
1555 | f 237/460/176 235/473/176 233/464/176
1556 | f 241/465/176 239/474/176 237/460/176
1557 | f 245/459/176 243/475/176 241/465/176
1558 | f 249/466/176 247/476/176 245/459/176
1559 | f 253/461/176 251/477/176 249/466/176
1560 | f 257/467/176 255/478/176 253/461/176
1561 | f 261/458/176 259/479/176 257/467/176
1562 | f 265/468/176 263/480/176 261/458/176
1563 | f 269/462/176 267/481/176 265/468/176
1564 | f 273/469/176 271/482/176 269/462/176
1565 | f 277/457/176 275/483/176 273/469/176
1566 | f 281/470/176 279/484/176 277/457/176
1567 | f 285/463/176 283/485/176 281/470/176
1568 | f 289/471/176 287/486/176 285/463/176
1569 | f 229/456/176 291/487/176 289/471/176
1570 | f 228/488/177 290/489/177 291/490/177
1571 | f 230/491/178 228/488/178 229/492/178
1572 | f 286/493/179 238/494/179 254/495/179
1573 | f 270/496/179 278/497/179 286/493/179
1574 | f 254/495/179 262/498/179 270/496/179
1575 | f 238/494/179 246/499/179 254/495/179
1576 | f 286/493/179 230/500/179 238/494/179
1577 | f 278/497/179 282/501/179 286/493/179
1578 | f 270/496/179 274/502/179 278/497/179
1579 | f 262/498/179 266/503/179 270/496/179
1580 | f 254/495/179 258/504/179 262/498/179
1581 | f 246/499/179 250/505/179 254/495/179
1582 | f 238/494/179 242/506/179 246/499/179
1583 | f 230/500/179 234/507/179 238/494/179
1584 | f 286/493/179 290/508/179 230/500/179
1585 | f 282/501/179 284/509/179 286/493/179
1586 | f 278/497/179 280/510/179 282/501/179
1587 | f 274/502/179 276/511/179 278/497/179
1588 | f 270/496/179 272/512/179 274/502/179
1589 | f 266/503/179 268/513/179 270/496/179
1590 | f 262/498/179 264/514/179 266/503/179
1591 | f 258/504/179 260/515/179 262/498/179
1592 | f 254/495/179 256/516/179 258/504/179
1593 | f 250/505/179 252/517/179 254/495/179
1594 | f 246/499/179 248/518/179 250/505/179
1595 | f 242/506/179 244/519/179 246/499/179
1596 | f 238/494/179 240/520/179 242/506/179
1597 | f 234/507/179 236/521/179 238/494/179
1598 | f 230/500/179 232/522/179 234/507/179
1599 | f 290/508/179 228/523/179 230/500/179
1600 | f 286/493/179 288/524/179 290/508/179
1601 | f 232/525/180 230/491/180 231/526/180
1602 | f 234/527/181 232/525/181 233/528/181
1603 | f 236/529/182 234/527/182 235/530/182
1604 | f 238/531/183 236/529/183 237/532/183
1605 | f 240/533/184 238/531/184 239/534/184
1606 | f 242/535/185 240/533/185 241/536/185
1607 | f 244/537/186 242/535/186 243/538/186
1608 | f 246/539/187 244/537/187 245/540/187
1609 | f 248/541/188 246/539/188 247/542/188
1610 | f 250/543/189 248/541/189 249/544/189
1611 | f 252/545/190 250/543/190 251/546/190
1612 | f 254/547/191 252/545/191 253/548/191
1613 | f 256/549/192 254/547/192 255/550/192
1614 | f 258/551/193 256/549/193 257/552/193
1615 | f 260/553/194 258/551/194 259/554/194
1616 | f 262/555/195 260/553/195 261/556/195
1617 | f 264/557/196 262/555/196 263/558/196
1618 | f 266/559/197 264/557/197 265/560/197
1619 | f 268/561/198 266/559/198 267/562/198
1620 | f 270/563/199 268/561/199 269/564/199
1621 | f 272/565/200 270/563/200 271/566/200
1622 | f 274/567/201 272/565/201 273/568/201
1623 | f 276/569/202 274/567/202 275/570/202
1624 | f 278/571/203 276/569/203 277/572/203
1625 | f 280/573/204 278/571/204 279/574/204
1626 | f 282/575/205 280/573/205 281/576/205
1627 | f 284/577/206 282/575/206 283/578/206
1628 | f 286/579/207 284/577/207 285/580/207
1629 | f 288/581/208 286/579/208 287/582/208
1630 | f 290/583/209 288/581/209 289/584/209
1631 | f 261/458/176 245/459/176 229/456/176
1632 | f 228/488/177 291/490/177 229/492/177
1633 | f 230/491/178 229/492/178 231/526/178
1634 | f 254/495/179 270/496/179 286/493/179
1635 | f 232/525/180 231/526/180 233/528/180
1636 | f 234/527/181 233/528/181 235/530/181
1637 | f 236/529/182 235/530/182 237/532/182
1638 | f 238/531/183 237/532/183 239/534/183
1639 | f 240/533/184 239/534/184 241/536/184
1640 | f 242/535/185 241/536/185 243/538/185
1641 | f 244/537/186 243/538/186 245/540/186
1642 | f 246/539/187 245/540/187 247/542/187
1643 | f 248/541/188 247/542/188 249/544/188
1644 | f 250/543/189 249/544/189 251/546/189
1645 | f 252/545/190 251/546/190 253/548/190
1646 | f 254/547/191 253/548/191 255/550/191
1647 | f 256/549/192 255/550/192 257/552/192
1648 | f 258/551/193 257/552/193 259/554/193
1649 | f 260/553/194 259/554/194 261/556/194
1650 | f 262/555/195 261/556/195 263/558/195
1651 | f 264/557/196 263/558/196 265/560/196
1652 | f 266/559/197 265/560/197 267/562/197
1653 | f 268/561/198 267/562/198 269/564/198
1654 | f 270/563/199 269/564/199 271/566/199
1655 | f 272/565/200 271/566/200 273/568/200
1656 | f 274/567/201 273/568/201 275/570/201
1657 | f 276/569/202 275/570/202 277/572/202
1658 | f 278/571/203 277/572/203 279/574/203
1659 | f 280/573/204 279/574/204 281/576/204
1660 | f 282/575/205 281/576/205 283/578/205
1661 | f 284/577/206 283/578/206 285/580/206
1662 | f 286/579/207 285/580/207 287/582/207
1663 | f 288/581/208 287/582/208 289/584/208
1664 | f 290/583/209 289/584/209 291/585/209
1665 |
--------------------------------------------------------------------------------
/assets/axis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpatialVision/Orient-Anything/fbbaf97e25e9ce1c6b5cbeb515f9c5ce9e83b1fc/assets/axis.png
--------------------------------------------------------------------------------
/assets/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpatialVision/Orient-Anything/fbbaf97e25e9ce1c6b5cbeb515f9c5ce9e83b1fc/assets/demo.png
--------------------------------------------------------------------------------
/inference.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from PIL import Image
3 | from utils import *
4 | import torch.nn.functional as F
5 | import numpy as np
6 |
7 | def get_3angle(image, dino, val_preprocess, device):
8 |
9 | # image = Image.open(image_path).convert('RGB')
10 | image_inputs = val_preprocess(images = image)
11 | image_inputs['pixel_values'] = torch.from_numpy(np.array(image_inputs['pixel_values'])).to(device)
12 | with torch.no_grad():
13 | dino_pred = dino(image_inputs)
14 |
15 | gaus_ax_pred = torch.argmax(dino_pred[:, 0:360], dim=-1)
16 | gaus_pl_pred = torch.argmax(dino_pred[:, 360:360+180], dim=-1)
17 | gaus_ro_pred = torch.argmax(dino_pred[:, 360+180:360+180+180], dim=-1)
18 | confidence = F.softmax(dino_pred[:, -2:], dim=-1)[0][0]
19 | angles = torch.zeros(4)
20 | angles[0] = gaus_ax_pred
21 | angles[1] = gaus_pl_pred - 90
22 | angles[2] = gaus_ro_pred - 90
23 | angles[3] = confidence
24 | return angles
25 |
26 | def get_3angle_infer_aug(origin_img, rm_bkg_img, dino, val_preprocess, device):
27 |
28 | # image = Image.open(image_path).convert('RGB')
29 | image = get_crop_images(origin_img, num=3) + get_crop_images(rm_bkg_img, num=3)
30 | image_inputs = val_preprocess(images = image)
31 | image_inputs['pixel_values'] = torch.from_numpy(np.array(image_inputs['pixel_values'])).to(device)
32 | with torch.no_grad():
33 | dino_pred = dino(image_inputs)
34 |
35 | gaus_ax_pred = torch.argmax(dino_pred[:, 0:360], dim=-1).to(torch.float32)
36 | gaus_pl_pred = torch.argmax(dino_pred[:, 360:360+180], dim=-1).to(torch.float32)
37 | gaus_ro_pred = torch.argmax(dino_pred[:, 360+180:360+180+180], dim=-1).to(torch.float32)
38 |
39 | gaus_ax_pred = remove_outliers_and_average_circular(gaus_ax_pred)
40 | gaus_pl_pred = remove_outliers_and_average(gaus_pl_pred)
41 | gaus_ro_pred = remove_outliers_and_average(gaus_ro_pred)
42 |
43 | confidence = torch.mean(F.softmax(dino_pred[:, -2:], dim=-1), dim=0)[0]
44 | angles = torch.zeros(4)
45 | angles[0] = gaus_ax_pred
46 | angles[1] = gaus_pl_pred - 90
47 | angles[2] = gaus_ro_pred - 90
48 | angles[3] = confidence
49 | return angles
--------------------------------------------------------------------------------
/paths.py:
--------------------------------------------------------------------------------
1 | DINO_SMALL = "facebook/dinov2-small"
2 | DINO_BASE = "facebook/dinov2-base"
3 | DINO_LARGE = "facebook/dinov2-large"
4 | DINO_GIANT = "facebook/dinov2-giant"
--------------------------------------------------------------------------------
/render/__init__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa
2 | from .core import render
3 | from .model import Model
4 |
--------------------------------------------------------------------------------
/render/canvas.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | from PIL import Image, ImageColor, ImageOps, ImageChops, ImageFilter
4 | import numpy as np
5 |
6 | class Canvas:
7 | def __init__(self, filename=None, height=500, width=500):
8 | self.filename = filename
9 | self.height, self.width = height, width
10 | self.img = Image.new("RGBA", (self.height, self.width), (0, 0, 0, 0))
11 |
12 | def draw(self, dots, color: t.Union[tuple, str]):
13 | if isinstance(color, str):
14 | color = ImageColor.getrgb(color)
15 | if isinstance(dots, tuple):
16 | dots = [dots]
17 | for dot in dots:
18 | if dot[0]>=self.height or dot[1]>=self.width or dot[0]<0 or dot[1]<0:
19 | # print(dot)
20 | continue
21 | self.img.putpixel(dot, color + (255,))
22 |
23 | def add_white_border(self, border_size=5):
24 | # 确保输入图像是 RGBA 模式
25 | if self.img.mode != "RGBA":
26 | self.img = self.img.convert("RGBA")
27 |
28 | # 提取 alpha 通道
29 | alpha = self.img.getchannel("A")
30 | # print(alpha.size)
31 | dilated_alpha = alpha.filter(ImageFilter.MaxFilter(size=5))
32 | # # print(dilated_alpha.size)
33 | white_area = Image.new("RGBA", self.img.size, (255, 255, 255, 255))
34 | white_area.putalpha(dilated_alpha)
35 |
36 | # 合并膨胀后的白色区域与原图像
37 | result = Image.alpha_composite(white_area, self.img)
38 | # expanded_alpha = ImageOps.expand(alpha, border=border_size, fill=255)
39 | # white_border = Image.new("RGBA", image.size, (255, 255, 255, 255))
40 | # white_border.putalpha(alpha)
41 | return result
42 |
43 | def __enter__(self):
44 | return self
45 |
46 | def __exit__(self, type, value, traceback):
47 | # self.img = add_white_border(self.img)
48 | self.img.save(self.filename)
49 | pass
50 |
--------------------------------------------------------------------------------
/render/core.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 | from functools import partial
3 |
4 | import numpy as np
5 | from copy import deepcopy
6 | from .canvas import Canvas
7 |
8 | from . import speedup
9 |
10 |
11 | # 2D part
12 |
13 |
14 | class Vec2d:
15 | __slots__ = "x", "y", "arr"
16 |
17 | def __init__(self, *args):
18 | if len(args) == 1 and isinstance(args[0], Vec3d):
19 | self.arr = Vec3d.narr
20 | else:
21 | assert len(args) == 2
22 | self.arr = list(args)
23 |
24 | self.x, self.y = [d if isinstance(d, int) else int(d + 0.5) for d in self.arr]
25 |
26 | def __repr__(self):
27 | return f"Vec2d({self.x}, {self.y})"
28 |
29 | def __truediv__(self, other):
30 | return (self.y - other.y) / (self.x - other.x)
31 |
32 | def __eq__(self, other):
33 | return self.x == other.x and self.y == other.y
34 |
35 |
36 | def draw_line(
37 | v1: Vec2d, v2: Vec2d, canvas: Canvas, color: t.Union[tuple, str] = "white"
38 | ):
39 | """
40 | Draw a line with a specified color
41 |
42 | https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
43 | """
44 | v1, v2 = deepcopy(v1), deepcopy(v2)
45 | if v1 == v2:
46 | canvas.draw((v1.x, v1.y), color=color)
47 | return
48 |
49 | steep = abs(v1.y - v2.y) > abs(v1.x - v2.x)
50 | if steep:
51 | v1.x, v1.y = v1.y, v1.x
52 | v2.x, v2.y = v2.y, v2.x
53 | v1, v2 = (v1, v2) if v1.x < v2.x else (v2, v1)
54 | slope = abs((v1.y - v2.y) / (v1.x - v2.x))
55 | y = v1.y
56 | error: float = 0
57 | incr = 1 if v1.y < v2.y else -1
58 | dots = []
59 | for x in range(int(v1.x), int(v2.x + 0.5)):
60 | dots.append((int(y), x) if steep else (x, int(y)))
61 | error += slope
62 | if abs(error) >= 0.5:
63 | y += incr
64 | error -= 1
65 |
66 | canvas.draw(dots, color=color)
67 |
68 |
69 | def draw_triangle(v1, v2, v3, canvas, color, wireframe=False):
70 | """
71 | Draw a triangle with 3 ordered vertices
72 |
73 | http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
74 | """
75 | _draw_line = partial(draw_line, canvas=canvas, color=color)
76 |
77 | if wireframe:
78 | _draw_line(v1, v2)
79 | _draw_line(v2, v3)
80 | _draw_line(v1, v3)
81 | return
82 |
83 | def sort_vertices_asc_by_y(vertices):
84 | return sorted(vertices, key=lambda v: v.y)
85 |
86 | def fill_bottom_flat_triangle(v1, v2, v3):
87 | invslope1 = (v2.x - v1.x) / (v2.y - v1.y)
88 | invslope2 = (v3.x - v1.x) / (v3.y - v1.y)
89 |
90 | x1 = x2 = v1.x
91 | y = v1.y
92 |
93 | while y <= v2.y:
94 | _draw_line(Vec2d(x1, y), Vec2d(x2, y))
95 | x1 += invslope1
96 | x2 += invslope2
97 | y += 1
98 |
99 | def fill_top_flat_triangle(v1, v2, v3):
100 | invslope1 = (v3.x - v1.x) / (v3.y - v1.y)
101 | invslope2 = (v3.x - v2.x) / (v3.y - v2.y)
102 |
103 | x1 = x2 = v3.x
104 | y = v3.y
105 |
106 | while y > v2.y:
107 | _draw_line(Vec2d(x1, y), Vec2d(x2, y))
108 | x1 -= invslope1
109 | x2 -= invslope2
110 | y -= 1
111 |
112 | v1, v2, v3 = sort_vertices_asc_by_y((v1, v2, v3))
113 |
114 | # 填充
115 | if v1.y == v2.y == v3.y:
116 | pass
117 | elif v2.y == v3.y:
118 | fill_bottom_flat_triangle(v1, v2, v3)
119 | elif v1.y == v2.y:
120 | fill_top_flat_triangle(v1, v2, v3)
121 | else:
122 | v4 = Vec2d(int(v1.x + (v2.y - v1.y) / (v3.y - v1.y) * (v3.x - v1.x)), v2.y)
123 | fill_bottom_flat_triangle(v1, v2, v4)
124 | fill_top_flat_triangle(v2, v4, v3)
125 |
126 |
127 | # 3D part
128 |
129 |
130 | class Vec3d:
131 | __slots__ = "x", "y", "z", "arr"
132 |
133 | def __init__(self, *args):
134 | # for Vec4d cast
135 | if len(args) == 1 and isinstance(args[0], Vec4d):
136 | vec4 = args[0]
137 | arr_value = (vec4.x, vec4.y, vec4.z)
138 | else:
139 | assert len(args) == 3
140 | arr_value = args
141 | self.arr = np.array(arr_value, dtype=np.float64)
142 | self.x, self.y, self.z = self.arr
143 |
144 | def __repr__(self):
145 | return repr(f"Vec3d({','.join([repr(d) for d in self.arr])})")
146 |
147 | def __sub__(self, other):
148 | return self.__class__(*[ds - do for ds, do in zip(self.arr, other.arr)])
149 |
150 | def __bool__(self):
151 | """ False for zero vector (0, 0, 0)
152 | """
153 | return any(self.arr)
154 |
155 |
156 | class Mat4d:
157 | def __init__(self, narr=None, value=None):
158 | self.value = np.matrix(narr) if value is None else value
159 |
160 | def __repr__(self):
161 | return repr(self.value)
162 |
163 | def __mul__(self, other):
164 | return self.__class__(value=self.value * other.value)
165 |
166 |
167 | class Vec4d(Mat4d):
168 | def __init__(self, *narr, value=None):
169 | if value is not None:
170 | self.value = value
171 | elif len(narr) == 1 and isinstance(narr[0], Mat4d):
172 | self.value = narr[0].value
173 | else:
174 | assert len(narr) == 4
175 | self.value = np.matrix([[d] for d in narr])
176 |
177 | self.x, self.y, self.z, self.w = (
178 | self.value[0, 0],
179 | self.value[1, 0],
180 | self.value[2, 0],
181 | self.value[3, 0],
182 | )
183 | self.arr = self.value.reshape((1, 4))
184 |
185 |
186 | # Math util
187 | def normalize(v: Vec3d):
188 | return Vec3d(*speedup.normalize(*v.arr))
189 |
190 |
191 | def dot_product(a: Vec3d, b: Vec3d):
192 | return speedup.dot_product(*a.arr, *b.arr)
193 |
194 |
195 | def cross_product(a: Vec3d, b: Vec3d):
196 | return Vec3d(*speedup.cross_product(*a.arr, *b.arr))
197 |
198 | BASE_LIGHT = 0.9
199 | def get_light_intensity(face) -> float:
200 | # lights = [Vec3d(-2, 4, -10), Vec3d(10, 4, -2), Vec3d(8, 8, -8), Vec3d(0, 0, -8)]
201 | lights = [Vec3d(-2, 4, -10)]
202 | # lights = []
203 |
204 | v1, v2, v3 = face
205 | up = normalize(cross_product(v2 - v1, v3 - v1))
206 | intensity = BASE_LIGHT
207 | for light in lights:
208 | intensity += dot_product(up, normalize(light))*0.2
209 | return intensity
210 |
211 |
212 | def look_at(eye: Vec3d, target: Vec3d, up: Vec3d = Vec3d(0, -1, 0)) -> Mat4d:
213 | """
214 | http://www.songho.ca/opengl/gl_camera.html#lookat
215 |
216 | Args:
217 | eye: 摄像机的世界坐标位置
218 | target: 观察点的位置
219 | up: 就是你想让摄像机立在哪个方向
220 | https://stackoverflow.com/questions/10635947/what-exactly-is-the-up-vector-in-opengls-lookat-function
221 | 这里默认使用了 0, -1, 0, 因为 blender 导出来的模型数据似乎有问题,导致y轴总是反的,于是把摄像机的up也翻一下得了。
222 | """
223 | f = normalize(eye - target)
224 | l = normalize(cross_product(up, f)) # noqa: E741
225 | u = cross_product(f, l)
226 |
227 | rotate_matrix = Mat4d(
228 | [[l.x, l.y, l.z, 0], [u.x, u.y, u.z, 0], [f.x, f.y, f.z, 0], [0, 0, 0, 1.0]]
229 | )
230 | translate_matrix = Mat4d(
231 | [[1, 0, 0, -eye.x], [0, 1, 0, -eye.y], [0, 0, 1, -eye.z], [0, 0, 0, 1.0]]
232 | )
233 |
234 | return Mat4d(value=(rotate_matrix * translate_matrix).value)
235 |
236 |
237 | def perspective_project(r, t, n, f, b=None, l=None): # noqa: E741
238 | """
239 | 目的:
240 | 把相机坐标转换成投影在视网膜的范围在(-1, 1)的笛卡尔坐标
241 |
242 | 原理:
243 | 对于x,y坐标,相似三角形可以算出投影点的x,y
244 | 对于z坐标,是假设了near是-1,far是1,然后带进去算的
245 | http://www.songho.ca/opengl/gl_projectionmatrix.html
246 | https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
247 |
248 | 推导出来的矩阵:
249 | [
250 | 2n/(r-l) 0 (r+l/r-l) 0
251 | 0 2n/(t-b) (t+b)/(t-b) 0
252 | 0 0 -(f+n)/f-n (-2*f*n)/(f-n)
253 | 0 0 -1 0
254 | ]
255 |
256 | 实际上由于我们用的视网膜(near pane)是个关于远点对称的矩形,所以矩阵简化为:
257 | [
258 | n/r 0 0 0
259 | 0 n/t 0 0
260 | 0 0 -(f+n)/f-n (-2*f*n)/(f-n)
261 | 0 0 -1 0
262 | ]
263 |
264 | Args:
265 | r: right, t: top, n: near, f: far, b: bottom, l: left
266 | """
267 | return Mat4d(
268 | [
269 | [n / r, 0, 0, 0],
270 | [0, n / t, 0, 0],
271 | [0, 0, -(f + n) / (f - n), (-2 * f * n) / (f - n)],
272 | [0, 0, -1, 0],
273 | ]
274 | )
275 |
276 |
277 | def draw(screen_vertices, world_vertices, model, canvas, wireframe=True):
278 | """standard algorithm
279 | """
280 | for triangle_indices in model.indices:
281 | vertex_group = [screen_vertices[idx - 1] for idx in triangle_indices]
282 | face = [Vec3d(world_vertices[idx - 1]) for idx in triangle_indices]
283 | if wireframe:
284 | draw_triangle(*vertex_group, canvas=canvas, color="black", wireframe=True)
285 | else:
286 | intensity = get_light_intensity(face)
287 | if intensity > 0:
288 | draw_triangle(
289 | *vertex_group, canvas=canvas, color=(int(intensity * 255),) * 3
290 | )
291 |
292 |
293 | def draw_with_z_buffer(screen_vertices, world_vertices, model, canvas):
294 | """ z-buffer algorithm
295 | """
296 | intensities = []
297 | triangles = []
298 | for i, triangle_indices in enumerate(model.indices):
299 | screen_triangle = [screen_vertices[idx - 1] for idx in triangle_indices]
300 | uv_triangle = [model.uv_vertices[idx - 1] for idx in model.uv_indices[i]]
301 | world_triangle = [Vec3d(world_vertices[idx - 1]) for idx in triangle_indices]
302 | intensities.append(abs(get_light_intensity(world_triangle)))
303 | # take off the class to let Cython work
304 | triangles.append(
305 | [np.append(screen_triangle[i].arr, uv_triangle[i]) for i in range(3)]
306 | )
307 |
308 | faces = speedup.generate_faces(
309 | np.array(triangles, dtype=np.float64), model.texture_width, model.texture_height
310 | )
311 | for face_dots in faces:
312 | for dot in face_dots:
313 | intensity = intensities[dot[0]]
314 | u, v = dot[3], dot[4]
315 | color = model.texture_array[u, v]
316 | canvas.draw((dot[1], dot[2]), tuple(int(c * intensity) for c in color[:3]))
317 | # TODO: add object rendering mode (no texture)
318 | # canvas.draw((dot[1], dot[2]), (int(255 * intensity),) * 3)
319 |
320 |
321 | def render(model, height, width, filename, cam_loc, wireframe=False):
322 | """
323 | Args:
324 | model: the Model object
325 | height: cavas height
326 | width: cavas width
327 | picname: picture file name
328 | """
329 | model_matrix = Mat4d([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
330 | # TODO: camera configration
331 | view_matrix = look_at(Vec3d(cam_loc[0], cam_loc[1], cam_loc[2]), Vec3d(0, 0, 0))
332 | projection_matrix = perspective_project(0.5, 0.5, 3, 1000)
333 |
334 | world_vertices = []
335 |
336 | def mvp(v):
337 | world_vertex = model_matrix * v
338 | world_vertices.append(Vec4d(world_vertex))
339 | return projection_matrix * view_matrix * world_vertex
340 |
341 | def ndc(v):
342 | """
343 | 各个坐标同时除以 w,得到 NDC 坐标
344 | """
345 | v = v.value
346 | w = v[3, 0]
347 | x, y, z = v[0, 0] / w, v[1, 0] / w, v[2, 0] / w
348 | return Mat4d([[x], [y], [z], [1 / w]])
349 |
350 | def viewport(v):
351 | x = y = 0
352 | w, h = width, height
353 | n, f = 0.3, 1000
354 | return Vec3d(
355 | w * 0.5 * v.value[0, 0] + x + w * 0.5,
356 | h * 0.5 * v.value[1, 0] + y + h * 0.5,
357 | 0.5 * (f - n) * v.value[2, 0] + 0.5 * (f + n),
358 | )
359 |
360 | # the render pipeline
361 | screen_vertices = [viewport(ndc(mvp(v))) for v in model.vertices]
362 |
363 | with Canvas(filename, height, width) as canvas:
364 | if wireframe:
365 | draw(screen_vertices, world_vertices, model, canvas)
366 | else:
367 | draw_with_z_buffer(screen_vertices, world_vertices, model, canvas)
368 |
369 | render_img = canvas.add_white_border().copy()
370 | return render_img
--------------------------------------------------------------------------------
/render/model.py:
--------------------------------------------------------------------------------
1 | import numpy
2 | from PIL import Image
3 | from .core import Vec4d
4 |
5 |
6 | class Model:
7 | def __init__(self, filename, texture_filename):
8 | """
9 | https://en.wikipedia.org/wiki/Wavefront_.obj_file#Vertex_normal_indices
10 | """
11 | self.vertices = []
12 | self.uv_vertices = []
13 | self.uv_indices = []
14 | self.indices = []
15 |
16 | texture = Image.open(texture_filename)
17 | self.texture_array = numpy.array(texture)
18 | self.texture_width, self.texture_height = texture.size
19 |
20 | with open(filename) as f:
21 | for line in f:
22 | if line.startswith("v "):
23 | x, y, z = [float(d) for d in line.strip("v").strip().split(" ")]
24 | self.vertices.append(Vec4d(x, y, z, 1))
25 | elif line.startswith("vt "):
26 | u, v = [float(d) for d in line.strip("vt").strip().split(" ")]
27 | self.uv_vertices.append([u, v])
28 | elif line.startswith("f "):
29 | facet = [d.split("/") for d in line.strip("f").strip().split(" ")]
30 | self.indices.append([int(d[0]) for d in facet])
31 | self.uv_indices.append([int(d[1]) for d in facet])
32 |
--------------------------------------------------------------------------------
/render/speedup.py:
--------------------------------------------------------------------------------
1 | # import cython
2 | import numpy as np
3 | from math import sqrt
4 |
5 |
6 | def normalize(x, y, z):
7 | unit = sqrt(x * x + y * y + z * z)
8 | if unit == 0:
9 | return 0, 0, 0
10 | return x / unit, y / unit, z / unit
11 |
12 |
13 | def get_min_max(a, b, c):
14 | min = a
15 | max = a
16 | if min > b:
17 | min = b
18 | if min > c:
19 | min = c
20 | if max < b:
21 | max = b
22 | if max < c:
23 | max = c
24 | return int(min), int(max)
25 |
26 | def dot_product(a0, a1, a2, b0, b1, b2):
27 | r = a0 * b0 + a1 * b1 + a2 * b2
28 | return r
29 |
30 |
31 | def cross_product(a0, a1, a2, b0, b1, b2):
32 | x = a1 * b2 - a2 * b1
33 | y = a2 * b0 - a0 * b2
34 | z = a0 * b1 - a1 * b0
35 | return x,y,z
36 |
37 |
38 | # @cython.boundscheck(False)
39 | def generate_faces(triangles, width, height):
40 | """ draw the triangle faces with z buffer
41 |
42 | Args:
43 | triangles: groups of vertices
44 |
45 | FYI:
46 | * zbuffer, https://github.com/ssloy/tinyrenderer/wiki/Lesson-3:-Hidden-faces-removal-(z-buffer)
47 | * uv mapping and perspective correction
48 | """
49 | i, j, k, length = 0, 0, 0, 0
50 | bcy, bcz, x, y, z = 0.,0.,0.,0.,0.
51 | a, b, c = [0.,0.,0.],[0.,0.,0.],[0.,0.,0.]
52 | m, bc = [0.,0.,0.],[0.,0.,0.]
53 | uva, uvb, uvc = [0.,0.],[0.,0.],[0.,0.]
54 | minx, maxx, miny, maxy = 0,0,0,0
55 | length = triangles.shape[0]
56 | zbuffer = {}
57 | faces = []
58 |
59 | for i in range(length):
60 | a = triangles[i, 0, 0], triangles[i, 0, 1], triangles[i, 0, 2]
61 | b = triangles[i, 1, 0], triangles[i, 1, 1], triangles[i, 1, 2]
62 | c = triangles[i, 2, 0], triangles[i, 2, 1], triangles[i, 2, 2]
63 | uva = triangles[i, 0, 3], triangles[i, 0, 4]
64 | uvb = triangles[i, 1, 3], triangles[i, 1, 4]
65 | uvc = triangles[i, 2, 3], triangles[i, 2, 4]
66 | minx, maxx = get_min_max(a[0], b[0], c[0])
67 | miny, maxy = get_min_max(a[1], b[1], c[1])
68 | pixels = []
69 | for j in range(minx, maxx + 2):
70 | for k in range(miny - 1, maxy + 2):
71 | # 必须显式转换成 double 参与底下的运算,不然结果是错的
72 | x = j
73 | y = k
74 |
75 | m[0], m[1], m[2] = cross_product(c[0] - a[0], b[0] - a[0], a[0] - x, c[1] - a[1], b[1] - a[1], a[1] - y)
76 | if abs(m[2]) > 0:
77 | bcy = m[1] / m[2]
78 | bcz = m[0] / m[2]
79 | bc = (1 - bcy - bcz, bcy, bcz)
80 | else:
81 | continue
82 |
83 | # here, -0.00001 because of the precision lose
84 | if bc[0] < -0.00001 or bc[1] < -0.00001 or bc[2] < -0.00001:
85 | continue
86 |
87 | z = 1 / (bc[0] / a[2] + bc[1] / b[2] + bc[2] / c[2])
88 |
89 | # Blender 导出来的 uv 数据,跟之前的顶点数据有一样的问题,Y轴是个反的,
90 | # 所以这里的纹理图片要旋转一下才能 work
91 | v = (uva[0] * bc[0] / a[2] + uvb[0] * bc[1] / b[2] + uvc[0] * bc[2] / c[2]) * z * width
92 | u = height - (uva[1] * bc[0] / a[2] + uvb[1] * bc[1] / b[2] + uvc[1] * bc[2] / c[2]) * z * height
93 |
94 | # https://en.wikipedia.org/wiki/Pairing_function
95 | idx = ((x + y) * (x + y + 1) + y) / 2
96 | if zbuffer.get(idx) is None or zbuffer[idx] < z:
97 | zbuffer[idx] = z
98 | pixels.append((i, j, k, int(u) - 1, int(v) - 1))
99 |
100 | faces.append(pixels)
101 | return faces
102 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | torch==2.2.1
2 | transformers==4.38
3 | matplotlib
4 | pillow==10.2.0
5 | huggingface-hub==0.26.5
6 | gradio==5.9.0
7 | numpy==1.26.4
8 | onnxruntime
9 | rembg
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import rembg
2 | import random
3 | import torch
4 | import numpy as np
5 | from PIL import Image, ImageOps
6 | import PIL
7 | from typing import Any
8 | import matplotlib.pyplot as plt
9 | import io
10 |
11 | def resize_foreground(
12 | image: Image,
13 | ratio: float,
14 | ) -> Image:
15 | image = np.array(image)
16 | assert image.shape[-1] == 4
17 | alpha = np.where(image[..., 3] > 0)
18 | y1, y2, x1, x2 = (
19 | alpha[0].min(),
20 | alpha[0].max(),
21 | alpha[1].min(),
22 | alpha[1].max(),
23 | )
24 | # crop the foreground
25 | fg = image[y1:y2, x1:x2]
26 | # pad to square
27 | size = max(fg.shape[0], fg.shape[1])
28 | ph0, pw0 = (size - fg.shape[0]) // 2, (size - fg.shape[1]) // 2
29 | ph1, pw1 = size - fg.shape[0] - ph0, size - fg.shape[1] - pw0
30 | new_image = np.pad(
31 | fg,
32 | ((ph0, ph1), (pw0, pw1), (0, 0)),
33 | mode="constant",
34 | constant_values=((0, 0), (0, 0), (0, 0)),
35 | )
36 |
37 | # compute padding according to the ratio
38 | new_size = int(new_image.shape[0] / ratio)
39 | # pad to size, double side
40 | ph0, pw0 = (new_size - size) // 2, (new_size - size) // 2
41 | ph1, pw1 = new_size - size - ph0, new_size - size - pw0
42 | new_image = np.pad(
43 | new_image,
44 | ((ph0, ph1), (pw0, pw1), (0, 0)),
45 | mode="constant",
46 | constant_values=((0, 0), (0, 0), (0, 0)),
47 | )
48 | new_image = Image.fromarray(new_image)
49 | return new_image
50 |
51 | def remove_background(image: Image,
52 | rembg_session: Any = None,
53 | force: bool = False,
54 | **rembg_kwargs,
55 | ) -> Image:
56 | do_remove = True
57 | if image.mode == "RGBA" and image.getextrema()[3][0] < 255:
58 | do_remove = False
59 | do_remove = do_remove or force
60 | if do_remove:
61 | image = rembg.remove(image, session=rembg_session, **rembg_kwargs)
62 | return image
63 |
64 | def random_crop(image, crop_scale=(0.8, 0.95)):
65 | """
66 | 随机裁切图片
67 | image (numpy.ndarray): (H, W, C)。
68 | crop_scale (tuple): (min_scale, max_scale)。
69 | """
70 | assert isinstance(image, Image.Image), "iput must be PIL.Image.Image"
71 | assert len(crop_scale) == 2 and 0 < crop_scale[0] <= crop_scale[1] <= 1
72 |
73 | width, height = image.size
74 |
75 | # 计算裁切的高度和宽度
76 | crop_width = random.randint(int(width * crop_scale[0]), int(width * crop_scale[1]))
77 | crop_height = random.randint(int(height * crop_scale[0]), int(height * crop_scale[1]))
78 |
79 | # 随机选择裁切的起始点
80 | left = random.randint(0, width - crop_width)
81 | top = random.randint(0, height - crop_height)
82 |
83 | # 裁切图片
84 | cropped_image = image.crop((left, top, left + crop_width, top + crop_height))
85 |
86 | return cropped_image
87 |
88 | def get_crop_images(img, num=3):
89 | cropped_images = []
90 | for i in range(num):
91 | cropped_images.append(random_crop(img))
92 | return cropped_images
93 |
94 | def background_preprocess(input_image, do_remove_background):
95 |
96 | rembg_session = rembg.new_session() if do_remove_background else None
97 |
98 | if do_remove_background:
99 | input_image = remove_background(input_image, rembg_session)
100 | input_image = resize_foreground(input_image, 0.85)
101 |
102 | return input_image
103 |
104 | def remove_outliers_and_average(tensor, threshold=1.5):
105 | assert tensor.dim() == 1, "dimension of input Tensor must equal to 1"
106 |
107 | q1 = torch.quantile(tensor, 0.25)
108 | q3 = torch.quantile(tensor, 0.75)
109 | iqr = q3 - q1
110 |
111 | lower_bound = q1 - threshold * iqr
112 | upper_bound = q3 + threshold * iqr
113 |
114 | non_outliers = tensor[(tensor >= lower_bound) & (tensor <= upper_bound)]
115 |
116 | if len(non_outliers) == 0:
117 | return tensor.mean().item()
118 |
119 | return non_outliers.mean().item()
120 |
121 |
122 | def remove_outliers_and_average_circular(tensor, threshold=1.5):
123 | assert tensor.dim() == 1, "dimension of input Tensor must equal to 1"
124 |
125 | # 将角度转换为二维平面上的点
126 | radians = tensor * torch.pi / 180.0
127 | x_coords = torch.cos(radians)
128 | y_coords = torch.sin(radians)
129 |
130 | # 计算平均向量
131 | mean_x = torch.mean(x_coords)
132 | mean_y = torch.mean(y_coords)
133 |
134 | differences = torch.sqrt((x_coords - mean_x) * (x_coords - mean_x) + (y_coords - mean_y) * (y_coords - mean_y))
135 |
136 | # 计算四分位数和 IQR
137 | q1 = torch.quantile(differences, 0.25)
138 | q3 = torch.quantile(differences, 0.75)
139 | iqr = q3 - q1
140 |
141 | # 计算上下限
142 | lower_bound = q1 - threshold * iqr
143 | upper_bound = q3 + threshold * iqr
144 |
145 | # 筛选非离群点
146 | non_outliers = tensor[(differences >= lower_bound) & (differences <= upper_bound)]
147 |
148 | if len(non_outliers) == 0:
149 | mean_angle = torch.atan2(mean_y, mean_x) * 180.0 / torch.pi
150 | mean_angle = (mean_angle + 360) % 360
151 | return mean_angle # 如果没有非离群点,返回 None
152 |
153 | # 对非离群点再次计算平均向量
154 | radians = non_outliers * torch.pi / 180.0
155 | x_coords = torch.cos(radians)
156 | y_coords = torch.sin(radians)
157 |
158 | mean_x = torch.mean(x_coords)
159 | mean_y = torch.mean(y_coords)
160 |
161 | mean_angle = torch.atan2(mean_y, mean_x) * 180.0 / torch.pi
162 | mean_angle = (mean_angle + 360) % 360
163 |
164 | return mean_angle
165 |
166 | def scale(x):
167 | # print(x)
168 | # if abs(x[0])<0.1 and abs(x[1])<0.1:
169 |
170 | # return x*5
171 | # else:
172 | # return x
173 | return x*3
174 |
175 | def get_proj2D_XYZ(phi, theta, gamma):
176 | x = np.array([-1*np.sin(phi)*np.cos(gamma) - np.cos(phi)*np.sin(theta)*np.sin(gamma), np.sin(phi)*np.sin(gamma) - np.cos(phi)*np.sin(theta)*np.cos(gamma)])
177 | y = np.array([-1*np.cos(phi)*np.cos(gamma) + np.sin(phi)*np.sin(theta)*np.sin(gamma), np.cos(phi)*np.sin(gamma) + np.sin(phi)*np.sin(theta)*np.cos(gamma)])
178 | z = np.array([np.cos(theta)*np.sin(gamma), np.cos(theta)*np.cos(gamma)])
179 | x = scale(x)
180 | y = scale(y)
181 | z = scale(z)
182 | return x, y, z
183 |
184 | # 绘制3D坐标轴
185 | def draw_axis(ax, origin, vector, color, label=None):
186 | ax.quiver(origin[0], origin[1], vector[0], vector[1], angles='xy', scale_units='xy', scale=1, color=color)
187 | if label!=None:
188 | ax.text(origin[0] + vector[0] * 1.1, origin[1] + vector[1] * 1.1, label, color=color, fontsize=12)
189 |
190 | def matplotlib_2D_arrow(angles, rm_bkg_img):
191 | fig, ax = plt.subplots(figsize=(8, 8))
192 |
193 | # 设置旋转角度
194 | phi = np.radians(angles[0])
195 | theta = np.radians(angles[1])
196 | gamma = np.radians(-1*angles[2])
197 |
198 | w, h = rm_bkg_img.size
199 | if h>w:
200 | extent = [-5*w/h, 5*w/h, -5, 5]
201 | else:
202 | extent = [-5, 5, -5*h/w, 5*h/w]
203 | ax.imshow(rm_bkg_img, extent=extent, zorder=0, aspect ='auto') # extent 设置图片的显示范围
204 |
205 | origin = np.array([0, 0])
206 |
207 | # 旋转后的向量
208 | rot_x, rot_y, rot_z = get_proj2D_XYZ(phi, theta, gamma)
209 |
210 | # draw arrow
211 | arrow_attr = [{'point':rot_x, 'color':'r', 'label':'front'},
212 | {'point':rot_y, 'color':'g', 'label':'right'},
213 | {'point':rot_z, 'color':'b', 'label':'top'}]
214 |
215 | if phi> 45 and phi<=225:
216 | order = [0,1,2]
217 | elif phi > 225 and phi < 315:
218 | order = [2,0,1]
219 | else:
220 | order = [2,1,0]
221 |
222 | for i in range(3):
223 | draw_axis(ax, origin, arrow_attr[order[i]]['point'], arrow_attr[order[i]]['color'], arrow_attr[order[i]]['label'])
224 | # draw_axis(ax, origin, rot_y, 'g', label='right')
225 | # draw_axis(ax, origin, rot_z, 'b', label='top')
226 | # draw_axis(ax, origin, rot_x, 'r', label='front')
227 |
228 | # 关闭坐标轴和网格
229 | ax.set_axis_off()
230 | ax.grid(False)
231 |
232 | # 设置坐标范围
233 | ax.set_xlim(-5, 5)
234 | ax.set_ylim(-5, 5)
235 |
236 | def figure_to_img(fig):
237 | with io.BytesIO() as buf:
238 | fig.savefig(buf, format='JPG', bbox_inches='tight')
239 | buf.seek(0)
240 | image = Image.open(buf).copy()
241 | return image
242 |
243 | from render import render, Model
244 | import math
245 | axis_model = Model("./assets/axis.obj", texture_filename="./assets/axis.png")
246 | def render_3D_axis(phi, theta, gamma):
247 | radius = 240
248 | # camera_location = [radius * math.cos(phi), radius * math.sin(phi), radius * math.tan(theta)]
249 | # print(camera_location)
250 | camera_location = [-1*radius * math.cos(phi), -1*radius * math.tan(theta), radius * math.sin(phi)]
251 | img = render(
252 | # Model("res/jinx.obj", texture_filename="res/jinx.tga"),
253 | axis_model,
254 | height=512,
255 | width=512,
256 | filename="tmp_render.png",
257 | cam_loc = camera_location
258 | )
259 | img = img.rotate(gamma)
260 | return img
261 |
262 | def overlay_images_with_scaling(center_image: Image.Image, background_image, target_size=(512, 512)):
263 | """
264 | 调整前景图像大小为 512x512,将背景图像缩放以适配,并中心对齐叠加
265 | :param center_image: 前景图像
266 | :param background_image: 背景图像
267 | :param target_size: 前景图像的目标大小,默认 (512, 512)
268 | :return: 叠加后的图像
269 | """
270 | # 确保输入图像为 RGBA 模式
271 | if center_image.mode != "RGBA":
272 | center_image = center_image.convert("RGBA")
273 | if background_image.mode != "RGBA":
274 | background_image = background_image.convert("RGBA")
275 |
276 | # 调整前景图像大小
277 | center_image = center_image.resize(target_size)
278 |
279 | # 缩放背景图像,确保其适合前景图像的尺寸
280 | bg_width, bg_height = background_image.size
281 |
282 | # 按宽度或高度等比例缩放背景
283 | scale = target_size[0] / max(bg_width, bg_height)
284 | new_width = int(bg_width * scale)
285 | new_height = int(bg_height * scale)
286 | resized_background = background_image.resize((new_width, new_height))
287 | # 计算需要的填充量
288 | pad_width = target_size[0] - new_width
289 | pad_height = target_size[0] - new_height
290 |
291 | # 计算上下左右的 padding
292 | left = pad_width // 2
293 | right = pad_width - left
294 | top = pad_height // 2
295 | bottom = pad_height - top
296 |
297 | # 添加 padding
298 | resized_background = ImageOps.expand(resized_background, border=(left, top, right, bottom), fill=(255,255,255,255))
299 |
300 | # 将前景图像叠加到背景图像上
301 | result = resized_background.copy()
302 | result.paste(center_image, (0, 0), mask=center_image)
303 |
304 | return result
305 |
--------------------------------------------------------------------------------
/vision_tower.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch import nn
3 | import torch.nn.init as init
4 | import torch.nn.functional as F
5 |
6 | from paths import *
7 |
8 | from typing import Dict, List, Optional, Set, Tuple, Union
9 | from transformers import AutoImageProcessor, AutoModel, Dinov2Model
10 | from transformers.models.dinov2.modeling_dinov2 import Dinov2Embeddings
11 | from transformers.models.dinov2.configuration_dinov2 import Dinov2Config
12 | import numpy as np
13 | from contextlib import nullcontext
14 |
15 | def get_activation(activation):
16 | if activation.lower() == 'gelu':
17 | return nn.GELU()
18 | elif activation.lower() == 'rrelu':
19 | return nn.RReLU(inplace=True)
20 | elif activation.lower() == 'selu':
21 | return nn.SELU(inplace=True)
22 | elif activation.lower() == 'silu':
23 | return nn.SiLU(inplace=True)
24 | elif activation.lower() == 'hardswish':
25 | return nn.Hardswish(inplace=True)
26 | elif activation.lower() == 'leakyrelu':
27 | return nn.LeakyReLU(inplace=True)
28 | elif activation.lower() == 'sigmoid':
29 | return nn.Sigmoid()
30 | elif activation.lower() == 'tanh':
31 | return nn.Tanh()
32 | else:
33 | return nn.ReLU(inplace=True)
34 |
35 |
36 |
37 | class MLP_dim(nn.Module):
38 | def __init__(
39 | self, in_dim=512, out_dim=1024, bias=True, activation='relu'):
40 | super().__init__()
41 | self.act = get_activation(activation)
42 | self.net1 = nn.Sequential(
43 | nn.Linear(in_dim, int(out_dim), bias=bias),
44 | nn.BatchNorm1d(int(out_dim)),
45 | self.act
46 | )
47 | self.net2 = nn.Sequential(
48 | nn.Linear(int(out_dim), out_dim, bias=bias),
49 | nn.BatchNorm1d(out_dim)
50 | )
51 |
52 | def forward(self, x):
53 | return self.net2(self.net1(x))
54 |
55 | class FLIP_Dinov2Embeddings(Dinov2Embeddings):
56 | """
57 | Construct the CLS token, mask token, position and patch embeddings.
58 | """
59 |
60 | def __init__(self, config: Dinov2Config) -> None:
61 | super().__init__(config)
62 |
63 | def forward(self, pixel_values: torch.Tensor, bool_masked_pos: Optional[torch.Tensor] = None) -> torch.Tensor:
64 | batch_size, _, height, width = pixel_values.shape
65 | target_dtype = self.patch_embeddings.projection.weight.dtype
66 | embeddings = self.patch_embeddings(pixel_values.to(dtype=target_dtype))
67 |
68 | # add the [CLS] token to the embedded patch tokens
69 | cls_tokens = self.cls_token.expand(batch_size, -1, -1)
70 | embeddings = torch.cat((cls_tokens, embeddings), dim=1)
71 |
72 | # add positional encoding to each token
73 | embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width)
74 |
75 | if bool_masked_pos is not None:
76 | # embeddings = torch.where(
77 | # bool_masked_pos.unsqueeze(-1), self.mask_token.to(embeddings.dtype).unsqueeze(0), embeddings
78 | # )
79 | B,S,D = embeddings.shape
80 | batch_indices = torch.arange(B).unsqueeze(1)
81 | embeddings = embeddings[batch_indices, bool_masked_pos]
82 |
83 | embeddings = self.dropout(embeddings)
84 |
85 | return embeddings
86 |
87 | class FLIP_DINOv2(Dinov2Model):
88 | def __init__(self, config):
89 | super().__init__(config)
90 |
91 | self.embeddings = FLIP_Dinov2Embeddings(config)
92 |
93 | class DINOv2_MLP(nn.Module):
94 | def __init__(self,
95 | dino_mode,
96 | in_dim,
97 | out_dim,
98 | evaluate,
99 | mask_dino,
100 | frozen_back
101 | ) -> None:
102 | super().__init__()
103 | # self.dinov2 = AutoModel.from_pretrained(DINO_BASE)
104 | if dino_mode == 'base':
105 | self.dinov2 = FLIP_DINOv2.from_pretrained(DINO_BASE, cache_dir='./')
106 | elif dino_mode == 'large':
107 | self.dinov2 = FLIP_DINOv2.from_pretrained(DINO_LARGE, cache_dir='./')
108 | elif dino_mode == 'small':
109 | self.dinov2 = FLIP_DINOv2.from_pretrained(DINO_SMALL, cache_dir='./')
110 | elif dino_mode == 'giant':
111 | self.dinov2 = FLIP_DINOv2.from_pretrained(DINO_GIANT, cache_dir='./')
112 |
113 | self.down_sampler = MLP_dim(in_dim=in_dim, out_dim=out_dim)
114 | self.random_mask = False
115 | if not evaluate:
116 | self.init_weights(self.down_sampler)
117 | self.random_mask = mask_dino
118 | if frozen_back:
119 | self.forward_mode = torch.no_grad()
120 | else:
121 | self.forward_mode = nullcontext()
122 |
123 | def forward(self, img_inputs):
124 | device = self.get_device()
125 | # print(img_inputs['pixel_values'].shape)
126 |
127 | with self.forward_mode:
128 | if self.random_mask:
129 | B = len(img_inputs['pixel_values'])
130 | S = 256
131 | indices = []
132 | for i in range(B):
133 | tmp = torch.randperm(S)[:S//2]
134 | tmp = tmp.sort().values + 1
135 | indices.append(tmp)
136 | indices = torch.stack(indices, dim=0)
137 | indices = torch.cat([torch.zeros(B, 1, dtype=torch.long, device='cpu'), indices], dim=1)
138 | # print(indices.shape)
139 | img_inputs['bool_masked_pos'] = indices.to(device)
140 |
141 | dino_outputs = self.dinov2(**img_inputs)
142 | dino_seq = dino_outputs.last_hidden_state
143 | # B,S,_ = dino_seq.shape
144 | # dino_seq = dino_seq.view(B*S,-1)
145 | dino_seq = dino_seq[:,0,:]
146 |
147 | down_sample_out = self.down_sampler(dino_seq)
148 | # down_sample_out = down_sample_out.view(B,S,-1)
149 | # down_sample_out = down_sample_out[:,0,:]
150 |
151 | return down_sample_out
152 |
153 | def get_device(self):
154 | return next(self.parameters()).device
155 |
156 | def init_weights(self, m):
157 | if isinstance(m, nn.Linear):
158 | init.xavier_uniform_(m.weight)
159 | if m.bias is not None:
160 | init.constant_(m.bias, 0)
161 |
162 |
--------------------------------------------------------------------------------