├── .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 | Paper PDF 12 | Project Page 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 | ![teaser](assets/demo.png) 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 | --------------------------------------------------------------------------------