├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── anno_criterion ├── CIPO │ ├── README.md │ └── sup-dataset-cipo-1.jpg └── Lane │ ├── README.md │ └── sup-dataset-lane-1.jpg ├── data ├── Coordinate_Sys.md └── README.md ├── eval ├── CIPO_evaluation │ ├── Makefile │ ├── README.md │ ├── adapter.py │ ├── common │ │ ├── gason.cpp │ │ ├── gason.h │ │ ├── maskApi.c │ │ └── maskApi.h │ ├── eval.py │ ├── example │ │ ├── EvalDemo.py │ │ ├── annotations │ │ │ └── segment-1146261869236413282_1680_000_1700_000_with_camera_labels │ │ │ │ ├── 155840113624736600.jpg.json │ │ │ │ └── 155840113634736000.jpg.json │ │ ├── resfile.txt │ │ ├── results │ │ │ └── segment-1146261869236413282_1680_000_1700_000_with_camera_labels │ │ │ │ ├── 155840113624736600.jpg.json │ │ │ │ └── 155840113634736000.jpg.json │ │ └── txtfile.txt │ ├── pycocotools │ │ ├── __init__.py │ │ ├── _mask.c │ │ ├── cocoeval.py │ │ └── mask.py │ └── setup.py ├── LANE_evaluation │ ├── README.md │ ├── lane2d │ │ ├── Makefile │ │ ├── example │ │ │ ├── annotations │ │ │ │ └── segment-10203656353524179475_7625_000_7645_000_with_camera_labels │ │ │ │ │ ├── 152268801497018700.json │ │ │ │ │ └── 152268801507012900.json │ │ │ ├── eval_demo.sh │ │ │ ├── images │ │ │ │ └── segment-10203656353524179475_7625_000_7645_000_with_camera_labels │ │ │ │ │ ├── 152268801497018700.jpg │ │ │ │ │ └── 152268801507012900.jpg │ │ │ ├── results │ │ │ │ └── segment-10203656353524179475_7625_000_7645_000_with_camera_labels │ │ │ │ │ ├── 152268801497018700.json │ │ │ │ │ └── 152268801507012900.json │ │ │ └── test_list.txt │ │ ├── include │ │ │ ├── CJsonObject.hpp │ │ │ ├── cJSON.h │ │ │ ├── counter.hpp │ │ │ ├── hungarianGraph.hpp │ │ │ ├── lane_compare.hpp │ │ │ └── spline.hpp │ │ └── src │ │ │ ├── CJsonObject.cpp │ │ │ ├── cJSON.c │ │ │ ├── counter.cpp │ │ │ ├── evaluate.cpp │ │ │ ├── lane_compare.cpp │ │ │ └── spline.cpp │ └── lane3d │ │ ├── eval_3D_lane.py │ │ ├── example │ │ ├── annotations │ │ │ └── segment-10203656353524179475_7625_000_7645_000_with_camera_labels │ │ │ │ ├── 152268801497018700.json │ │ │ │ └── 152268801507012900.json │ │ ├── eval_demo.sh │ │ ├── results │ │ │ └── segment-10203656353524179475_7625_000_7645_000_with_camera_labels │ │ │ │ ├── 152268801497018700.json │ │ │ │ └── 152268801507012900.json │ │ └── test_list.txt │ │ └── utils │ │ ├── MinCostFlow.py │ │ └── utils.py ├── README.md └── requirements.txt ├── imgs ├── overview.gif └── overview.jpg └── misc ├── 1000_curve.txt ├── 1000_merge_split_case.txt └── 1000_night.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [OpenDriveLab] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .DS_Store 131 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 The OpenLane Dataset Authors. All rights reserved. 2 | 3 | Apache License 4 | Version 2.0, January 2004 5 | http://www.apache.org/licenses/ 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, 12 | and distribution as defined by Sections 1 through 9 of this document. 13 | 14 | "Licensor" shall mean the copyright owner or entity authorized by 15 | the copyright owner that is granting the License. 16 | 17 | "Legal Entity" shall mean the union of the acting entity and all 18 | other entities that control, are controlled by, or are under common 19 | control with that entity. For the purposes of this definition, 20 | "control" means (i) the power, direct or indirect, to cause the 21 | direction or management of such entity, whether by contract or 22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 23 | outstanding shares, or (iii) beneficial ownership of such entity. 24 | 25 | "You" (or "Your") shall mean an individual or Legal Entity 26 | exercising permissions granted by this License. 27 | 28 | "Source" form shall mean the preferred form for making modifications, 29 | including but not limited to software source code, documentation 30 | source, and configuration files. 31 | 32 | "Object" form shall mean any form resulting from mechanical 33 | transformation or translation of a Source form, including but 34 | not limited to compiled object code, generated documentation, 35 | and conversions to other media types. 36 | 37 | "Work" shall mean the work of authorship, whether in Source or 38 | Object form, made available under the License, as indicated by a 39 | copyright notice that is included in or attached to the work 40 | (an example is provided in the Appendix below). 41 | 42 | "Derivative Works" shall mean any work, whether in Source or Object 43 | form, that is based on (or derived from) the Work and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. For the purposes 46 | of this License, Derivative Works shall not include works that remain 47 | separable from, or merely link (or bind by name) to the interfaces of, 48 | the Work and Derivative Works thereof. 49 | 50 | "Contribution" shall mean any work of authorship, including 51 | the original version of the Work and any modifications or additions 52 | to that Work or Derivative Works thereof, that is intentionally 53 | submitted to Licensor for inclusion in the Work by the copyright owner 54 | or by an individual or Legal Entity authorized to submit on behalf of 55 | the copyright owner. For the purposes of this definition, "submitted" 56 | means any form of electronic, verbal, or written communication sent 57 | to the Licensor or its representatives, including but not limited to 58 | communication on electronic mailing lists, source code control systems, 59 | and issue tracking systems that are managed by, or on behalf of, the 60 | Licensor for the purpose of discussing and improving the Work, but 61 | excluding communication that is conspicuously marked or otherwise 62 | designated in writing by the copyright owner as "Not a Contribution." 63 | 64 | "Contributor" shall mean Licensor and any individual or Legal Entity 65 | on behalf of whom a Contribution has been received by Licensor and 66 | subsequently incorporated within the Work. 67 | 68 | 2. Grant of Copyright License. Subject to the terms and conditions of 69 | this License, each Contributor hereby grants to You a perpetual, 70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 71 | copyright license to reproduce, prepare Derivative Works of, 72 | publicly display, publicly perform, sublicense, and distribute the 73 | Work and such Derivative Works in Source or Object form. 74 | 75 | 3. Grant of Patent License. Subject to the terms and conditions of 76 | this License, each Contributor hereby grants to You a perpetual, 77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 78 | (except as stated in this section) patent license to make, have made, 79 | use, offer to sell, sell, import, and otherwise transfer the Work, 80 | where such license applies only to those patent claims licensable 81 | by such Contributor that are necessarily infringed by their 82 | Contribution(s) alone or by combination of their Contribution(s) 83 | with the Work to which such Contribution(s) was submitted. If You 84 | institute patent litigation against any entity (including a 85 | cross-claim or counterclaim in a lawsuit) alleging that the Work 86 | or a Contribution incorporated within the Work constitutes direct 87 | or contributory patent infringement, then any patent licenses 88 | granted to You under this License for that Work shall terminate 89 | as of the date such litigation is filed. 90 | 91 | 4. Redistribution. You may reproduce and distribute copies of the 92 | Work or Derivative Works thereof in any medium, with or without 93 | modifications, and in Source or Object form, provided that You 94 | meet the following conditions: 95 | 96 | (a) You must give any other recipients of the Work or 97 | Derivative Works a copy of this License; and 98 | 99 | (b) You must cause any modified files to carry prominent notices 100 | stating that You changed the files; and 101 | 102 | (c) You must retain, in the Source form of any Derivative Works 103 | that You distribute, all copyright, patent, trademark, and 104 | attribution notices from the Source form of the Work, 105 | excluding those notices that do not pertain to any part of 106 | the Derivative Works; and 107 | 108 | (d) If the Work includes a "NOTICE" text file as part of its 109 | distribution, then any Derivative Works that You distribute must 110 | include a readable copy of the attribution notices contained 111 | within such NOTICE file, excluding those notices that do not 112 | pertain to any part of the Derivative Works, in at least one 113 | of the following places: within a NOTICE text file distributed 114 | as part of the Derivative Works; within the Source form or 115 | documentation, if provided along with the Derivative Works; or, 116 | within a display generated by the Derivative Works, if and 117 | wherever such third-party notices normally appear. The contents 118 | of the NOTICE file are for informational purposes only and 119 | do not modify the License. You may add Your own attribution 120 | notices within Derivative Works that You distribute, alongside 121 | or as an addendum to the NOTICE text from the Work, provided 122 | that such additional attribution notices cannot be construed 123 | as modifying the License. 124 | 125 | You may add Your own copyright statement to Your modifications and 126 | may provide additional or different license terms and conditions 127 | for use, reproduction, or distribution of Your modifications, or 128 | for any such Derivative Works as a whole, provided Your use, 129 | reproduction, and distribution of the Work otherwise complies with 130 | the conditions stated in this License. 131 | 132 | 5. Submission of Contributions. Unless You explicitly state otherwise, 133 | any Contribution intentionally submitted for inclusion in the Work 134 | by You to the Licensor shall be under the terms and conditions of 135 | this License, without any additional terms or conditions. 136 | Notwithstanding the above, nothing herein shall supersede or modify 137 | the terms of any separate license agreement you may have executed 138 | with Licensor regarding such Contributions. 139 | 140 | 6. Trademarks. This License does not grant permission to use the trade 141 | names, trademarks, service marks, or product names of the Licensor, 142 | except as required for reasonable and customary use in describing the 143 | origin of the Work and reproducing the content of the NOTICE file. 144 | 145 | 7. Disclaimer of Warranty. Unless required by applicable law or 146 | agreed to in writing, Licensor provides the Work (and each 147 | Contributor provides its Contributions) on an "AS IS" BASIS, 148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 149 | implied, including, without limitation, any warranties or conditions 150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any 153 | risks associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, 156 | whether in tort (including negligence), contract, or otherwise, 157 | unless required by applicable law (such as deliberate and grossly 158 | negligent acts) or agreed to in writing, shall any Contributor be 159 | liable to You for damages, including any direct, indirect, special, 160 | incidental, or consequential damages of any character arising as a 161 | result of this License or out of the use or inability to use the 162 | Work (including but not limited to damages for loss of goodwill, 163 | work stoppage, computer failure or malfunction, or any and all 164 | other commercial damages or losses), even if such Contributor 165 | has been advised of the possibility of such damages. 166 | 167 | 9. Accepting Warranty or Additional Liability. While redistributing 168 | the Work or Derivative Works thereof, You may choose to offer, 169 | and charge a fee for, acceptance of support, warranty, indemnity, 170 | or other liability obligations and/or rights consistent with this 171 | License. However, in accepting such obligations, You may act only 172 | on Your own behalf and on Your sole responsibility, not on behalf 173 | of any other Contributor, and only if You agree to indemnify, 174 | defend, and hold each Contributor harmless for any liability 175 | incurred by, or claims asserted against, such Contributor by reason 176 | of your accepting any such warranty or additional liability. 177 | 178 | END OF TERMS AND CONDITIONS 179 | 180 | APPENDIX: How to apply the Apache License to your work. 181 | 182 | To apply the Apache License to your work, attach the following 183 | boilerplate notice, with the fields enclosed by brackets "[]" 184 | replaced with your own identifying information. (Don't include 185 | the brackets!) The text should be enclosed in the appropriate 186 | comment syntax for the file format. We also recommend that a 187 | file or class name and description of purpose be included on the 188 | same "printed page" as the copyright notice for easier 189 | identification within third-party archives. 190 | 191 | Copyright [yyyy] [name of copyright owner] 192 | 193 | Licensed under the Apache License, Version 2.0 (the "License"); 194 | you may not use this file except in compliance with the License. 195 | You may obtain a copy of the License at 196 | 197 | http://www.apache.org/licenses/LICENSE-2.0 198 | 199 | Unless required by applicable law or agreed to in writing, software 200 | distributed under the License is distributed on an "AS IS" BASIS, 201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 202 | See the License for the specific language governing permissions and 203 | limitations under the License. 204 | 205 | ------------------------------------------------------------------------------ 206 | 207 | Files: third_party/camera/* 208 | 209 | Copyright (c) 2022 Shanghai Artificial Intelligence Laboratory. All rights reserved. 210 | 211 | Redistribution and use in source and binary forms, with or without 212 | modification, are permitted provided that the following conditions are 213 | met: 214 | 215 | * Redistributions of source code must retain the above copyright 216 | notice, this list of conditions and the following disclaimer. 217 | * Redistributions in binary form must reproduce the above 218 | copyright notice, this list of conditions and the following disclaimer 219 | in the documentation and/or other materials provided with the 220 | distribution. 221 | * Neither the name of the copyright holder nor the names of its 222 | contributors may be used to endorse or promote products derived 223 | from this software without specific prior written permission. 224 | 225 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 226 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 227 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 228 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 229 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 230 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 231 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 234 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 236 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenLane-V1 2 | OpenLane is the first real-world and the largest scaled 3D lane dataset to date. Our dataset collects valuable contents from [public perception dataset](https://waymo.com/open/data/perception/), providing lane and closest-in-path object(CIPO) annotations for **1000** segments. In short, OpenLane owns **200K** frames and over **880K** carefully annotated lanes. We have released the OpenLane Dataset publicly to aid the research community in making advancements in 3D perception and autonomous driving technology. See details in [Paper.](https://arxiv.org/abs/2203.11089) 3 | 4 | 5 | 6 | This repository is organized as the following. 7 | 8 | - [Get Started](#get-started) 9 | - [Download](#download) 10 | - [Evaluation Kit](#evaluation-kit) 11 | - [Data](#data) 12 | - [Lane Annotation](#lane-annotation) 13 | - [CIPO/Scenes Annotation](#ciposcenes-annotation) 14 | - [Benchmark and Leaderboard](#benchmark-and-leaderboard) 15 | - [Benchmark](#benchmark) 16 | - [Leaderboard](#leaderboard) 17 | - [Citation](#citation) 18 | - [License](#license) 19 | 20 | > Note that our OpenLane is an autonomous driving dataset, while there's another repository with the same name [The-OpenROAD-Project/OpenLane](https://github.com/The-OpenROAD-Project/OpenLane). 21 | 22 | ## News 23 | - [2023/03]: We announced a brand-new dataset on scene understanding and are holding a challenge on the dataset, check out on [OpenLane-V2](https://github.com/OpenDriveLab/OpenLane-V2) and [challenge website](https://opendrivelab.com/AD23Challenge.html) :star:. 24 | - [2023/03]: We are maintaining a leaderboard on [paperswithcode](https://paperswithcode.com/sota/3d-lane-detection-on-openlane) :microphone:. 25 | - [2022/11]: We released `v1.2` of the Openlane dataset and features are shown as following. 26 | - Add frame pose info for sequential research. 27 | - [Filter some noise points](https://github.com/OpenDriveLab/OpenLane/issues/23) and [fix coordinate system bug](https://github.com/OpenDriveLab/OpenLane/issues/31). 28 | - [2022/09]: Update evaluation metrics, prune gt points by visibility before evaluation, fixing issue [A question about prune_3d_lane_by_visibility](https://github.com/OpenDriveLab/OpenLane/issues/18). 29 | - [2022/07]: We released `v1.1` of the Openlane dataset, fixing [3D lane evaluation issues](https://github.com/OpenDriveLab/OpenLane/issues/15) and some json files mismatch. 30 | - [2022/04]: We released v1.0 of the [PersFormer codebase](https://github.com/OpenDriveLab/PersFormer_3DLane), providing a baseline method on OpenLane dataset. 31 | - [2022/03]: We released v1.0 of the Openlane dataset including 1000 segments with labels of 3D/2D lanes and CIPO/Scenes. 32 | 33 | ## Get Started 34 | Please follow these steps to make yourself familiar with the OpenLane dataset. Create an issue if you need any further information. 35 | ### Download 36 | You can download the entire OpenLane dataset [here](data/README.md). Note that before using OpenLane dataset, you should register at [Waymo Open Dataset Website](waymo.com/open) and agreed to these Terms since OpenLane is built on top of Waymo Open Dataset. 37 | 38 | ### Evaluation Kit 39 | We provide evaluation tools on both lane and CIPO, following the same data format as Waymo and common evaluation pipeline in 2D/3D lane detection. Please refer to [Evaluation Kit Instruction](eval/README.md). 40 | 41 | ## Data 42 | OpenLane dataset is constructed on mainstream datasets in the field of autonomous driving. In v1.0, we release the annotation on [Waymo Open Dataset](https://waymo.com/open/data/perception/). In the future we'll update for annotation on [nuScenes](https://www.nuscenes.org/nuscenes). 43 | OpenLane dataset focuses on lane detection as well as CIPO. We annotate all the lanes in each frame, including those in the opposite direction if no curbside exists in the middle. In addition to the lane detection task, we also annotate: (a) scene tags, such as weather and locations; (b) the CIPO, which is defined as the most concerned target w.r.t. ego vehicle; such a tag is quite pragmatic for subsequent modules as in planning/control, besides a whole set of objects from perception. The introduction about the [coordinates system](./data/Coordinate_Sys.md) can be found here. 44 | 45 | ### Lane Annotation 46 | We annotate lane in the following format. 47 | - Lane shape. Each 2D/3D lane is presented as a set of 2D/3D points. 48 | - Lane category. Each lane has a category such as double yellow line or curb. 49 | - Lane property. Some of lanes have a property such as right, left. 50 | - Lane tracking ID. Each lane except curb has a unique id. 51 | 52 | For more annotation criterion, please refer to [Lane Anno Criterion](anno_criterion/Lane/README.md). 53 | 54 | ### CIPO/Scenes Annotation 55 | We annotate CIPO and Scenes in the following format. 56 | - 2D bounding box with a category representing the importance level of object. 57 | - Scene Tag. It describes in which scenario this frame is collected. 58 | - Weather Tag. It describes under what weather this frame is collected. 59 | - Hours Tag. It annotates in what time this frame is collected. 60 | 61 | For more annotation criterion, please refer to [CIPO Anno Criterion](anno_criterion/CIPO/README.md). 62 | 63 | ## Benchmark and Leaderboard 64 | 65 | ### Benchmark 66 | 67 | We provide an initial benchmark on OpenLane 2D/3D Lane Detection and you are welcome to **pull request** and add your work here! To thoroughly evaluate the model, we provide different case split from the entire validation set. They are Up&Down case, Curve case, Extreme Weather case, Night case, Intersection case, and Merge&Split case. More detail can be found in [Lane Anno Criterion](anno_criterion/Lane/README.md) 68 | Based on the [Lane Eval Metric](eval/LANE_evaluation/README.md), results (**F-Score**) of different 2D/3D methods on different cases are shown as follows. 69 | - 2D Lane Detection 70 | 71 | | Method | All | Up&
Down | Curve | Extreme
Weather | Night | Intersection | Merge&
Split | 72 | | :----: |:----:|:----:|:----:|:----:|:----:|:----:|:----:| 73 | | LaneATT-S | 28.3 | 25.3 | 25.8 | 32.0 | 27.6 | 14.0 | 24.3 | 74 | | LaneATT-M | 31.0 | 28.3 | 27.4 | 34.7 | 30.2 | 17.0 | 26.5 | 75 | | PersFormer | 42.0 | 40.7 | 46.3 | 43.7 | 36.1 | 28.9 | 41.2 | 76 | | CondLaneNet-S | 52.3 | 55.3 | 57.5 | 45.8 | 46.6 | 48.4 | 45.5 | 77 | | CondLaneNet-M | 55.0 | 58.5 | 59.4 | 49.2 | 48.6 | 50.7 | 47.8 | 78 | |**CondLaneNet-L**|**59.1**|**62.1**|**62.9**|**54.7**|**51.0**|**55.7**|**52.3**| 79 | 80 | - 3D Lane Detection 81 | 82 | | Method |Version| All | Up &
Down | Curve | Extreme
Weather | Night | Intersection | Merge&
Split | Best model |x-c|x-f|z-c|z-f|Category Accuracy| 83 | | :----: |:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| 84 | | GenLaneNet |1.1| 32.3 | 25.4 | 33.5 | 28.1 | 18.7 | 21.4 | 31.0 | [model](https://docs.google.com/forms/d/e/1FAIpQLScLRUvr14taMIZzGZs7ZDRIOchPQQ50rdIWyipQeRl2bsO9dQ/viewform?usp=sharing) |0.593| 0.494|0.140|0.195|/| 85 | | 3DLaneNet |1.1| 44.1 | 40.8 | 46.5 | 47.5 | 41.5 | 32.1 | 41.7 | - | -|-| -|-|-| 86 | |**PersFormer**|1.1|**50.5**|**45.6**|**58.7**|**54.0**|**50.0**|**41.6**|**53.1**|[model](https://drive.google.com/file/d/1TwjmFB3p3luCG8ytZ4MEI-TMoDT2Vn3G/view?usp=share_link) | 0.319|0.325|0.112|0.141|89.51| 87 | |**PersFormer**|1.2|**52.9**|**47.5**|**58.4**|**51.8**|**47.4**|**42.1**|**50.9**|[model](https://drive.google.com/file/d/1jtDfnxcNNbefgpYGfue1XlvcvtmfPZj7/view?usp=share_link) | 0.291|0.294| 0.080|0.116|89.24| 88 | 89 | The implementation of PersFormer can be found [here](https://github.com/OpenDriveLab/PersFormer_3DLane). 90 | 91 | ### Leaderboard 92 | 93 | For comparison, we provide a leaderboard on [paperwithcode](https://paperswithcode.com/sota/3d-lane-detection-on-openlane). 94 | 95 | 96 | ## Citation 97 | 98 | Please use the following citation when referencing [OpenLane](https://arxiv.org/abs/2203.11089): 99 | ```bibtex 100 | @inproceedings{chen2022persformer, 101 | title={PersFormer: 3D Lane Detection via Perspective Transformer and the OpenLane Benchmark}, 102 | author={Chen, Li and Sima, Chonghao and Li, Yang and Zheng, Zehan and Xu, Jiajie and Geng, Xiangwei and Li, Hongyang and He, Conghui and Shi, Jianping and Qiao, Yu and Yan, Junchi}, 103 | booktitle={European Conference on Computer Vision (ECCV)}, 104 | year={2022} 105 | } 106 | ``` 107 | 108 | 109 | ## License 110 | Our dataset is based on the [Waymo Open Dataset](https://waymo.com/open/data/perception/) and therefore we distribute the data under [Creative Commons Attribution-NonCommercial-ShareAlike](https://creativecommons.org/licenses/by-nc-sa/4.0/) license and [Waymo Dataset License Agreement for Non-Commercial Use (August 2019)](https://waymo.com/open/terms/). You are free to share and adapt the data, but have to give appropriate credit and may not use the work for commercial purposes. 111 | All code within this repository is under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). 112 | -------------------------------------------------------------------------------- /anno_criterion/CIPO/README.md: -------------------------------------------------------------------------------- 1 | # CIPO & Scenes Annotation Criterion 2 | 3 | Examples of visualizing CIPO&Scene annotation on 2D image are shown below. 4 | 5 | ![](sup-dataset-cipo-1.jpg) 6 | 7 | ## CIPO 8 | We utilize 2D bounding boxes annotation from [Waymo Open Dataset](https://waymo.com/open/data/perception/) to generate CIPO annotation. To cover the complex scenarios, we categorize objects, mainly including vehicles, pedestrians and cyclists, into 4 different CIPO levels. 9 | 10 | `Level 1`: The most important one, which is closest to ego vehicle within the required reaction distance and has over 50% part of it in the ego lane. Level 1 contains one object at most. 11 | 12 | `Level 2`: Objects whose bodies interact with the real or virtual lines of ego lane, typically in the process of cut-in or cut-out. 13 | 14 | `Level 3`: Objects mainly within the reaction distance or drivable area, or those in left/ego/right lanes, with occlusion rate less than 50%. Note that vehicles in the opposite direction can be in this CIPO level as well. 15 | 16 | `Level 4`: The remains which are almost unlikely to impact the future path. They are mainly objects in lanes with far distance, objects out of drivable area, or parked vehicles in our dataset. 17 | 18 | Here's the data format for CIPO annotation. The evaluation can be referred from [here](../../eval/CIPO_evaluation/README.md) 19 | ``` 20 | { 21 | "results": [ (k objects in `results` list) 22 | { 23 | "width": -- width of cipo bbox 24 | "height": -- height of cipo bbox 25 | "x": -- x axis of cipo bbox left-top corner 26 | "y": -- y axis of cipo bbox left-top corner 27 | "id": -- importance level of cipo 28 | "trackid": -- tracking id of cipo, unique in the whole segment 29 | "type": -- type of cipo 30 | 0: TYPE_UNKNOWN 31 | 1: TYPE_VEHICLE 32 | 2: TYPE_PEDESTRIAN 33 | 3: TYPE_SIGN 34 | 4: TYPE_CYCLIST 35 | }, 36 | ... 37 | ], 38 | "raw_file_path": -- image path 39 | } 40 | ``` 41 | 42 | 43 | ## Scene Tag 44 | Here's the data format for Scene Tag annotation. 45 | ``` 46 | { 47 | "segment-xxx": -- segment id 48 | { 49 | "scene": 50 | "weather": 51 | "time": 52 | } 53 | ... (1000 segments) 54 | } 55 | ``` 56 | 57 | `scene`: residential, urban, suburbs, highway, parking lot 58 | 59 | `weather`: clear, partly cloud, overcast, rainy, foggy 60 | 61 | `time`: daytime, night, dawn/dusk 62 | -------------------------------------------------------------------------------- /anno_criterion/CIPO/sup-dataset-cipo-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/anno_criterion/CIPO/sup-dataset-cipo-1.jpg -------------------------------------------------------------------------------- /anno_criterion/Lane/README.md: -------------------------------------------------------------------------------- 1 | # Lane Annotation Criterion 2 | Our principle for the lane detection task is to find all visible lanes inside left and right curbsides. Examples of visualizing lane annotation on 2D image are shown below. 3 | 4 | ![](sup-dataset-lane-1.jpg) 5 | 6 | ## Data Format 7 | Here's the data format for 2D/3D lane annotation. The evaluation can be referred from [here](../../eval/LANE_evaluation/README.md) 8 | ``` 9 | { 10 | "intrinsic": [3, 3] -- camera intrinsic matrix 11 | "extrinsic": [4, 4] -- camera extrinsic matrix 12 | "lane_lines": [ (k lanes in `lane_lines` list) 13 | { 14 | "category": -- lane category 15 | 0: 'unkown', 16 | 1: 'white-dash', 17 | 2: 'white-solid', 18 | 3: 'double-white-dash', 19 | 4: 'double-white-solid', 20 | 5: 'white-ldash-rsolid', 21 | 6: 'white-lsolid-rdash', 22 | 7: 'yellow-dash', 23 | 8: 'yellow-solid', 24 | 9: 'double-yellow-dash', 25 | 10: 'double-yellow-solid', 26 | 11: 'yellow-ldash-rsolid', 27 | 12: 'yellow-lsolid-rdash', 28 | 20: 'left-curbside', 29 | 21: 'right-curbside' 30 | "visibility": [n, ] -- visibility of each point 31 | "uv":[ [2, n] -- 2d lane points under image coordinate 32 | [u1,u2,u3...], 33 | [v1,v2,v3...] 34 | ], 35 | "xyz":[ [3, n] -- 3d lane points under camera coordinate 36 | [x1,x2,x3...], 37 | [y1,y2,y3...], 38 | [z1,z2,z3...], 39 | 40 | ], 41 | "attribute": -- left-right attribute of the lane 42 | 1: left-left 43 | 2: left 44 | 3: right 45 | 4: right-right 46 | "track_id": -- lane tracking id 47 | }, 48 | ... 49 | ], 50 | "file_path": -- image path 51 | } 52 | ``` 53 | 54 | 55 | ## 2D/3D Lane Annotation Generation Workflow 56 | 1. The necessary high-quality 2D lane labels. They contain the final annotations of tracking ID, category, and 2D points ground truth. 57 | 2. Then for each frame, the point clouds are first filtered with the original 3D object bounding boxes and then projected back into the corresponding image. We further keep those points related to 2D lanes only with a certain threshold. 58 | 3. With the help of the localization and mapping system, 3D lane points in frames within a segment could be spliced into long, high-density lanes. 59 | 4. Points whose 2D projections are higher than the ending position of its 2D annotation are labeled as invisible. 60 | 5. A smoothing step is ultimately deployed to filtrate any outliers and generate the 3D labeling results. 61 | 62 | 63 | ## Note 64 | ### Occlusion 65 | Lanes are often occluded by objects or invisible because of abrasion, but they are still valuable for the real application. Thus, we annotate lanes if parts of them are visible, meaning lanes with one side being occluded are extended, or lanes with invisible intermediate parts are completed, according to the context. 66 | ### Visibility 67 | Visibility mainly relates to points in the far distance, rather than occlusion or abrasion. It's not needed in evaluation, but it helps the model to distinguish visible lane points from invisible ones. 68 | ### Topology 69 | It is very common that the number of lanes changes, especially when lanes have complex topologies such as fork lanes in merge and split cases. Fork lanes are annotated as separate lanes with a common starting point (split) or ending point (merge) - two close adjacent lanes are desired for the lane detection methods. 70 | ### Category 71 | We annotate each lane as one of the 14 lane categories. Note that traffic bollards are considered as curbside as well if they are not temporally placed. 72 | ### Tracking ID 73 | We annotate a tracking ID for each lane which is unique across the whole segment. We believe this could be helpful for video lane detection or lane tracking tasks. 74 | ### Left-Right Attribute 75 | We also assign a number in 1-4 to the most important 4 lanes based on their relative position to the ego-vehicle. Basically, the left-left lane is 1, the left lane is 2, the right lane is 3, and the right-right lane is 4. 76 | ### Scene Case 77 | We provide different splitting based on these themes: Up&Down case, Curve case, Extreme Weather case, Night case, Intersection case, and Merge&Split case. Up&Down case focuses on uphill/downhill roads. Curve case consists of different big curve roads. Extreme Weather, as its name explains, is composed of roads in rain. Night case aims at roads in dim light. Intersection case and Merge&Split case are the two common traffic scenes where lane topology is difficult. 78 | 79 | -------------------------------------------------------------------------------- /anno_criterion/Lane/sup-dataset-lane-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/anno_criterion/Lane/sup-dataset-lane-1.jpg -------------------------------------------------------------------------------- /data/Coordinate_Sys.md: -------------------------------------------------------------------------------- 1 | ## Three camera coord sys in eval code 2 | ### Waymo (OpenLane) camera coord sys. x-front, y-left, z-up 3 | 4 | 5 | ### normal (aka. standard) camera coord sys widely used. x-right, y-down, z-front 6 | 7 | 8 | ### LaneNet (3D-LaneNet) camera coord sys. x-right, y-front, z-up 9 | 10 | 11 | ## The transformation matrices in the code 12 | 13 | - cam_representation: Waymo to normal 14 | https://github.com/OpenPerceptionX/OpenLane/blob/1e8e61ccb456232955cf999b8db2aa4023945d25/eval/LANE_evaluation/lane3d/eval_3D_lane.py#L333-L338 15 | - R_gc: normal to LaneNet 16 | https://github.com/OpenPerceptionX/OpenLane/blob/1e8e61ccb456232955cf999b8db2aa4023945d25/eval/LANE_evaluation/lane3d/eval_3D_lane.py#L305-L307 17 | - R_vg: LaneNet to Waymo 18 | https://github.com/OpenPerceptionX/OpenLane/blob/1e8e61ccb456232955cf999b8db2aa4023945d25/eval/LANE_evaluation/lane3d/eval_3D_lane.py#L302-L304 19 | - original cam_extrinsics in JSON: Waymo camera to Waymo vehicle 20 | - inv(R_vg): Waymo to LaneNet 21 | 22 | Note that the 3D lane GT are annotated in the Waymo camera coord sys. With matrices above, the final `cam_extrinsics` can transform GT to road coord (which is right-down of the camera and actually has the same z height with Waymo vehicle coord rather than on the road, with setting `x/y=0` in the last line of code). 23 | https://github.com/OpenPerceptionX/OpenLane/blob/1e8e61ccb456232955cf999b8db2aa4023945d25/eval/LANE_evaluation/lane3d/eval_3D_lane.py#L308-L314 24 | 25 | **In conclusion, there are some redundancies in the process and one could try to use only `R_vg` and original `cam_extrinsics` to see if they could get the same results.** 26 | 27 | ## Pose Info in OpenLaneV1.2 28 | ### Waymo (OpenLane) vehicle coord sys: vehicle to global 29 | point_global = pose_matrix @ point_vehicle 30 | -------------------------------------------------------------------------------- /data/README.md: -------------------------------------------------------------------------------- 1 | # Data Download 2 | Please download the OpenLane dataset from the link following 3 | 4 | [Download Link](https://forms.gle/BzxxkUZDuPTqFKgu9) 5 | 6 | The entire folder hierarchy is shown below. 7 | ``` 8 | ├── images 9 | | ├── training 10 | | | ├── segment-xxx 11 | | | | ├── xxx.jpg 12 | | | | └── ... 13 | | | ├── segment-xxx 14 | | | | ├── xxx.jpg 15 | | | | └── ... 16 | | | └── ... 17 | | └── validation 18 | | ├── segment-xxx 19 | | | ├── xxx.jpg 20 | | | └── ... 21 | | ├── segment-xxx 22 | | | ├── xxx.jpg 23 | | | └── ... 24 | | └── ... 25 | ├── cipo 26 | | ├── training 27 | | | ├── segment-xxx 28 | | | | ├── xxx.jpg.json 29 | | | | └── ... 30 | | | ├── segment-xxx 31 | | | | ├── xxx.jpg.json 32 | | | | └── ... 33 | | | └── ... 34 | | └── validation 35 | | ├── segment-xxx 36 | | | ├── xxx.jpg.json 37 | | | └── ... 38 | | ├── segment-xxx 39 | | | ├── xxx.jpg.json 40 | | | └── ... 41 | | └── ... 42 | ├── lane3d_300 43 | | ├── training 44 | | | ├── segment-xxx 45 | | | | ├── xxx.json 46 | | | | └── ... 47 | | | ├── segment-xxx 48 | | | | ├── xxx.json 49 | | | | └── ... 50 | | | └── ... 51 | | ├── validation 52 | | | ├── segment-xxx 53 | | | | ├── xxx.json 54 | | | | └── ... 55 | | | ├── segment-xxx 56 | | | | ├── xxx.json 57 | | | | └── ... 58 | | | └── ... 59 | | └── test 60 | | ├── curve_case 61 | | | ├── segment-xxx 62 | | | | ├── xxx.json 63 | | | | └── ... 64 | | | ├── segment-xxx 65 | | | | ├── xxx.json 66 | | | | └── ... 67 | | | └── ... 68 | | ├── extreme_weather_case 69 | | | ├── segment-xxx 70 | | | | ├── xxx.json 71 | | | | └── ... 72 | | | ├── segment-xxx 73 | | | | ├── xxx.json 74 | | | | └── ... 75 | | | └── ... 76 | | ├── intersection_case 77 | | | ├── segment-xxx 78 | | | | ├── xxx.json 79 | | | | └── ... 80 | | | ├── segment-xxx 81 | | | | ├── xxx.json 82 | | | | └── ... 83 | | | └── ... 84 | | ├── merge_split_case 85 | | | ├── segment-xxx 86 | | | | ├── xxx.json 87 | | | | └── ... 88 | | | ├── segment-xxx 89 | | | | ├── xxx.json 90 | | | | └── ... 91 | | | └── ... 92 | | ├── night_case 93 | | | ├── segment-xxx 94 | | | | ├── xxx.json 95 | | | | └── ... 96 | | | ├── segment-xxx 97 | | | | ├── xxx.json 98 | | | | └── ... 99 | | | └── ... 100 | | ├── up_down_case 101 | | | ├── segment-xxx 102 | | | | ├── xxx.json 103 | | | | └── ... 104 | | | ├── segment-xxx 105 | | | | ├── xxx.json 106 | | | | └── ... 107 | | | └── ... 108 | | ├── curve.txt 109 | | ├── extreme_weather.txt 110 | | ├── intersection.txt 111 | | ├── merge_split.txt 112 | | ├── night.txt 113 | | └── up_down.txt 114 | ├── lane3d_1000 115 | | ├── training 116 | | | ├── segment-xxx 117 | | | | ├── xxx.json 118 | | | | └── ... 119 | | | ├── segment-xxx 120 | | | | ├── xxx.json 121 | | | | └── ... 122 | | | └── ... 123 | | ├── validation 124 | | | ├── segment-xxx 125 | | | | ├── xxx.json 126 | | | | └── ... 127 | | | ├── segment-xxx 128 | | | | ├── xxx.json 129 | | | | └── ... 130 | | | └── ... 131 | | └── test 132 | | ├── curve_case 133 | | | ├── segment-xxx 134 | | | | ├── xxx.json 135 | | | | └── ... 136 | | | ├── segment-xxx 137 | | | | ├── xxx.json 138 | | | | └── ... 139 | | | └── ... 140 | | ├── extreme_weather_case 141 | | | ├── segment-xxx 142 | | | | ├── xxx.json 143 | | | | └── ... 144 | | | ├── segment-xxx 145 | | | | ├── xxx.json 146 | | | | └── ... 147 | | | └── ... 148 | | ├── intersection_case 149 | | | ├── segment-xxx 150 | | | | ├── xxx.json 151 | | | | └── ... 152 | | | ├── segment-xxx 153 | | | | ├── xxx.json 154 | | | | └── ... 155 | | | └── ... 156 | | ├── merge_split_case 157 | | | ├── segment-xxx 158 | | | | ├── xxx.json 159 | | | | └── ... 160 | | | ├── segment-xxx 161 | | | | ├── xxx.json 162 | | | | └── ... 163 | | | └── ... 164 | | ├── night_case 165 | | | ├── segment-xxx 166 | | | | ├── xxx.json 167 | | | | └── ... 168 | | | ├── segment-xxx 169 | | | | ├── xxx.json 170 | | | | └── ... 171 | | | └── ... 172 | | ├── up_down_case 173 | | | ├── segment-xxx 174 | | | | ├── xxx.json 175 | | | | └── ... 176 | | | ├── segment-xxx 177 | | | | ├── xxx.json 178 | | | | └── ... 179 | | | └── ... 180 | | ├── 1000_curve.txt 181 | | ├── 1000_extreme_weather.txt 182 | | ├── 1000_intersection.txt 183 | | ├── 1000_merge_split.txt 184 | | ├── 1000_night.txt 185 | | └── 1000_up_down.txt 186 | └── scene 187 | └── SCENE 188 | └── scene.json 189 | ``` 190 | * Universal Rules: We use `XXX` to represent any of `images`, `cipo`, `lane3d_300` and `lane3d_1000`. We provide train/val split under `XXX/training/` and `XXX/validation/`, and it's consistent to Waymo original train/val split. `XXX/training/segment-xxx` denotes that the following files belong to a whole segment. 191 | * `images/`: this folder contains all the front-view raw image files from [Waymo Open Dataset](https://waymo.com/open/data/perception/). We extract them from the original `tfrecord` format. It contains 1000 segments in total, 798 segments for training and 202 for validatioin. 192 | * `cipo/`: this folder contains all the CIPO annotation. For the detail of the ground truth json files, please refer to [CIPO Annotation](../anno_criterion/CIPO/README.md) 193 | * `lane3d_1000/`: this folder contains all 2D/3D lane annotation. In addition to train/val split, we provide several scene cases under `lane3d_1000/test/`. Each case contains segments selected from validation set for a special theme. And we provide corresponding image name in each `lane3d_1000/test/1000_XXX.txt` For the detail of the ground truth json files, please refer to [Lane Annotation](../anno_criterion/Lane/README.md) 194 | * `lane3d_300/`: this folder contains a tiny set from `lane3d_1000/`. We provide this set for those users whose computation resource is limited. It contains 300 sequence in total, 240 for training and 60 for validation. 195 | * `scene`: this folder contains all scene annotation. It only has one json file. For the detail of json file, please refer to [CIPO Annotation](../anno_criterion/CIPO/README.md) 196 | -------------------------------------------------------------------------------- /eval/CIPO_evaluation/Makefile: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # Makefile The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # See: 7 | # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/Makefile 8 | # https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | # 10 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # ============================================================================== 24 | 25 | all: 26 | # install pycocotools locally 27 | python3 setup.py build_ext --inplace 28 | rm -rf build 29 | 30 | install: 31 | # install pycocotools to the Python site-packages 32 | python3 setup.py build_ext install 33 | rm -rf build 34 | 35 | clean: 36 | rm -rf build 37 | rm pycocotools/_mask.cpython-38-x86_64-linux-gnu.so -------------------------------------------------------------------------------- /eval/CIPO_evaluation/README.md: -------------------------------------------------------------------------------- 1 | # CIPO Evaluation Kit 2 | 3 | This is the Official Evaluation Kit for OpenLane CIPO Detection. 4 | 5 | ## Overview 6 | - [Requirements & Install](#a-name"requirement"a-requirements) 7 | - [Install](#a-name"install"a-install) 8 | - [CIPO evaluation](#a-name"cipoeval"a-cipo-evaluation) 9 | - [Acknowledgements](#a-name"ack"a-acknowledgements) 10 | 11 | ## Requirements & Install 12 | See [Requirements & Install](../README.md) 13 | 14 | 15 | ## CIPO evaluation 16 | 17 | ### Data Format 18 | - Prepare your result json in directory following this structure: 19 | ``` 20 | |-- results 21 | | |-- segment-xxx 22 | | | |-- xxx.json 23 | | | |-- ... 24 | | |-- segment-xxx 25 | | | |-- xxx.json 26 | | | |-- ... 27 | | |-- ... 28 | ``` 29 | - Prepare your annotation json in directory following this structure: 30 | ``` 31 | |-- annotations 32 | | |-- segment-xxx 33 | | | |-- xxx.json 34 | | | |-- ... 35 | | |-- segment-xxx 36 | | | |-- xxx.json 37 | | | |-- ... 38 | | |-- ... 39 | ``` 40 | - Each json should be formatted in the following structure: 41 | ``` 42 | { 43 | "results": [ (k objects in `results` list) 44 | { 45 | "width": -- width of cipo bbox 46 | "height": -- height of cipo bbox 47 | "x": -- x axis of cipo bbox left-top corner 48 | "y": -- y axis of cipo bbox left-top corner 49 | "id": -- importance level of cipo bbox 50 | "type": -- type of cipo bbox 51 | "score": -- confidence, it only exists in result json 52 | }, 53 | ... 54 | ], 55 | "raw_file_path": -- image path 56 | } 57 | ``` 58 | - Prepare your annotation and result file name in two txt file, both of which in the following formats: 59 | ``` 60 | segment-xxx/xxx.json 61 | segment-xxx/xxx.json 62 | ... 63 | ``` 64 | 65 | 66 | ### Evaluation 67 | To run the evaluation for your method, please run: 68 | ``` 69 | python eval.py --anno_txt ./anno_file.txt --res_txt ./res_file.txt 70 | ``` 71 | We provide demo code in `example/`. Please follow `example/EvalDemo.py`. We put some dummy ground truth in `example/annotations/` and prediction in `example/results/`. And we prepare two example txt files `txtfile.txt` and `resfile.txt`. please run `python EvalDemo.py --anno_txt ./txtfile.txt --res_txt ./resfile.txt` to see the demo evaluation. 72 | 73 | ### Metric formula 74 | We adopt the evaluation metric in [COCO](https://github.com/cocodataset/cocoapi). 75 | 76 | 77 | ## Acknowledgements 78 | Our CIPO evaluation code builds on [COCO](https://github.com/cocodataset/cocoapi). 79 | -------------------------------------------------------------------------------- /eval/CIPO_evaluation/common/gason.cpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | gason.cpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/vivkin/gason/blob/master/src/gason.cpp 8 | https://github.com/vivkin/gason/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | #include "gason.h" 24 | #include 25 | 26 | #define JSON_ZONE_SIZE 4096 27 | #define JSON_STACK_SIZE 32 28 | 29 | const char *jsonStrError(int err) { 30 | switch (err) { 31 | #define XX(no, str) \ 32 | case JSON_##no: \ 33 | return str; 34 | JSON_ERRNO_MAP(XX) 35 | #undef XX 36 | default: 37 | return "unknown"; 38 | } 39 | } 40 | 41 | void *JsonAllocator::allocate(size_t size) { 42 | size = (size + 7) & ~7; 43 | 44 | if (head && head->used + size <= JSON_ZONE_SIZE) { 45 | char *p = (char *)head + head->used; 46 | head->used += size; 47 | return p; 48 | } 49 | 50 | size_t allocSize = sizeof(Zone) + size; 51 | Zone *zone = (Zone *)malloc(allocSize <= JSON_ZONE_SIZE ? JSON_ZONE_SIZE : allocSize); 52 | if (zone == nullptr) 53 | return nullptr; 54 | zone->used = allocSize; 55 | if (allocSize <= JSON_ZONE_SIZE || head == nullptr) { 56 | zone->next = head; 57 | head = zone; 58 | } else { 59 | zone->next = head->next; 60 | head->next = zone; 61 | } 62 | return (char *)zone + sizeof(Zone); 63 | } 64 | 65 | void JsonAllocator::deallocate() { 66 | while (head) { 67 | Zone *next = head->next; 68 | free(head); 69 | head = next; 70 | } 71 | } 72 | 73 | static inline bool isspace(char c) { 74 | return c == ' ' || (c >= '\t' && c <= '\r'); 75 | } 76 | 77 | static inline bool isdelim(char c) { 78 | return c == ',' || c == ':' || c == ']' || c == '}' || isspace(c) || !c; 79 | } 80 | 81 | static inline bool isdigit(char c) { 82 | return c >= '0' && c <= '9'; 83 | } 84 | 85 | static inline bool isxdigit(char c) { 86 | return (c >= '0' && c <= '9') || ((c & ~' ') >= 'A' && (c & ~' ') <= 'F'); 87 | } 88 | 89 | static inline int char2int(char c) { 90 | if (c <= '9') 91 | return c - '0'; 92 | return (c & ~' ') - 'A' + 10; 93 | } 94 | 95 | static double string2double(char *s, char **endptr) { 96 | char ch = *s; 97 | if (ch == '-') 98 | ++s; 99 | 100 | double result = 0; 101 | while (isdigit(*s)) 102 | result = (result * 10) + (*s++ - '0'); 103 | 104 | if (*s == '.') { 105 | ++s; 106 | 107 | double fraction = 1; 108 | while (isdigit(*s)) { 109 | fraction *= 0.1; 110 | result += (*s++ - '0') * fraction; 111 | } 112 | } 113 | 114 | if (*s == 'e' || *s == 'E') { 115 | ++s; 116 | 117 | double base = 10; 118 | if (*s == '+') 119 | ++s; 120 | else if (*s == '-') { 121 | ++s; 122 | base = 0.1; 123 | } 124 | 125 | unsigned int exponent = 0; 126 | while (isdigit(*s)) 127 | exponent = (exponent * 10) + (*s++ - '0'); 128 | 129 | double power = 1; 130 | for (; exponent; exponent >>= 1, base *= base) 131 | if (exponent & 1) 132 | power *= base; 133 | 134 | result *= power; 135 | } 136 | 137 | *endptr = s; 138 | return ch == '-' ? -result : result; 139 | } 140 | 141 | static inline JsonNode *insertAfter(JsonNode *tail, JsonNode *node) { 142 | if (!tail) 143 | return node->next = node; 144 | node->next = tail->next; 145 | tail->next = node; 146 | return node; 147 | } 148 | 149 | static inline JsonValue listToValue(JsonTag tag, JsonNode *tail) { 150 | if (tail) { 151 | auto head = tail->next; 152 | tail->next = nullptr; 153 | return JsonValue(tag, head); 154 | } 155 | return JsonValue(tag, nullptr); 156 | } 157 | 158 | int jsonParse(char *s, char **endptr, JsonValue *value, JsonAllocator &allocator) { 159 | JsonNode *tails[JSON_STACK_SIZE]; 160 | JsonTag tags[JSON_STACK_SIZE]; 161 | char *keys[JSON_STACK_SIZE]; 162 | JsonValue o; 163 | int pos = -1; 164 | bool separator = true; 165 | JsonNode *node; 166 | *endptr = s; 167 | 168 | while (*s) { 169 | while (isspace(*s)) { 170 | ++s; 171 | if (!*s) break; 172 | } 173 | *endptr = s++; 174 | switch (**endptr) { 175 | case '-': 176 | if (!isdigit(*s) && *s != '.') { 177 | *endptr = s; 178 | return JSON_BAD_NUMBER; 179 | } 180 | case '0': 181 | case '1': 182 | case '2': 183 | case '3': 184 | case '4': 185 | case '5': 186 | case '6': 187 | case '7': 188 | case '8': 189 | case '9': 190 | o = JsonValue(string2double(*endptr, &s)); 191 | if (!isdelim(*s)) { 192 | *endptr = s; 193 | return JSON_BAD_NUMBER; 194 | } 195 | break; 196 | case '"': 197 | o = JsonValue(JSON_STRING, s); 198 | for (char *it = s; *s; ++it, ++s) { 199 | int c = *it = *s; 200 | if (c == '\\') { 201 | c = *++s; 202 | switch (c) { 203 | case '\\': 204 | case '"': 205 | case '/': 206 | *it = c; 207 | break; 208 | case 'b': 209 | *it = '\b'; 210 | break; 211 | case 'f': 212 | *it = '\f'; 213 | break; 214 | case 'n': 215 | *it = '\n'; 216 | break; 217 | case 'r': 218 | *it = '\r'; 219 | break; 220 | case 't': 221 | *it = '\t'; 222 | break; 223 | case 'u': 224 | c = 0; 225 | for (int i = 0; i < 4; ++i) { 226 | if (isxdigit(*++s)) { 227 | c = c * 16 + char2int(*s); 228 | } else { 229 | *endptr = s; 230 | return JSON_BAD_STRING; 231 | } 232 | } 233 | if (c < 0x80) { 234 | *it = c; 235 | } else if (c < 0x800) { 236 | *it++ = 0xC0 | (c >> 6); 237 | *it = 0x80 | (c & 0x3F); 238 | } else { 239 | *it++ = 0xE0 | (c >> 12); 240 | *it++ = 0x80 | ((c >> 6) & 0x3F); 241 | *it = 0x80 | (c & 0x3F); 242 | } 243 | break; 244 | default: 245 | *endptr = s; 246 | return JSON_BAD_STRING; 247 | } 248 | } else if ((unsigned int)c < ' ' || c == '\x7F') { 249 | *endptr = s; 250 | return JSON_BAD_STRING; 251 | } else if (c == '"') { 252 | *it = 0; 253 | ++s; 254 | break; 255 | } 256 | } 257 | if (!isdelim(*s)) { 258 | *endptr = s; 259 | return JSON_BAD_STRING; 260 | } 261 | break; 262 | case 't': 263 | if (!(s[0] == 'r' && s[1] == 'u' && s[2] == 'e' && isdelim(s[3]))) 264 | return JSON_BAD_IDENTIFIER; 265 | o = JsonValue(JSON_TRUE); 266 | s += 3; 267 | break; 268 | case 'f': 269 | if (!(s[0] == 'a' && s[1] == 'l' && s[2] == 's' && s[3] == 'e' && isdelim(s[4]))) 270 | return JSON_BAD_IDENTIFIER; 271 | o = JsonValue(JSON_FALSE); 272 | s += 4; 273 | break; 274 | case 'n': 275 | if (!(s[0] == 'u' && s[1] == 'l' && s[2] == 'l' && isdelim(s[3]))) 276 | return JSON_BAD_IDENTIFIER; 277 | o = JsonValue(JSON_NULL); 278 | s += 3; 279 | break; 280 | case ']': 281 | if (pos == -1) 282 | return JSON_STACK_UNDERFLOW; 283 | if (tags[pos] != JSON_ARRAY) 284 | return JSON_MISMATCH_BRACKET; 285 | o = listToValue(JSON_ARRAY, tails[pos--]); 286 | break; 287 | case '}': 288 | if (pos == -1) 289 | return JSON_STACK_UNDERFLOW; 290 | if (tags[pos] != JSON_OBJECT) 291 | return JSON_MISMATCH_BRACKET; 292 | if (keys[pos] != nullptr) 293 | return JSON_UNEXPECTED_CHARACTER; 294 | o = listToValue(JSON_OBJECT, tails[pos--]); 295 | break; 296 | case '[': 297 | if (++pos == JSON_STACK_SIZE) 298 | return JSON_STACK_OVERFLOW; 299 | tails[pos] = nullptr; 300 | tags[pos] = JSON_ARRAY; 301 | keys[pos] = nullptr; 302 | separator = true; 303 | continue; 304 | case '{': 305 | if (++pos == JSON_STACK_SIZE) 306 | return JSON_STACK_OVERFLOW; 307 | tails[pos] = nullptr; 308 | tags[pos] = JSON_OBJECT; 309 | keys[pos] = nullptr; 310 | separator = true; 311 | continue; 312 | case ':': 313 | if (separator || keys[pos] == nullptr) 314 | return JSON_UNEXPECTED_CHARACTER; 315 | separator = true; 316 | continue; 317 | case ',': 318 | if (separator || keys[pos] != nullptr) 319 | return JSON_UNEXPECTED_CHARACTER; 320 | separator = true; 321 | continue; 322 | case '\0': 323 | continue; 324 | default: 325 | return JSON_UNEXPECTED_CHARACTER; 326 | } 327 | 328 | separator = false; 329 | 330 | if (pos == -1) { 331 | *endptr = s; 332 | *value = o; 333 | return JSON_OK; 334 | } 335 | 336 | if (tags[pos] == JSON_OBJECT) { 337 | if (!keys[pos]) { 338 | if (o.getTag() != JSON_STRING) 339 | return JSON_UNQUOTED_KEY; 340 | keys[pos] = o.toString(); 341 | continue; 342 | } 343 | if ((node = (JsonNode *) allocator.allocate(sizeof(JsonNode))) == nullptr) 344 | return JSON_ALLOCATION_FAILURE; 345 | tails[pos] = insertAfter(tails[pos], node); 346 | tails[pos]->key = keys[pos]; 347 | keys[pos] = nullptr; 348 | } else { 349 | if ((node = (JsonNode *) allocator.allocate(sizeof(JsonNode) - sizeof(char *))) == nullptr) 350 | return JSON_ALLOCATION_FAILURE; 351 | tails[pos] = insertAfter(tails[pos], node); 352 | } 353 | tails[pos]->value = o; 354 | } 355 | return JSON_BREAKING_BAD; 356 | } -------------------------------------------------------------------------------- /eval/CIPO_evaluation/common/gason.h: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | gason.h The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/vivkin/gason/blob/master/src/gason.h 8 | https://github.com/vivkin/gason/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | enum JsonTag { 31 | JSON_NUMBER = 0, 32 | JSON_STRING, 33 | JSON_ARRAY, 34 | JSON_OBJECT, 35 | JSON_TRUE, 36 | JSON_FALSE, 37 | JSON_NULL = 0xF 38 | }; 39 | 40 | struct JsonNode; 41 | 42 | #define JSON_VALUE_PAYLOAD_MASK 0x00007FFFFFFFFFFFULL 43 | #define JSON_VALUE_NAN_MASK 0x7FF8000000000000ULL 44 | #define JSON_VALUE_TAG_MASK 0xF 45 | #define JSON_VALUE_TAG_SHIFT 47 46 | 47 | union JsonValue { 48 | uint64_t ival; 49 | double fval; 50 | 51 | JsonValue(double x) 52 | : fval(x) { 53 | } 54 | JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr) { 55 | assert((uintptr_t)payload <= JSON_VALUE_PAYLOAD_MASK); 56 | ival = JSON_VALUE_NAN_MASK | ((uint64_t)tag << JSON_VALUE_TAG_SHIFT) | (uintptr_t)payload; 57 | } 58 | bool isDouble() const { 59 | return (int64_t)ival <= (int64_t)JSON_VALUE_NAN_MASK; 60 | } 61 | JsonTag getTag() const { 62 | return isDouble() ? JSON_NUMBER : JsonTag((ival >> JSON_VALUE_TAG_SHIFT) & JSON_VALUE_TAG_MASK); 63 | } 64 | uint64_t getPayload() const { 65 | assert(!isDouble()); 66 | return ival & JSON_VALUE_PAYLOAD_MASK; 67 | } 68 | double toNumber() const { 69 | assert(getTag() == JSON_NUMBER); 70 | return fval; 71 | } 72 | char *toString() const { 73 | assert(getTag() == JSON_STRING); 74 | return (char *)getPayload(); 75 | } 76 | JsonNode *toNode() const { 77 | assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT); 78 | return (JsonNode *)getPayload(); 79 | } 80 | }; 81 | 82 | struct JsonNode { 83 | JsonValue value; 84 | JsonNode *next; 85 | char *key; 86 | }; 87 | 88 | struct JsonIterator { 89 | JsonNode *p; 90 | 91 | void operator++() { 92 | p = p->next; 93 | } 94 | bool operator!=(const JsonIterator &x) const { 95 | return p != x.p; 96 | } 97 | JsonNode *operator*() const { 98 | return p; 99 | } 100 | JsonNode *operator->() const { 101 | return p; 102 | } 103 | }; 104 | 105 | inline JsonIterator begin(JsonValue o) { 106 | return JsonIterator{o.toNode()}; 107 | } 108 | inline JsonIterator end(JsonValue) { 109 | return JsonIterator{nullptr}; 110 | } 111 | 112 | #define JSON_ERRNO_MAP(XX) \ 113 | XX(OK, "ok") \ 114 | XX(BAD_NUMBER, "bad number") \ 115 | XX(BAD_STRING, "bad string") \ 116 | XX(BAD_IDENTIFIER, "bad identifier") \ 117 | XX(STACK_OVERFLOW, "stack overflow") \ 118 | XX(STACK_UNDERFLOW, "stack underflow") \ 119 | XX(MISMATCH_BRACKET, "mismatch bracket") \ 120 | XX(UNEXPECTED_CHARACTER, "unexpected character") \ 121 | XX(UNQUOTED_KEY, "unquoted key") \ 122 | XX(BREAKING_BAD, "breaking bad") \ 123 | XX(ALLOCATION_FAILURE, "allocation failure") 124 | 125 | enum JsonErrno { 126 | #define XX(no, str) JSON_##no, 127 | JSON_ERRNO_MAP(XX) 128 | #undef XX 129 | }; 130 | 131 | const char *jsonStrError(int err); 132 | 133 | class JsonAllocator { 134 | struct Zone { 135 | Zone *next; 136 | size_t used; 137 | } *head = nullptr; 138 | 139 | public: 140 | JsonAllocator() = default; 141 | JsonAllocator(const JsonAllocator &) = delete; 142 | JsonAllocator &operator=(const JsonAllocator &) = delete; 143 | JsonAllocator(JsonAllocator &&x) : head(x.head) { 144 | x.head = nullptr; 145 | } 146 | JsonAllocator &operator=(JsonAllocator &&x) { 147 | head = x.head; 148 | x.head = nullptr; 149 | return *this; 150 | } 151 | ~JsonAllocator() { 152 | deallocate(); 153 | } 154 | void *allocate(size_t size); 155 | void deallocate(); 156 | }; 157 | 158 | int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator); -------------------------------------------------------------------------------- /eval/CIPO_evaluation/common/maskApi.c: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | maskApi.c The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/cocodataset/cocoapi/blob/master/common/maskApi.c 8 | https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #include "maskApi.h" 25 | #include 26 | #include 27 | 28 | uint umin( uint a, uint b ) { return (ab) ? a : b; } 30 | 31 | void rleInit( RLE *R, siz h, siz w, siz m, uint *cnts ) { 32 | R->h=h; R->w=w; R->m=m; R->cnts=(m==0)?0:malloc(sizeof(uint)*m); 33 | siz j; if(cnts) for(j=0; jcnts[j]=cnts[j]; 34 | } 35 | 36 | void rleFree( RLE *R ) { 37 | free(R->cnts); R->cnts=0; 38 | } 39 | 40 | void rlesInit( RLE **R, siz n ) { 41 | siz i; *R = (RLE*) malloc(sizeof(RLE)*n); 42 | for(i=0; i0 ) { 78 | c=umin(ca,cb); cc+=c; ct=0; 79 | ca-=c; if(!ca && a0) { 100 | crowd=iscrowd!=NULL && iscrowd[g]; 101 | if(dt[d].h!=gt[g].h || dt[d].w!=gt[g].w) { o[g*m+d]=-1; continue; } 102 | siz ka, kb, a, b; uint c, ca, cb, ct, i, u; int va, vb; 103 | ca=dt[d].cnts[0]; ka=dt[d].m; va=vb=0; 104 | cb=gt[g].cnts[0]; kb=gt[g].m; a=b=1; i=u=0; ct=1; 105 | while( ct>0 ) { 106 | c=umin(ca,cb); if(va||vb) { u+=c; if(va&&vb) i+=c; } ct=0; 107 | ca-=c; if(!ca && athr) keep[j]=0; 122 | } 123 | } 124 | } 125 | 126 | void bbIou( BB dt, BB gt, siz m, siz n, byte *iscrowd, double *o ) { 127 | double h, w, i, u, ga, da; siz g, d; int crowd; 128 | for( g=0; gthr) keep[j]=0; 146 | } 147 | } 148 | } 149 | 150 | void rleToBbox( const RLE *R, BB bb, siz n ) { 151 | siz i; for( i=0; id?1:c=dy && xs>xe) || (dxye); 191 | if(flip) { t=xs; xs=xe; xe=t; t=ys; ys=ye; ye=t; } 192 | s = dx>=dy ? (double)(ye-ys)/dx : (double)(xe-xs)/dy; 193 | if(dx>=dy) for( d=0; d<=dx; d++ ) { 194 | t=flip?dx-d:d; u[m]=t+xs; v[m]=(int)(ys+s*t+.5); m++; 195 | } else for( d=0; d<=dy; d++ ) { 196 | t=flip?dy-d:d; v[m]=t+ys; u[m]=(int)(xs+s*t+.5); m++; 197 | } 198 | } 199 | /* get points along y-boundary and downsample */ 200 | free(x); free(y); k=m; m=0; double xd, yd; 201 | x=malloc(sizeof(int)*k); y=malloc(sizeof(int)*k); 202 | for( j=1; jw-1 ) continue; 205 | yd=(double)(v[j]h) yd=h; yd=ceil(yd); 207 | x[m]=(int) xd; y[m]=(int) yd; m++; 208 | } 209 | /* compute rle encoding given y-boundary points */ 210 | k=m; a=malloc(sizeof(uint)*(k+1)); 211 | for( j=0; j0) b[m++]=a[j++]; else { 217 | j++; if(jm, p=0; long x; int more; 224 | char *s=malloc(sizeof(char)*m*6); 225 | for( i=0; icnts[i]; if(i>2) x-=(long) R->cnts[i-2]; more=1; 227 | while( more ) { 228 | char c=x & 0x1f; x >>= 5; more=(c & 0x10) ? x!=-1 : x!=0; 229 | if(more) c |= 0x20; c+=48; s[p++]=c; 230 | } 231 | } 232 | s[p]=0; return s; 233 | } 234 | 235 | void rleFrString( RLE *R, char *s, siz h, siz w ) { 236 | siz m=0, p=0, k; long x; int more; uint *cnts; 237 | while( s[m] ) m++; cnts=malloc(sizeof(uint)*m); m=0; 238 | while( s[p] ) { 239 | x=0; k=0; more=1; 240 | while( more ) { 241 | char c=s[p]-48; x |= (c & 0x1f) << 5*k; 242 | more = c & 0x20; p++; k++; 243 | if(!more && (c & 0x10)) x |= -1 << 5*k; 244 | } 245 | if(m>2) x+=(long) cnts[m-2]; cnts[m++]=(uint) x; 246 | } 247 | rleInit(R,h,w,m,cnts); free(cnts); 248 | } -------------------------------------------------------------------------------- /eval/CIPO_evaluation/common/maskApi.h: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | maskApi.h The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/cocodataset/cocoapi/blob/master/common/maskApi.h 8 | https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #pragma once 25 | 26 | typedef unsigned int uint; 27 | typedef unsigned long siz; 28 | typedef unsigned char byte; 29 | typedef double* BB; 30 | typedef struct { siz h, w, m; uint *cnts; } RLE; 31 | 32 | /* Initialize/destroy RLE. */ 33 | void rleInit( RLE *R, siz h, siz w, siz m, uint *cnts ); 34 | void rleFree( RLE *R ); 35 | 36 | /* Initialize/destroy RLE array. */ 37 | void rlesInit( RLE **R, siz n ); 38 | void rlesFree( RLE **R, siz n ); 39 | 40 | /* Encode binary masks using RLE. */ 41 | void rleEncode( RLE *R, const byte *mask, siz h, siz w, siz n ); 42 | 43 | /* Decode binary masks encoded via RLE. */ 44 | void rleDecode( const RLE *R, byte *mask, siz n ); 45 | 46 | /* Compute union or intersection of encoded masks. */ 47 | void rleMerge( const RLE *R, RLE *M, siz n, int intersect ); 48 | 49 | /* Compute area of encoded masks. */ 50 | void rleArea( const RLE *R, siz n, uint *a ); 51 | 52 | /* Compute intersection over union between masks. */ 53 | void rleIou( RLE *dt, RLE *gt, siz m, siz n, byte *iscrowd, double *o ); 54 | 55 | /* Compute non-maximum suppression between bounding masks */ 56 | void rleNms( RLE *dt, siz n, uint *keep, double thr ); 57 | 58 | /* Compute intersection over union between bounding boxes. */ 59 | void bbIou( BB dt, BB gt, siz m, siz n, byte *iscrowd, double *o ); 60 | 61 | /* Compute non-maximum suppression between bounding boxes */ 62 | void bbNms( BB dt, siz n, uint *keep, double thr ); 63 | 64 | /* Get bounding boxes surrounding encoded masks. */ 65 | void rleToBbox( const RLE *R, BB bb, siz n ); 66 | 67 | /* Convert bounding boxes to encoded masks. */ 68 | void rleFrBbox( RLE *R, const BB bb, siz h, siz w, siz n ); 69 | 70 | /* Convert polygon to encoded mask. */ 71 | void rleFrPoly( RLE *R, const double *xy, siz k, siz h, siz w ); 72 | 73 | /* Get compressed string representation of encoded mask. */ 74 | char* rleToString( const RLE *R ); 75 | 76 | /* Convert from compressed string representation of encoded mask. */ 77 | void rleFrString( RLE *R, char *s, siz h, siz w ); -------------------------------------------------------------------------------- /eval/CIPO_evaluation/eval.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # eval.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # See: 7 | # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb 8 | # https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | # 10 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # ============================================================================== 24 | 25 | from adapter import adapter 26 | from pycocotools.cocoeval import COCOeval 27 | import argparse 28 | 29 | def CIPO_eval(annFile, resFile): 30 | 31 | # load annotation 32 | cocoGt = adapter(annFile) 33 | print(len(cocoGt.getAnnIds())) 34 | 35 | # load result 36 | cocoDt=cocoGt.loadRes(resFile) 37 | 38 | imgIds=sorted(list(cocoGt.imgs.keys())) 39 | 40 | # run evaluation 41 | cocoEval = COCOeval(cocoGt,cocoDt) 42 | cocoEval.params.imgIds = imgIds 43 | cocoEval.evaluate() 44 | cocoEval.accumulate() 45 | cocoEval.summarize() 46 | 47 | 48 | if __name__ == '__main__': 49 | parser = argparse.ArgumentParser(description='prepare your results and annotations as required') 50 | parser.add_argument('--anno_txt', type=str, help='The txtfile saving anno json paths') 51 | parser.add_argument('--res_txt', type=str, help='The txtfile saving res json paths') 52 | 53 | args = parser.parse_args() 54 | 55 | CIPO_eval(args.anno_txt, args.res_txt) 56 | -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/EvalDemo.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # EvalDemo.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # See: 7 | # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb 8 | # https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | # 10 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # ============================================================================== 24 | 25 | import argparse 26 | import sys 27 | sys.path.append("../") 28 | from adapter import adapter 29 | from pycocotools.cocoeval import COCOeval 30 | 31 | def CIPO_eval(annFile, resFile): 32 | 33 | # load annotation 34 | cocoGt = adapter(annFile) 35 | print(len(cocoGt.getAnnIds())) 36 | 37 | # load result 38 | cocoDt=cocoGt.loadRes(resFile) 39 | 40 | imgIds=sorted(list(cocoGt.imgs.keys())) 41 | 42 | # run evaluation 43 | cocoEval = COCOeval(cocoGt,cocoDt) 44 | cocoEval.params.imgIds = imgIds 45 | cocoEval.evaluate() 46 | cocoEval.accumulate() 47 | cocoEval.summarize() 48 | 49 | 50 | if __name__ == '__main__': 51 | parser = argparse.ArgumentParser(description='prepare your results and annotations as required') 52 | parser.add_argument('--anno_txt', type=str, help='The txtfile saving anno json paths') 53 | parser.add_argument('--res_txt', type=str, help='The txtfile saving res json paths') 54 | 55 | args = parser.parse_args() 56 | 57 | CIPO_eval(args.anno_txt, args.res_txt) 58 | 59 | -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/annotations/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113624736600.jpg.json: -------------------------------------------------------------------------------- 1 | {"results": [{"width": 425.97385499999996, "height": 443.37617999999986, "x": 1494.0261449999998, "y": 776.2241100000001, "id": "4", "type": 1}, {"width": 11.368619999999964, "height": 30.94790999999998, "x": 1180.4417099999996, "y": 635.0637449999999, "id": "4", "type": 2}, {"width": 24.632111073940905, "height": 19.579290000000015, "x": 948.3323344630295, "y": 608.7474388478106, "id": "4", "type": 1}, {"width": 14.526569999999992, "height": 24.632010000000037, "x": 687.485715, "y": 620.5371749999999, "id": "4", "type": 2}, {"width": 131.3371199999999, "height": 104.21235000000001, "x": 1788.6628799999999, "y": 678.643455, "id": "4", "type": 1}, {"width": 28.421550000000025, "height": 22.737240000000043, "x": 1001.385945, "y": 622.74774, "id": "4", "type": 1}, {"width": 144.63410999999996, "height": 95.37009, "x": 1413.182625, "y": 644.537595, "id": "4", "type": 1}, {"width": 17.68452000000002, "height": 17.68452000000002, "x": 699.17013, "y": 603.80004, "id": "4", "type": 1}, {"width": 42.52693576742274, "height": 26.947774725256068, "x": 576.2208553066989, "y": 632.8531578908126, "id": "4", "type": 1}, {"width": 169.26612, "height": 118.10732999999993, "x": 348.00609, "y": 643.906005, "id": "4", "type": 1}, {"width": 53.05360421771161, "height": 45.79030184646774, "x": 673.9064605150246, "y": 648.1692319727861, "id": "4", "type": 1}, {"width": 18.000315, "height": 29.053139999999985, "x": 0, "y": 641.06385, "id": "4", "type": 2}, {"width": 8.84226000000001, "height": 10.737030000000004, "x": 798.96135, "y": 609.168555, "id": "4", "type": 1}, {"width": 19.579290000000015, "height": 47.369249999999965, "x": 292.110375, "y": 649.590315, "id": "4", "type": 2}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1132.756665, "y": 618.32661, "id": "4", "type": 2}, {"width": 28.421550000000025, "height": 19.579290000000015, "x": 969.8064449999999, "y": 606.6421949999999, "id": "4", "type": 1}, {"width": 104.21235000000001, "height": 77.68556999999998, "x": 573.167925, "y": 640.7480549999998, "id": "4", "type": 1}, {"width": 24.0005937206912, "height": 20.21094948827647, "x": 787.2766831049978, "y": 626.5373668603456, "id": "4", "type": 1}, {"width": 22.737239999999986, "height": 22.737240000000043, "x": 329.68998, "y": 647.3797500000001, "id": "4", "type": 1}, {"width": 31.57949999999994, "height": 22.737240000000043, "x": 1006.7544600000001, "y": 636.64272, "id": "4", "type": 1}, {"width": 31.579500000000053, "height": 39.15858000000003, "x": 1033.2812400000003, "y": 584.22075, "id": "4", "type": 1}, {"width": 39.158579999999915, "height": 33.47427000000005, "x": 1020.6494400000001, "y": 643.906005, "id": "4", "type": 1}, {"width": 8.210669999999993, "height": 8.21067000000005, "x": 438.007665, "y": 638.2216950000002, "id": "4", "type": 2}, {"width": 54.94833, "height": 82.73829, "x": 145.581495, "y": 650.853495, "id": "4", "type": 1}, {"width": 58.10627999999997, "height": 39.15858000000003, "x": 1191.81033, "y": 646.11657, "id": "4", "type": 1}, {"width": 99.15962999999999, "height": 84.63306, "x": 305.373765, "y": 649.9061099999999, "id": "4", "type": 1}, {"width": 14.526569999999992, "height": 31.579441890349585, "x": 1148.799376414042, "y": 613.9056252741257, "id": "4", "type": 2}, {"width": 30.316319999999905, "height": 28.421550000000025, "x": 1051.59735, "y": 596.536755, "id": "4", "type": 1}, {"width": 26.52678000000003, "height": 28.421550000000025, "x": 663.1695, "y": 646.432365, "id": "4", "type": 1}, {"width": 24.632010000000008, "height": 58.73787000000004, "x": 239.05681499999997, "y": 640.748055, "id": "4", "type": 2}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1137.809385, "y": 619.58979, "id": "4", "type": 2}, {"width": 70.10648368308921, "height": 43.158708957833255, "x": 1047.7025313133602, "y": 636.9585023661787, "id": "4", "type": 1}, {"width": 106.1071199999999, "height": 72.63284999999996, "x": 1044.01827, "y": 655.906215, "id": "4", "type": 1}, {"width": 31.579500000000053, "height": 24.632000524776117, "x": 947.7007997376119, "y": 625.90569, "id": "4", "type": 1}, {"width": 79.58033999999998, "height": 54.94832999999994, "x": 1261.91682, "y": 645.169185, "id": "4", "type": 1}, {"width": 11.36862, "height": 11.368619999999964, "x": 42.94812, "y": 646.74816, "id": "4", "type": 2}, {"width": 29.36893973761198, "height": 33.47427000000005, "x": 975.3328693440299, "y": 580.115405524776, "id": "4", "type": 1}, {"width": 16.105583948699177, "height": 25.684530171002848, "x": 1160.9145007267625, "y": 635.5900050855014, "id": "4", "type": 2}, {"width": 184.740075, "height": 148.42364999999995, "x": 0, "y": 647.695545, "id": "4", "type": 1}, {"width": 22.73723999999993, "height": 47.369249999999965, "x": 1138.75677, "y": 641.379645, "id": "4", "type": 4}, {"width": 8.84226000000001, "height": 17.68452000000002, "x": 732.0128100000002, "y": 610.74753, "id": "4", "type": 1}, {"width": 22.737240000000043, "height": 19.579290000000015, "x": 714.3282900000002, "y": 645.169185, "id": "4", "type": 1}], "raw_file_path": "training/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/images/155840113624736600.jpg"} -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/annotations/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113634736000.jpg.json: -------------------------------------------------------------------------------- 1 | {"results": [{"width": 405.52694674903, "height": 463.58625147586235, "x": 1514.4730532509702, "y": 781.9081926025863, "id": "4", "type": 1}, {"width": 13.263390000000072, "height": 30.94790999999998, "x": 1183.9154549999998, "y": 635.0637449999999, "id": "4", "type": 2}, {"width": 26.526963196517954, "height": 19.579290000000015, "x": 947.384908401741, "y": 607.6947432241566, "id": "4", "type": 1}, {"width": 14.526569999999992, "height": 29.053139999999985, "x": 687.485715, "y": 616.43184, "id": "4", "type": 2}, {"width": 70.7044800000001, "height": 84.63306, "x": 1849.2955199999997, "y": 697.2753600000001, "id": "4", "type": 1}, {"width": 28.42154999999991, "height": 22.737240000000043, "x": 1003.2807149999999, "y": 620.8529700000001, "id": "4", "type": 1}, {"width": 151.89790354182924, "height": 97.89662688411454, "x": 1430.7104746335444, "y": 644.2217778894857, "id": "4", "type": 1}, {"width": 17.68452000000002, "height": 17.68452000000002, "x": 699.17013, "y": 603.80004, "id": "4", "type": 1}, {"width": 54.94832999999994, "height": 33.47427000000005, "x": 551.693865, "y": 635.0637449999999, "id": "4", "type": 1}, {"width": 183.79269, "height": 113.05461000000003, "x": 305.373765, "y": 651.485085, "id": "4", "type": 1}, {"width": 61.89581999999996, "height": 51.158789999999954, "x": 660.01155, "y": 647.063955, "id": "4", "type": 1}, {"width": 8.84226000000001, "height": 12.631799999999998, "x": 797.6981700000001, "y": 608.2211699999998, "id": "4", "type": 1}, {"width": 16.421339999999987, "height": 36.00063, "x": 282.32073, "y": 647.063955, "id": "4", "type": 2}, {"width": 8.210669999999936, "height": 29.684748951111146, "x": 1135.493637121482, "y": 618.4318781585184, "id": "4", "type": 2}, {"width": 28.421550000000025, "height": 19.579290000000015, "x": 967.911675, "y": 604.747425, "id": "4", "type": 1}, {"width": 120.00210000000004, "height": 84.63306, "x": 543.79899, "y": 642.9586199999999, "id": "4", "type": 1}, {"width": 27.158677959407214, "height": 21.474183183762875, "x": 782.6974609588596, "y": 628.1164089797037, "id": "4", "type": 1}, {"width": 31.57949999999994, "height": 28.421550000000025, "x": 1010.5440000000001, "y": 628.747845, "id": "4", "type": 1}, {"width": 31.579500000000053, "height": 39.15858000000003, "x": 1036.1235939946291, "y": 584.22075, "id": "4", "type": 1}, {"width": 39.15858000000003, "height": 33.47427000000005, "x": 1024.43898, "y": 642.0112349999999, "id": "4", "type": 1}, {"width": 14.526569999999992, "height": 16.421339999999987, "x": 428.533815, "y": 642.3270299999999, "id": "4", "type": 2}, {"width": 77.68556999999998, "height": 84.63306, "x": 132.318105, "y": 651.80088, "id": "4", "type": 1}, {"width": 61.89581999999996, "height": 39.15858000000003, "x": 1194.96828, "y": 648.01134, "id": "4", "type": 1}, {"width": 75.79079999999999, "height": 91.58055000000002, "x": 267.79416, "y": 649.5903149999999, "id": "4", "type": 1}, {"width": 14.526569999999992, "height": 30.94790999999998, "x": 1152.335955, "y": 615.484455, "id": "4", "type": 2}, {"width": 31.579500000000053, "height": 28.421550000000025, "x": 1054.7553000000003, "y": 596.536755, "id": "4", "type": 1}, {"width": 33.05340582814904, "height": 32.000667389630166, "x": 649.3793712340719, "y": 648.6429963288892, "id": "4", "type": 1}, {"width": 24.632010000000008, "height": 63.79058999999995, "x": 224.53024499999998, "y": 646.4323649999999, "id": "4", "type": 2}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1140.967335, "y": 619.58979, "id": "4", "type": 2}, {"width": 70.73808000000008, "height": 37.263810000000035, "x": 1049.07099, "y": 638.2216950000002, "id": "4", "type": 1}, {"width": 106.1071199999999, "height": 73.26448422102862, "x": 1042.1233673369143, "y": 655.5903978894856, "id": "4", "type": 1}, {"width": 31.579500000000053, "height": 22.737240000000043, "x": 948.6481799999999, "y": 625.90569, "id": "4", "type": 1}, {"width": 81.47511000000009, "height": 54.948330000000055, "x": 1273.601235, "y": 643.2744149999999, "id": "4", "type": 1}, {"width": 30.31632000000002, "height": 33.47427000000005, "x": 977.7013200000001, "y": 578.2206449999999, "id": "4", "type": 1}, {"width": 15.78983105540101, "height": 26.737039815330263, "x": 1165.3876667151535, "y": 636.116259907665, "id": "4", "type": 2}, {"width": 90.001575, "height": 157.26590999999996, "x": 0, "y": 652.116675, "id": "4", "type": 1}, {"width": 22.73723999999993, "height": 47.369249999999965, "x": 1141.91472, "y": 640.116465, "id": "4", "type": 4}, {"width": 24.947716567672387, "height": 21.31609301745698, "x": 705.3284925459051, "y": 646.9849336091595, "id": "4", "type": 1}], "raw_file_path": "training/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/images/155840113634736000.jpg"} -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/resfile.txt: -------------------------------------------------------------------------------- 1 | segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113624736600.jpg.json 2 | segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113634736000.jpg.json -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/results/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113624736600.jpg.json: -------------------------------------------------------------------------------- 1 | {"raw_file_path": "training/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/images/155840113624736600.jpg", "results": [{"width": 425.97385499999996, "height": 443.37617999999986, "x": 1494.0261449999998, "y": 776.2241100000001, "id": "4", "type": 1, "score": 0.7}, {"width": 11.368619999999964, "height": 30.94790999999998, "x": 1180.4417099999996, "y": 635.0637449999999, "id": "4", "type": 2, "score": 0.7}, {"width": 24.632111073940905, "height": 19.579290000000015, "x": 948.3323344630295, "y": 608.7474388478106, "id": "4", "type": 1, "score": 0.7}, {"width": 14.526569999999992, "height": 24.632010000000037, "x": 687.485715, "y": 620.5371749999999, "id": "4", "type": 2, "score": 0.7}, {"width": 131.3371199999999, "height": 104.21235000000001, "x": 1788.6628799999999, "y": 678.643455, "id": "4", "type": 1, "score": 0.7}, {"width": 28.421550000000025, "height": 22.737240000000043, "x": 1001.385945, "y": 622.74774, "id": "4", "type": 1, "score": 0.7}, {"width": 144.63410999999996, "height": 95.37009, "x": 1413.182625, "y": 644.537595, "id": "4", "type": 1, "score": 0.7}, {"width": 17.68452000000002, "height": 17.68452000000002, "x": 699.17013, "y": 603.80004, "id": "4", "type": 1, "score": 0.7}, {"width": 42.52693576742274, "height": 26.947774725256068, "x": 576.2208553066989, "y": 632.8531578908126, "id": "4", "type": 1, "score": 0.7}, {"width": 169.26612, "height": 118.10732999999993, "x": 348.00609, "y": 643.906005, "id": "4", "type": 1, "score": 0.7}, {"width": 53.05360421771161, "height": 45.79030184646774, "x": 673.9064605150246, "y": 648.1692319727861, "id": "4", "type": 1, "score": 0.7}, {"width": 18.000315, "height": 29.053139999999985, "x": 0, "y": 641.06385, "id": "4", "type": 2, "score": 0.7}, {"width": 8.84226000000001, "height": 10.737030000000004, "x": 798.96135, "y": 609.168555, "id": "4", "type": 1, "score": 0.7}, {"width": 19.579290000000015, "height": 47.369249999999965, "x": 292.110375, "y": 649.590315, "id": "4", "type": 2, "score": 0.7}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1132.756665, "y": 618.32661, "id": "4", "type": 2, "score": 0.7}, {"width": 28.421550000000025, "height": 19.579290000000015, "x": 969.8064449999999, "y": 606.6421949999999, "id": "4", "type": 1, "score": 0.7}, {"width": 104.21235000000001, "height": 77.68556999999998, "x": 573.167925, "y": 640.7480549999998, "id": "4", "type": 1, "score": 0.7}, {"width": 24.0005937206912, "height": 20.21094948827647, "x": 787.2766831049978, "y": 626.5373668603456, "id": "4", "type": 1, "score": 0.7}, {"width": 22.737239999999986, "height": 22.737240000000043, "x": 329.68998, "y": 647.3797500000001, "id": "4", "type": 1, "score": 0.7}, {"width": 31.57949999999994, "height": 22.737240000000043, "x": 1006.7544600000001, "y": 636.64272, "id": "4", "type": 1, "score": 0.7}, {"width": 31.579500000000053, "height": 39.15858000000003, "x": 1033.2812400000003, "y": 584.22075, "id": "4", "type": 1, "score": 0.7}, {"width": 39.158579999999915, "height": 33.47427000000005, "x": 1020.6494400000001, "y": 643.906005, "id": "4", "type": 1, "score": 0.7}, {"width": 8.210669999999993, "height": 8.21067000000005, "x": 438.007665, "y": 638.2216950000002, "id": "4", "type": 2, "score": 0.7}, {"width": 54.94833, "height": 82.73829, "x": 145.581495, "y": 650.853495, "id": "4", "type": 1, "score": 0.7}, {"width": 58.10627999999997, "height": 39.15858000000003, "x": 1191.81033, "y": 646.11657, "id": "4", "type": 1, "score": 0.7}, {"width": 99.15962999999999, "height": 84.63306, "x": 305.373765, "y": 649.9061099999999, "id": "4", "type": 1, "score": 0.7}, {"width": 14.526569999999992, "height": 31.579441890349585, "x": 1148.799376414042, "y": 613.9056252741257, "id": "4", "type": 2, "score": 0.7}, {"width": 30.316319999999905, "height": 28.421550000000025, "x": 1051.59735, "y": 596.536755, "id": "4", "type": 1, "score": 0.7}, {"width": 26.52678000000003, "height": 28.421550000000025, "x": 663.1695, "y": 646.432365, "id": "4", "type": 1, "score": 0.7}, {"width": 24.632010000000008, "height": 58.73787000000004, "x": 239.05681499999997, "y": 640.748055, "id": "4", "type": 2, "score": 0.7}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1137.809385, "y": 619.58979, "id": "4", "type": 2, "score": 0.7}, {"width": 70.10648368308921, "height": 43.158708957833255, "x": 1047.7025313133602, "y": 636.9585023661787, "id": "4", "type": 1, "score": 0.7}, {"width": 106.1071199999999, "height": 72.63284999999996, "x": 1044.01827, "y": 655.906215, "id": "4", "type": 1, "score": 0.7}, {"width": 31.579500000000053, "height": 24.632000524776117, "x": 947.7007997376119, "y": 625.90569, "id": "4", "type": 1, "score": 0.7}, {"width": 79.58033999999998, "height": 54.94832999999994, "x": 1261.91682, "y": 645.169185, "id": "4", "type": 1, "score": 0.7}, {"width": 11.36862, "height": 11.368619999999964, "x": 42.94812, "y": 646.74816, "id": "4", "type": 2, "score": 0.7}, {"width": 29.36893973761198, "height": 33.47427000000005, "x": 975.3328693440299, "y": 580.115405524776, "id": "4", "type": 1, "score": 0.7}, {"width": 16.105583948699177, "height": 25.684530171002848, "x": 1160.9145007267625, "y": 635.5900050855014, "id": "4", "type": 2, "score": 0.7}, {"width": 184.740075, "height": 148.42364999999995, "x": 0, "y": 647.695545, "id": "4", "type": 1, "score": 0.7}, {"width": 22.73723999999993, "height": 47.369249999999965, "x": 1138.75677, "y": 641.379645, "id": "4", "type": 4, "score": 0.7}, {"width": 8.84226000000001, "height": 17.68452000000002, "x": 732.0128100000002, "y": 610.74753, "id": "4", "type": 1, "score": 0.7}, {"width": 22.737240000000043, "height": 19.579290000000015, "x": 714.3282900000002, "y": 645.169185, "id": "4", "type": 1, "score": 0.7}]} -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/results/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113634736000.jpg.json: -------------------------------------------------------------------------------- 1 | {"raw_file_path": "training/segment-1146261869236413282_1680_000_1700_000_with_camera_labels/images/155840113634736000.jpg", "results": [{"width": 405.52694674903, "height": 463.58625147586235, "x": 1514.4730532509702, "y": 781.9081926025863, "id": "4", "type": 1, "score": 0.7}, {"width": 13.263390000000072, "height": 30.94790999999998, "x": 1183.9154549999998, "y": 635.0637449999999, "id": "4", "type": 2, "score": 0.7}, {"width": 26.526963196517954, "height": 19.579290000000015, "x": 947.384908401741, "y": 607.6947432241566, "id": "4", "type": 1, "score": 0.7}, {"width": 14.526569999999992, "height": 29.053139999999985, "x": 687.485715, "y": 616.43184, "id": "4", "type": 2, "score": 0.7}, {"width": 70.7044800000001, "height": 84.63306, "x": 1849.2955199999997, "y": 697.2753600000001, "id": "4", "type": 1, "score": 0.7}, {"width": 28.42154999999991, "height": 22.737240000000043, "x": 1003.2807149999999, "y": 620.8529700000001, "id": "4", "type": 1, "score": 0.7}, {"width": 151.89790354182924, "height": 97.89662688411454, "x": 1430.7104746335444, "y": 644.2217778894857, "id": "4", "type": 1, "score": 0.7}, {"width": 17.68452000000002, "height": 17.68452000000002, "x": 699.17013, "y": 603.80004, "id": "4", "type": 1, "score": 0.7}, {"width": 54.94832999999994, "height": 33.47427000000005, "x": 551.693865, "y": 635.0637449999999, "id": "4", "type": 1, "score": 0.7}, {"width": 183.79269, "height": 113.05461000000003, "x": 305.373765, "y": 651.485085, "id": "4", "type": 1, "score": 0.7}, {"width": 61.89581999999996, "height": 51.158789999999954, "x": 660.01155, "y": 647.063955, "id": "4", "type": 1, "score": 0.7}, {"width": 8.84226000000001, "height": 12.631799999999998, "x": 797.6981700000001, "y": 608.2211699999998, "id": "4", "type": 1, "score": 0.7}, {"width": 16.421339999999987, "height": 36.00063, "x": 282.32073, "y": 647.063955, "id": "4", "type": 2, "score": 0.7}, {"width": 8.210669999999936, "height": 29.684748951111146, "x": 1135.493637121482, "y": 618.4318781585184, "id": "4", "type": 2, "score": 0.7}, {"width": 28.421550000000025, "height": 19.579290000000015, "x": 967.911675, "y": 604.747425, "id": "4", "type": 1, "score": 0.7}, {"width": 120.00210000000004, "height": 84.63306, "x": 543.79899, "y": 642.9586199999999, "id": "4", "type": 1, "score": 0.7}, {"width": 27.158677959407214, "height": 21.474183183762875, "x": 782.6974609588596, "y": 628.1164089797037, "id": "4", "type": 1, "score": 0.7}, {"width": 31.57949999999994, "height": 28.421550000000025, "x": 1010.5440000000001, "y": 628.747845, "id": "4", "type": 1, "score": 0.7}, {"width": 31.579500000000053, "height": 39.15858000000003, "x": 1036.1235939946291, "y": 584.22075, "id": "4", "type": 1, "score": 0.7}, {"width": 39.15858000000003, "height": 33.47427000000005, "x": 1024.43898, "y": 642.0112349999999, "id": "4", "type": 1, "score": 0.7}, {"width": 14.526569999999992, "height": 16.421339999999987, "x": 428.533815, "y": 642.3270299999999, "id": "4", "type": 2, "score": 0.7}, {"width": 77.68556999999998, "height": 84.63306, "x": 132.318105, "y": 651.80088, "id": "4", "type": 1, "score": 0.7}, {"width": 61.89581999999996, "height": 39.15858000000003, "x": 1194.96828, "y": 648.01134, "id": "4", "type": 1, "score": 0.7}, {"width": 75.79079999999999, "height": 91.58055000000002, "x": 267.79416, "y": 649.5903149999999, "id": "4", "type": 1, "score": 0.7}, {"width": 14.526569999999992, "height": 30.94790999999998, "x": 1152.335955, "y": 615.484455, "id": "4", "type": 2, "score": 0.7}, {"width": 31.579500000000053, "height": 28.421550000000025, "x": 1054.7553000000003, "y": 596.536755, "id": "4", "type": 1, "score": 0.7}, {"width": 33.05340582814904, "height": 32.000667389630166, "x": 649.3793712340719, "y": 648.6429963288892, "id": "4", "type": 1, "score": 0.7}, {"width": 24.632010000000008, "height": 63.79058999999995, "x": 224.53024499999998, "y": 646.4323649999999, "id": "4", "type": 2, "score": 0.7}, {"width": 8.210669999999936, "height": 29.053139999999985, "x": 1140.967335, "y": 619.58979, "id": "4", "type": 2, "score": 0.7}, {"width": 70.73808000000008, "height": 37.263810000000035, "x": 1049.07099, "y": 638.2216950000002, "id": "4", "type": 1, "score": 0.7}, {"width": 106.1071199999999, "height": 73.26448422102862, "x": 1042.1233673369143, "y": 655.5903978894856, "id": "4", "type": 1, "score": 0.7}, {"width": 31.579500000000053, "height": 22.737240000000043, "x": 948.6481799999999, "y": 625.90569, "id": "4", "type": 1, "score": 0.7}, {"width": 81.47511000000009, "height": 54.948330000000055, "x": 1273.601235, "y": 643.2744149999999, "id": "4", "type": 1, "score": 0.7}, {"width": 30.31632000000002, "height": 33.47427000000005, "x": 977.7013200000001, "y": 578.2206449999999, "id": "4", "type": 1, "score": 0.7}, {"width": 15.78983105540101, "height": 26.737039815330263, "x": 1165.3876667151535, "y": 636.116259907665, "id": "4", "type": 2, "score": 0.7}, {"width": 90.001575, "height": 157.26590999999996, "x": 0, "y": 652.116675, "id": "4", "type": 1, "score": 0.7}, {"width": 22.73723999999993, "height": 47.369249999999965, "x": 1141.91472, "y": 640.116465, "id": "4", "type": 4, "score": 0.7}, {"width": 24.947716567672387, "height": 21.31609301745698, "x": 705.3284925459051, "y": 646.9849336091595, "id": "4", "type": 1, "score": 0.7}]} -------------------------------------------------------------------------------- /eval/CIPO_evaluation/example/txtfile.txt: -------------------------------------------------------------------------------- 1 | segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113624736600.jpg.json 2 | segment-1146261869236413282_1680_000_1700_000_with_camera_labels/155840113634736000.jpg.json -------------------------------------------------------------------------------- /eval/CIPO_evaluation/pycocotools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/eval/CIPO_evaluation/pycocotools/__init__.py -------------------------------------------------------------------------------- /eval/CIPO_evaluation/pycocotools/mask.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # mask.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # See: 7 | # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/mask.py 8 | # https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | # 10 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # ============================================================================== 24 | 25 | import pycocotools._mask as _mask 26 | 27 | # Interface for manipulating masks stored in RLE format. 28 | # 29 | # RLE is a simple yet efficient format for storing binary masks. RLE 30 | # first divides a vector (or vectorized image) into a series of piecewise 31 | # constant regions and then for each piece simply stores the length of 32 | # that piece. For example, given M=[0 0 1 1 1 0 1] the RLE counts would 33 | # be [2 3 1 1], or for M=[1 1 1 1 1 1 0] the counts would be [0 6 1] 34 | # (note that the odd counts are always the numbers of zeros). Instead of 35 | # storing the counts directly, additional compression is achieved with a 36 | # variable bitrate representation based on a common scheme called LEB128. 37 | # 38 | # Compression is greatest given large piecewise constant regions. 39 | # Specifically, the size of the RLE is proportional to the number of 40 | # *boundaries* in M (or for an image the number of boundaries in the y 41 | # direction). Assuming fairly simple shapes, the RLE representation is 42 | # O(sqrt(n)) where n is number of pixels in the object. Hence space usage 43 | # is substantially lower, especially for large simple objects (large n). 44 | # 45 | # Many common operations on masks can be computed directly using the RLE 46 | # (without need for decoding). This includes computations such as area, 47 | # union, intersection, etc. All of these operations are linear in the 48 | # size of the RLE, in other words they are O(sqrt(n)) where n is the area 49 | # of the object. Computing these operations on the original mask is O(n). 50 | # Thus, using the RLE can result in substantial computational savings. 51 | # 52 | # The following API functions are defined: 53 | # encode - Encode binary masks using RLE. 54 | # decode - Decode binary masks encoded via RLE. 55 | # merge - Compute union or intersection of encoded masks. 56 | # iou - Compute intersection over union between masks. 57 | # area - Compute area of encoded masks. 58 | # toBbox - Get bounding boxes surrounding encoded masks. 59 | # frPyObjects - Convert polygon, bbox, and uncompressed RLE to encoded RLE mask. 60 | # 61 | # Usage: 62 | # Rs = encode( masks ) 63 | # masks = decode( Rs ) 64 | # R = merge( Rs, intersect=false ) 65 | # o = iou( dt, gt, iscrowd ) 66 | # a = area( Rs ) 67 | # bbs = toBbox( Rs ) 68 | # Rs = frPyObjects( [pyObjects], h, w ) 69 | # 70 | # In the API the following formats are used: 71 | # Rs - [dict] Run-length encoding of binary masks 72 | # R - dict Run-length encoding of binary mask 73 | # masks - [hxwxn] Binary mask(s) (must have type np.ndarray(dtype=uint8) in column-major order) 74 | # iscrowd - [nx1] list of np.ndarray. 1 indicates corresponding gt image has crowd region to ignore 75 | # bbs - [nx4] Bounding box(es) stored as [x y w h] 76 | # poly - Polygon stored as [[x1 y1 x2 y2...],[x1 y1 ...],...] (2D list) 77 | # dt,gt - May be either bounding boxes or encoded masks 78 | # Both poly and bbs are 0-indexed (bbox=[0 0 1 1] encloses first pixel). 79 | # 80 | # Finally, a note about the intersection over union (iou) computation. 81 | # The standard iou of a ground truth (gt) and detected (dt) object is 82 | # iou(gt,dt) = area(intersect(gt,dt)) / area(union(gt,dt)) 83 | # For "crowd" regions, we use a modified criteria. If a gt object is 84 | # marked as "iscrowd", we allow a dt to match any subregion of the gt. 85 | # Choosing gt' in the crowd gt that best matches the dt can be done using 86 | # gt'=intersect(dt,gt). Since by definition union(gt',dt)=dt, computing 87 | # iou(gt,dt,iscrowd) = iou(gt',dt) = area(intersect(gt,dt)) / area(dt) 88 | # For crowd gt regions we use this modified criteria above for the iou. 89 | 90 | iou = _mask.iou 91 | merge = _mask.merge 92 | frPyObjects = _mask.frPyObjects 93 | 94 | def encode(bimask): 95 | if len(bimask.shape) == 3: 96 | return _mask.encode(bimask) 97 | elif len(bimask.shape) == 2: 98 | h, w = bimask.shape 99 | return _mask.encode(bimask.reshape((h, w, 1), order='F'))[0] 100 | 101 | def decode(rleObjs): 102 | if type(rleObjs) == list: 103 | return _mask.decode(rleObjs) 104 | else: 105 | return _mask.decode([rleObjs])[:,:,0] 106 | 107 | def area(rleObjs): 108 | if type(rleObjs) == list: 109 | return _mask.area(rleObjs) 110 | else: 111 | return _mask.area([rleObjs])[0] 112 | 113 | def toBbox(rleObjs): 114 | if type(rleObjs) == list: 115 | return _mask.toBbox(rleObjs) 116 | else: 117 | return _mask.toBbox([rleObjs])[0] -------------------------------------------------------------------------------- /eval/CIPO_evaluation/setup.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # setup.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # See: 7 | # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/setup.py 8 | # https://github.com/cocodataset/cocoapi/blob/master/license.txt 9 | # 10 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # ============================================================================== 24 | 25 | from setuptools import setup, Extension 26 | import numpy as np 27 | 28 | # To compile and install locally run "python setup.py build_ext --inplace" 29 | # To install library to Python site-packages run "python setup.py build_ext install" 30 | 31 | ext_modules = [ 32 | Extension( 33 | 'pycocotools._mask', 34 | sources=['common/maskApi.c', 'pycocotools/_mask.pyx'], 35 | include_dirs = [np.get_include(), 'common'], 36 | extra_compile_args=['-Wno-cpp', '-Wno-unused-function', '-std=c99'], 37 | ) 38 | ] 39 | 40 | setup( 41 | name='pycocotools', 42 | packages=['pycocotools'], 43 | package_dir = {'pycocotools': 'pycocotools'}, 44 | install_requires=[ 45 | 'setuptools>=18.0', 46 | 'cython>=0.27.3', 47 | 'matplotlib>=2.1.0' 48 | ], 49 | version='2.0', 50 | ext_modules= ext_modules 51 | ) 52 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/README.md: -------------------------------------------------------------------------------- 1 | # Laneline Evaluation Kit 2 | 3 | This is the Official Evaluation Kit for OpenLane Lane Detection. 4 | 5 | ## Overview 6 | - [Requirements & Install](#a-name"requirement"a-requirements) 7 | - [2D Lane evaluation](#a-name"2dlane"a-2d-lane-evaluation) 8 | - [Acknowledgements](#a-name"ack"a-acknowledgements) 9 | 10 | ## Requirements & Install 11 | See [Requirements & Install](../README.md) 12 | 13 | ## 2D Lane evaluation 14 | 15 | ### Data Format 16 | - Prepare your result json in directory following this structure: 17 | ``` 18 | ├── result_dir 19 | | ├── validation 20 | | | ├── segment-xxx 21 | | | | ├── xxx.json 22 | | | | └── ... 23 | | | ├── segment-xxx 24 | | | | ├── xxx.json 25 | | | | └── ... 26 | | | └── ... 27 | ``` 28 | - Prepare a test list file(.txt) contains the relative image path of dataset which is consistent with the structure above: 29 | ``` 30 | validation/segment-xxx/xxx.jpg 31 | validation/segment-xxx/xxx.jpg 32 | validation/segment-xxx/xxx.jpg 33 | ... 34 | ``` 35 | - Each result json should be formatted in the following structure: 36 | ``` 37 | { 38 | "file_path": -- image path 39 | "lane_lines": [ 40 | { 41 | "category": -- lane category 42 | "uv": [2, n] -- 2D lane points in pixel coordinate 43 | }, 44 | ... (k lanes in `lane_lines` dict) 45 | ] 46 | } 47 | ``` 48 | 49 | 50 | ### Evaluation 51 | To run the evaluation for your method, please run: 52 | ``` 53 | cd lane2d 54 | ./evaluate -a $dataset_dir -d $result_dir -i $image_dir -l $test_list -w $w_lane -t $iou -o $output_file 55 | ``` 56 | 57 | The basic arguments are described below. 58 | 59 | `dataset_dir`: Data (Annotation) path of OpenLane dataset 60 | 61 | `result_dir`: Detection results path of your model. See 'Data Format' above. 62 | 63 | `image_dir`: Image path of OpenLane dataset 64 | 65 | `test_list`: Image list file(.txt) which contains relative path of every image. See 'Data Format' above. 66 | 67 | `w_lane`: Lane width, 30 in original [SCNN](https://github.com/XingangPan/SCNN) paper 68 | 69 | `iou`: IOU threshold used for evaluation, 0.3/0.5 in original [SCNN](https://github.com/XingangPan/SCNN) paper 70 | 71 | `output_file`: Evaluation outputs file path 72 | 73 | Here is an example: 74 | 75 | ``` 76 | ./evaluate \ 77 | -a ./Dataset/OpenLane/lane3d_v2.0/ \ 78 | -d ./Evaluation/PersFormer/result_dir/ \ 79 | -i ./Dataset/OpenLane/images/ \ 80 | -l ./Evaluation/PersFormer/test_list.txt \ 81 | -w 30 \ 82 | -t 0.3 \ 83 | -o ./Evaluation/PersFormer/ \ 84 | ``` 85 | 86 | We provide some json files in `example` folder, and you can run the demo evaluation: 87 | ``` 88 | cd example 89 | bash eval_demo.sh 90 | ``` 91 | 92 | ### Known Issue 93 | - libopencv not found `error while loading shared libraries: libopencv_core.so.3.4: cannot open shared object file: No such file or directory`. 94 | Please try `export LD_LIBRARY_PATH=/path/to/opencv/lib64/:$LD_LIBRARY_PATH` (for example: `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib`) and then `bash eval_demo.sh`. 95 | 96 | ### Metric formula 97 | We adopt the evaluation metric from CULane dataset in [SCNN](https://github.com/XingangPan/SCNN). 98 | 99 | 100 | ## 3D laneline evaluation 101 | 102 | ### Data Format 103 | - Prepare your result json in directory following this structure: 104 | ``` 105 | ├── result_dir 106 | | ├── validation 107 | | | ├── segment-xxx 108 | | | | ├── xxx.json 109 | | | | └── ... 110 | | | ├── segment-xxx 111 | | | | ├── xxx.json 112 | | | | └── ... 113 | | | └── ... 114 | ``` 115 | - Prepare a test list file(.txt) contains the relative image path of dataset which is consistent with the structure above: 116 | ``` 117 | validation/segment-xxx/xxx.jpg 118 | validation/segment-xxx/xxx.jpg 119 | validation/segment-xxx/xxx.jpg 120 | ... 121 | ``` 122 | - Each result json should include result following this structure: 123 | ``` 124 | { 125 | "intrinsic": [3, 3] -- camera intrinsic matrix 126 | "extrinsic": [4, 4] -- camera extrinsic matrix 127 | "file_path": -- image path 128 | "lane_lines": [ 129 | { 130 | "xyz": [3, n] -- x,y,z coordinates of sampled points in vehicle coordinate 131 | "category": -- lane category 132 | }, 133 | ... (k lanes in `lane_lines` dict) 134 | ] 135 | } 136 | ``` 137 | 138 | 139 | ### Evaluation 140 | To run the evaluation for your method, please run: 141 | ``` 142 | cd lane3d 143 | python eval_3D_lane.py --dataset_dir $dataset_dir --pred_dir $pred_dir --test_list $test_list 144 | ``` 145 | 146 | The basic arguments are described below. For more arguments, please see the script `utils.py`. 147 | 148 | `dataset_dir`: Data (Annotation) path of OpenLane dataset. 149 | 150 | `pred_dir`: Prediction results path of your model. See 'Data Format' above. 151 | 152 | `test_list`: Image list file(.txt) which contains relative path of every image. See 'Data Format' above. 153 | 154 | Here is an example: 155 | ``` 156 | python eval_3D_lane.py \ 157 | --dataset_dir=./Dataset/OpenLane/lane3d_v2.0/ \ 158 | --pred_dir=./Evaluation/PersFormer/result_dir/ \ 159 | --test_list=./Evaluation/PersFormer/test_list.txt \ 160 | ``` 161 | 162 | We provide some json files in `example` folder, and you can run the demo evaluation: 163 | ``` 164 | cd example 165 | bash eval_demo.sh 166 | ``` 167 | 168 | ### Metric formula 169 | To evaluate 3d lane predictions, we first prune gt lanes by their visibilities and only consider those lanes overlapping with the sampling range for both gts and predictions. 170 | After resampling lanes at each y step, we define a new visibility value for each point: only those within the x & y range are set for visible points. 171 | The matching cost is defined as the Euclidean distance between each gt and prediction lane, which can be formulated as follows: 172 | 173 | $$ 174 | d_{i}^{j,k}= 175 | \begin{cases} 176 | (x_{i}^{j}-x_{i}^{k})^2+(z_{i}^{j}-z_{i}^{k})^2, \quad if {\kern 3pt} both {\kern 3pt} visible\\ 177 | 0, {\kern 100pt} if {\kern 3pt} both {\kern 3pt} invisible\\ 178 | 1.5, {\kern 100pt} otherwise\\ 179 | \end{cases} 180 | $$ 181 | 182 | 183 | Then use minimum-cost flow to get the global best matching results. 184 | For each gt-pred matching pair, we also count the number of matching points between whom the Euclidean distance is under a threshold (here we set it to 1.5). With the definition above, a prediction lane can be counted as a true positive when: 185 | 186 | $$ 187 | \begin{cases} 188 | \frac {num {\kern 4pt} match {\kern 4pt} points}{num {\kern 4pt} gt {\kern 4pt} points}\geq0.75,\\ 189 | \frac {num {\kern 4pt} match {\kern 4pt} points}{num {\kern 4pt} pred {\kern 4pt} points}\geq0.75,\\ 190 | \end{cases} 191 | $$ 192 | 193 | Moreover, we divide the error metric into two parts: the close error (within the first 40 points), and the far error (the rest of 60 points). 194 | 195 | 196 | ## Acknowledgements 197 | Our 2D evaluation code builds on [SCNN](https://github.com/XingangPan/SCNN) and 3D on [Gen-LaneNet](https://github.com/yuliangguo/Pytorch_Generalized_3D_Lane_Detection). 198 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/Makefile: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # Makefile The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # Copyright (c) 2022, The OpenLane Dataset Authors. All Rights Reserved. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # ============================================================================== 20 | PROJECT_NAME:= evaluate 21 | 22 | # config ---------------------------------- 23 | 24 | INCLUDE_DIRS := include 25 | LIBRARY_DIRS := lib 26 | 27 | COMMON_FLAGS := -DCPU_ONLY 28 | CXXFLAGS := -std=c++11 -fopenmp 29 | LDFLAGS := -fopenmp -Wl,-rpath,./lib 30 | 31 | BUILD_DIR := build 32 | 33 | # make rules ------------------------------- 34 | CXX ?= g++ 35 | CC ?= gcc 36 | 37 | BUILD_DIR ?= ./build 38 | 39 | # You should change OPENCV_INCLUDE and OPENCV_LIB_PATH to your own path 40 | OPENCV_INCLUDE = /usr/include 41 | OPENCV_LIB_PATH = /usr/lib64 42 | OPENCV_LIB += opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs 43 | 44 | 45 | CXXFLAGS += $(COMMON_FLAGS) $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) -I$(OPENCV_INCLUDE) 46 | 47 | LDFLAGS += $(COMMON_FLAGS) $(foreach includedir,$(LIBRARY_DIRS),-L$(includedir)) $(foreach library,$(LIBRARIES),-l$(library)) -I$(OPENCV_INCLUDE) -L$(OPENCV_LIB_PATH) $(foreach opencv_library,$(OPENCV_LIB),-l$(opencv_library)) 48 | 49 | 50 | SRC_DIRS += $(shell find * -type d -exec bash -c "find {} -maxdepth 1 \( -name '*.cpp' -o -name '*.c' \) | grep -q ." \; -print) 51 | CXX_SRCS += $(shell find src/ -name "*.cpp") 52 | C_SRCS += $(shell find src/ -name "*.c") 53 | 54 | CXX_TARGETS:=$(patsubst %.cpp, $(BUILD_DIR)/%.o, $(CXX_SRCS)) 55 | C_TARGETS:=$(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SRCS)) 56 | 57 | CXX_BUILD_DIRS := $(sort $(BUILD_DIR) $(addprefix $(BUILD_DIR)/, $(SRC_DIRS))) 58 | C_BUILD_DIRS := $(sort $(BUILD_DIR) $(addprefix $(BUILD_DIR)/, $(SRC_DIRS))) 59 | 60 | 61 | .PHONY: all 62 | all: $(PROJECT_NAME) 63 | 64 | .PHONY: $(C_BUILD_DIRS) 65 | .PHONY: $(CXX_BUILD_DIRS) 66 | 67 | $(CXX_BUILD_DIRS): 68 | @mkdir -p $@ 69 | $(C_BUILD_DIRS): 70 | @mkdir -p $@ 71 | $(BUILD_DIR)/%.o: %.c | $(C_BUILD_DIRS) 72 | @$(CC) $(CXXFLAGS) -c -o $@ $< 73 | 74 | $(BUILD_DIR)/%.o: %.cpp | $(CXX_BUILD_DIRS) $(C_BUILD_DIRS) 75 | 76 | @$(CXX) $(CXXFLAGS) -c -o $@ $< 77 | $(PROJECT_NAME): $(CXX_TARGETS) $(C_TARGETS) 78 | @echo "CXX/LD" $@ 79 | @$(CXX) -o $@ $^ $(LDFLAGS) 80 | 81 | 82 | 83 | .PHONY: clean 84 | clean: 85 | @rm -rf $(CXX_TARGETS) 86 | @rm -rf $(PROJECT_NAME) 87 | @rm -rf $(BUILD_DIR) 88 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/annotations/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.json: -------------------------------------------------------------------------------- 1 | {"intrinsic": [[2059.0471439559833, 0.0, 935.1248081874216], [0.0, 2059.0471439559833, 635.052474560227], [0.0, 0.0, 1.0]], "extrinsic": [[0.9999944135207451, 0.0017267926275759344, -0.002862012320402869, 1.5439641908208435], [-0.0016833005658143062, 0.9998841227217824, 0.015129693588982756, -0.02326789235447021], [0.002887806521551894, -0.01512479144030509, 0.9998814436008807, 2.1153331179684765], [0.0, 0.0, 0.0, 1.0]], "file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg", "lane_lines": [{"uv": [[629.3775532516289, 650.5258390839297, 666.8276427463281, 677.4017856624785, 685.3323928495912, 688.8571071549746, 689.2976964431476, 684.0106249850725, 672.9379479810013, 659.3134323542938, 634.6439621364623, 595.1536871532295, 538.9229695140613, 441.1551721892041, 338.76458127007874], [688.320324264743, 696.2509314518558, 707.2656636561791, 719.1615744368482, 732.8198423702091, 748.2404674562617, 770.2699318649082, 792.2993962735549, 820.0565214284495, 846.8957584534761, 891.5369388693044, 951.6308355829194, 1025.4604801167893, 1152.202528857544, 1280]], "trackid": 1, "category": 20, "attribute": 0}, {"uv": [[675.8944759860336, 728.8200290943676, 779.8273811330914, 842.8830130641701, 949.3443823245494, 1015.6261163544276, 1105.0771290938649, 1243.5062373332562, 1403.7577000067722, 1920.0000000000002], [659.2414428672356, 663.1888819772606, 668.2458287022586, 675.2845969178209, 688.1890053130185, 698.7471576363617, 712.8246940674863, 738.3402288488995, 769.8533081407518, 879.4287034837973]], "trackid": 2, "category": 21, "attribute": 0}, {"uv": [[662.5124166936373, 727.4021417903238, 789.9504850536247, 863.2022881266882, 950.5023822000654, 1025.7610839874594, 1173.268139490752, 1445.8718815206462, 1598.73066692882, 1920], [666.8927155735057, 674.2513441927176, 684.2858377643702, 697.3306794075183, 719.0720821460989, 740.4790017656243, 792.6583683382175, 901.6998651501752, 966.2551071278067, 1104.2183473398325]], "trackid": 3, "category": 1, "attribute": 4}, {"uv": [[655.1485054376484, 704.0034672697094, 753.3193249681107, 804.9396619982128, 867.6214998204798, 936.2949839051694, 991.87780579563, 1050.5971587575386, 1116.0443717778467, 1251.973910161123, 1395.0063378561276], [673.9446963199468, 684.5453012457714, 697.450385503297, 714.0426366915441, 741.6963886719559, 786.8641835732953, 833.9798642035871, 894.2007692987659, 962.0046127825707, 1105.9588322102554, 1280]], "trackid": 4, "category": 1, "attribute": 3}, {"uv": [[670.3971214945303, 720.0645272594971, 789.5397674664446, 853.69349991286, 907.2042168382111, 971.3579492846264, 1015.1125686490019, 1063.5974171338503, 1105.5782005780484, 1180.6705878655578, 1242.163566431707, 1305.4303809180337, 1357.1672619232074, 1424.2773875699183, 1504.9869219379893, 1574.1665228249074, 1639.7984518714704, 1708.3867741183294, 1795.8960128470803, 1920], [661.8561924880582, 665.6995036484426, 672.203568689093, 680.7771089699503, 688.7593706107485, 699.4023861318128, 706.4977298125224, 715.0712700933798, 724.2360890142962, 740.4962516159222, 754.9825782973709, 769.764544298849, 782.7726743801499, 799.3284763018055, 819.4319500638157, 836.8746699455601, 853.4304718672156, 871.4644703890191, 893.3417800712068, 927.044662554577]], "trackid": 5, "category": 2, "attribute": 0}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/annotations/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.json: -------------------------------------------------------------------------------- 1 | {"intrinsic": [[2059.0471439559833, 0.0, 935.1248081874216], [0.0, 2059.0471439559833, 635.052474560227], [0.0, 0.0, 1.0]], "extrinsic": [[0.9999944135207451, 0.0017267926275759344, -0.002862012320402869, 1.5439641908208435], [-0.0016833005658143062, 0.9998841227217824, 0.015129693588982756, -0.02326789235447021], [0.002887806521551894, -0.01512479144030509, 0.9998814436008807, 2.1153331179684765], [0.0, 0.0, 0.0, 1.0]], "file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg", "lane_lines": [{"uv": [[636.2649757645892, 649.4425171236642, 662.6812601175922, 673.4593455557804, 682.7624634231089, 689.3024713508956, 692.5783073975898, 693.9307951707783, 691.5785217746995, 686.9120864686804, 677.0581310080617, 663.1345726856557, 636.9247874680144, 597.4345124847816, 541.2037948456134, 443.435997520756, 341.0454066016305], [699.8859707611665, 703.7642006282645, 709.9479833156524, 716.2369687887698, 726.1950662938823, 737.160022846468, 748.9563823236607, 763.7563712576577, 779.579474145746, 797.2644854900018, 823.1597021887288, 850.6195753658111, 891.5369388693044, 951.6308355829194, 1025.4604801167893, 1152.202528857544, 1280]], "trackid": 1, "category": 20, "attribute": 0}, {"uv": [[673.9270612919053, 728.8200290943676, 779.1715762350486, 842.8830130641701, 948.6885774265066, 1015.6261163544276, 1104.7492266448435, 1243.1783348842348, 1403.7577000067722, 1920.0000000000002], [666.1273942966849, 670.0748334067099, 674.8038776826864, 681.186841000206, 693.7633469463822, 703.6656943716827, 717.7432308028073, 743.2587655842204, 774.7718448760727, 884.0193377700969]], "trackid": 2, "category": 21, "attribute": 0}, {"uv": [[657.3321292744185, 696.406947164846, 741.3059656637993, 774.9434573818633, 816.4712499739343, 877.3768479991593, 934.377257056738, 983.6437671350227, 1048.06063978441, 1112.8707833243277, 1244.9779048252628, 1386.009294184779], [680.5699551191183, 688.6466519309723, 699.974293617267, 710.2567745205891, 724.5794860935017, 751.7920211278359, 787.4951606017878, 830.188395009274, 894.1852954547518, 963.2787517433511, 1107.870040651426, 1280]], "trackid": 4, "category": 1, "attribute": 3}, {"uv": [[662.5124166936373, 727.4021417903238, 789.9504850536247, 863.2022881266882, 950.5023822000654, 1025.7610839874594, 1173.268139490752, 1445.8718815206462, 1598.73066692882, 1920], [671.6327540863185, 678.9913827055304, 689.025876277183, 702.0707179203312, 723.8121206589117, 745.2190402784371, 797.3984068510304, 906.4399036629881, 970.9951456406195, 1108.9583858526464]], "trackid": 3, "category": 1, "attribute": 4}, {"uv": [[672.9030551465481, 753.9082288346486, 821.0183544813597, 878.6680218871246, 932.4743781325052, 997.2193892189797, 1067.2859080659864, 1135.8742303128452, 1214.8099287607388, 1290.7892340083367, 1347.2563441339835, 1425.3051246217883, 1497.1454793889723, 1548.882360394146, 1614.2186501206797, 1687.7910167894086, 1754.3900015609822, 1822.6133518147892, 1920], [668.5326177108808, 675.9236007116199, 683.314583712359, 691.2968453531572, 698.9834676739258, 709.6264831949901, 722.0433346362319, 736.2340219976509, 753.9723811994247, 771.7107404011986, 785.014509802529, 805.1179835645393, 822.2650641262541, 836.1601121676435, 852.4202747692696, 871.228184413327, 887.471839235662, 906.1520422813472, 931.3297072559666]], "trackid": 5, "category": 2, "attribute": 0}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/eval_demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ../evaluate \ 3 | -a ./annotations/ \ 4 | -d ./results/ \ 5 | -i ./images/ \ 6 | -l ./test_list.txt \ 7 | -o ./ \ 8 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/images/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/eval/LANE_evaluation/lane2d/example/images/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/images/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/eval/LANE_evaluation/lane2d/example/images/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/results/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.json: -------------------------------------------------------------------------------- 1 | {"file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg", "lane_lines": [{"category": 20, "uv": [[649.5150375366211, 677.4679756164551, 686.7765426635742, 688.9757537841797, 689.4354629516602, 686.996955871582, 682.3802375793457, 675.1566123962402, 664.797248840332, 654.0862655639648, 641.3564872741699, 627.7820205688477, 614.9929046630859, 601.9543647766113, 587.9108619689941, 573.695011138916, 560.0691032409668, 546.3521575927734, 532.2887420654297, 518.7030029296875, 503.7052917480469, 489.5920944213867, 474.9897766113281, 462.74980545043945, 448.1858825683594, 434.66883659362793, 421.27976417541504, 408.7433624267578, 395.45897483825684, 382.7665901184082, 370.3575611114502, 357.5638675689697, 331.21633529663086], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062, 1117.7465057373047, 1135.7746887207031, 1153.8027954101562, 1171.8309783935547, 1189.8591613769531, 1207.8873443603516, 1225.91552734375, 1243.9436340332031, 1261.9718170166016, 1280.0]]}, {"category": 2, "uv": [[823.9638519287109, 943.2839584350586, 1054.9059677124023, 1148.8975524902344, 1233.328628540039, 1313.3982467651367, 1390.931053161621, 1466.7416381835938, 1540.8366394042969, 1614.1133880615234, 1685.823097229004, 1757.8696060180664, 1827.2962188720703, 1894.6575164794922], [685.0704193115234, 703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125]]}, {"category": 1, "uv": [[776.5076065063477, 867.1622657775879, 946.7735481262207, 1008.6114120483398, 1063.7089920043945, 1115.741958618164, 1166.0497283935547, 1215.099105834961, 1262.8218841552734, 1310.0634384155273, 1355.0712203979492, 1399.9652481079102, 1442.7034378051758, 1484.684715270996, 1528.4258651733398, 1572.063217163086, 1617.8375244140625, 1664.2070388793945, 1709.4953155517578, 1753.7429809570312, 1796.6790390014648, 1836.7776489257812, 1872.9243850708008, 1904.519920349121], [685.0704193115234, 703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062]]}, {"category": 2, "uv": [[861.331901550293, 975.0991058349609, 1074.294319152832, 1157.552833557129, 1234.1688537597656, 1310.7149505615234, 1385.5570220947266, 1459.9742889404297, 1534.3461227416992, 1604.7631072998047, 1672.7838134765625, 1738.5697174072266, 1802.109146118164, 1866.0289764404297], [685.0704193115234, 703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125]]}, {"category": 1, "uv": [[705.1395034790039, 771.4144706726074, 828.160400390625, 867.5958824157715, 899.8411560058594, 927.5217819213867, 951.1556053161621, 971.8164825439453, 991.3253402709961, 1010.4306793212891, 1027.766990661621, 1044.155158996582, 1060.2178573608398, 1076.2408447265625, 1092.0503997802734, 1107.824935913086, 1123.6912536621094, 1140.2897644042969, 1156.2571334838867, 1172.4843978881836, 1189.6333694458008, 1205.9608840942383, 1222.356834411621, 1238.0665969848633, 1253.2529067993164, 1267.9535293579102, 1283.3173370361328, 1299.6447372436523, 1316.067008972168, 1332.3284912109375, 1348.9073181152344, 1368.794288635254, 1391.6582107543945, 1534.3207168579102], [685.0704193115234, 703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062, 1117.7465057373047, 1135.7746887207031, 1153.8027954101562, 1171.8309783935547, 1189.8591613769531, 1207.8873443603516, 1225.91552734375, 1243.9436340332031, 1261.9718170166016, 1280.0]]}, {"category": 20, "uv": [[1011.6420364379883, 1116.8982696533203, 1219.9316024780273, 1317.1085357666016, 1407.985954284668, 1493.6479568481445, 1577.552375793457, 1658.5858154296875, 1738.5374450683594, 1814.9774551391602, 1883.6327362060547], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156]]}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/results/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.json: -------------------------------------------------------------------------------- 1 | {"file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg", "lane_lines": [{"category": 20, "uv": [[638.192138671875, 670.023250579834, 683.6001205444336, 688.4648323059082, 690.97412109375, 690.142650604248, 686.495189666748, 679.3702125549316, 669.2071151733398, 658.351936340332, 645.8142471313477, 632.1303176879883, 619.1415596008301, 605.6027984619141, 591.2067031860352, 576.9857597351074, 563.2284164428711, 549.2171859741211, 535.0798416137695, 521.3643836975098, 506.71680450439453, 492.9422950744629, 479.06776428222656, 467.5276851654053, 453.6822509765625, 440.84315299987793, 428.1983757019043, 416.10042572021484, 403.1528091430664, 390.56556701660156, 377.90319442749023, 365.3635883331299, 331.83385848999023], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062, 1117.7465057373047, 1135.7746887207031, 1153.8027954101562, 1171.8309783935547, 1189.8591613769531, 1207.8873443603516, 1225.91552734375, 1243.9436340332031, 1261.9718170166016, 1280.0]]}, {"category": 2, "uv": [[907.9058647155762, 1019.1044998168945, 1117.9619979858398, 1206.8597030639648, 1288.982276916504, 1367.8483200073242, 1444.4192504882812, 1518.6922073364258, 1592.3493576049805, 1665.2664184570312, 1738.267707824707, 1808.9885330200195, 1877.5318908691406], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125]]}, {"category": 1, "uv": [[829.3108177185059, 912.6371383666992, 981.0575866699219, 1040.3631591796875, 1093.9181900024414, 1145.0492477416992, 1195.096206665039, 1243.612403869629, 1291.7203903198242, 1337.2547149658203, 1382.1765518188477, 1425.505256652832, 1468.509178161621, 1512.9190063476562, 1556.9415664672852, 1602.3858261108398, 1648.1391906738281, 1693.0517578125, 1737.0974349975586, 1779.5901489257812, 1818.965721130371, 1854.1171646118164, 1884.6264266967773, 1908.0895614624023], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062, 1117.7465057373047]]}, {"category": 1, "uv": [[676.4473342895508, 745.4637336730957, 807.4069976806641, 854.2170524597168, 890.4024124145508, 919.8200798034668, 944.0153503417969, 965.6332397460938, 986.1238861083984, 1006.1759948730469, 1023.966178894043, 1040.891990661621, 1057.1896362304688, 1073.5981750488281, 1089.7880172729492, 1105.9917068481445, 1122.238540649414, 1139.1968536376953, 1155.5403900146484, 1172.1506881713867, 1189.0874862670898, 1205.6244277954102, 1222.5850296020508, 1239.649543762207, 1256.8004608154297, 1274.5479583740234, 1292.4985885620117, 1310.1318740844727, 1327.4363708496094, 1344.5538711547852, 1361.2578964233398, 1379.7700881958008, 1399.0727233886719, 1533.7875366210938], [685.0704193115234, 703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109, 955.4929351806641, 973.5211181640625, 991.5493011474609, 1009.5774841308594, 1027.6056671142578, 1045.6338500976562, 1063.6620330810547, 1081.6902160644531, 1099.7183227539062, 1117.7465057373047, 1135.7746887207031, 1153.8027954101562, 1171.8309783935547, 1189.8591613769531, 1207.8873443603516, 1225.91552734375, 1243.9436340332031, 1261.9718170166016, 1280.0]]}, {"category": 2, "uv": [[932.1015930175781, 1036.8414688110352, 1128.3338928222656, 1211.5748977661133, 1291.7161560058594, 1368.1230926513672, 1444.0731811523438, 1518.5905838012695, 1587.012062072754, 1651.1160278320312, 1712.3651504516602, 1771.611671447754, 1832.1437072753906, 1891.7112350463867], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156, 901.4084625244141, 919.4366455078125, 937.4648284912109]]}, {"category": 20, "uv": [[977.2827529907227, 1076.916847229004, 1182.2415161132812, 1285.3396224975586, 1382.4674606323242, 1471.9284439086914, 1557.0653915405273, 1638.4577178955078, 1718.6248397827148, 1796.609001159668, 1867.1097564697266], [703.0986022949219, 721.126708984375, 739.1548919677734, 757.1830749511719, 775.2112579345703, 793.2394409179688, 811.2675476074219, 829.2957305908203, 847.3239135742188, 865.3520965576172, 883.3802795410156]]}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/example/test_list.txt: -------------------------------------------------------------------------------- 1 | segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg 2 | segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/CJsonObject.hpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | CJsonObject.hpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/Bwar/CJsonObject/blob/master/CJsonObject.hpp 8 | https://github.com/Bwar/CJsonObject/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef CJSONOBJECT_HPP_ 25 | #define CJSONOBJECT_HPP_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #if __cplusplus < 201101L 36 | #include 37 | #else 38 | #include 39 | #endif 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | #include "cJSON.h" 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | 49 | namespace neb 50 | { 51 | 52 | class CJsonObject 53 | { 54 | public: // method of ordinary json object or json array 55 | CJsonObject(); 56 | CJsonObject(const std::string& strJson); 57 | CJsonObject(const CJsonObject* pJsonObject); 58 | CJsonObject(const CJsonObject& oJsonObject); 59 | #if __cplusplus >= 201101L 60 | CJsonObject(CJsonObject&& oJsonObject); 61 | #endif 62 | virtual ~CJsonObject(); 63 | 64 | CJsonObject& operator=(const CJsonObject& oJsonObject); 65 | #if __cplusplus >= 201101L 66 | CJsonObject& operator=(CJsonObject&& oJsonObject); 67 | #endif 68 | bool operator==(const CJsonObject& oJsonObject) const; 69 | bool Parse(const std::string& strJson); 70 | void Clear(); 71 | bool IsEmpty() const; 72 | bool IsArray() const; 73 | std::string ToString() const; 74 | std::string ToFormattedString() const; 75 | const std::string& GetErrMsg() const 76 | { 77 | return(m_strErrMsg); 78 | } 79 | 80 | public: // method of ordinary json object 81 | bool AddEmptySubObject(const std::string& strKey); 82 | bool AddEmptySubArray(const std::string& strKey); 83 | bool GetKey(std::string& strKey); 84 | void ResetTraversing(); 85 | CJsonObject& operator[](const std::string& strKey); 86 | std::string operator()(const std::string& strKey) const; 87 | bool KeyExist(const std::string& strKey) const; 88 | bool Get(const std::string& strKey, CJsonObject& oJsonObject) const; 89 | bool Get(const std::string& strKey, std::string& strValue) const; 90 | bool Get(const std::string& strKey, int32& iValue) const; 91 | bool Get(const std::string& strKey, uint32& uiValue) const; 92 | bool Get(const std::string& strKey, int64& llValue) const; 93 | bool Get(const std::string& strKey, uint64& ullValue) const; 94 | bool Get(const std::string& strKey, bool& bValue) const; 95 | bool Get(const std::string& strKey, float& fValue) const; 96 | bool Get(const std::string& strKey, double& dValue) const; 97 | int GetValueType(const std::string& strKey) const; 98 | bool IsNull(const std::string& strKey) const; 99 | bool Add(const std::string& strKey, const CJsonObject& oJsonObject); 100 | #if __cplusplus < 201101L 101 | bool AddWithMove(const std::string& strKey, CJsonObject& oJsonObject); 102 | #else 103 | bool Add(const std::string& strKey, CJsonObject&& oJsonObject); 104 | #endif 105 | bool Add(const std::string& strKey, const std::string& strValue); 106 | bool Add(const std::string& strKey, int32 iValue); 107 | bool Add(const std::string& strKey, uint32 uiValue); 108 | bool Add(const std::string& strKey, int64 llValue); 109 | bool Add(const std::string& strKey, uint64 ullValue); 110 | bool Add(const std::string& strKey, bool bValue, bool bValueAgain); 111 | bool Add(const std::string& strKey, float fValue); 112 | bool Add(const std::string& strKey, double dValue); 113 | bool AddNull(const std::string& strKey); // add null like this: "key":null 114 | bool Delete(const std::string& strKey); 115 | bool Replace(const std::string& strKey, const CJsonObject& oJsonObject); 116 | #if __cplusplus < 201101L 117 | bool ReplaceWithMove(const std::string& strKey, CJsonObject& oJsonObject); 118 | #else 119 | bool Replace(const std::string& strKey, CJsonObject&& oJsonObject); 120 | #endif 121 | bool Replace(const std::string& strKey, const std::string& strValue); 122 | bool Replace(const std::string& strKey, int32 iValue); 123 | bool Replace(const std::string& strKey, uint32 uiValue); 124 | bool Replace(const std::string& strKey, int64 llValue); 125 | bool Replace(const std::string& strKey, uint64 ullValue); 126 | bool Replace(const std::string& strKey, bool bValue, bool bValueAgain); 127 | bool Replace(const std::string& strKey, float fValue); 128 | bool Replace(const std::string& strKey, double dValue); 129 | bool ReplaceWithNull(const std::string& strKey); // replace value with null 130 | #if __cplusplus < 201101L 131 | bool ReplaceAdd(const std::string& strKey, const CJsonObject& oJsonObject); 132 | bool ReplaceAdd(const std::string& strKey, const std::string& strValue); 133 | template 134 | bool ReplaceAdd(const std::string& strKey, T value) 135 | { 136 | if (KeyExist(strKey)) 137 | { 138 | return(Replace(strKey, value)); 139 | } 140 | return(Add(strKey, value)); 141 | } 142 | #else 143 | template 144 | bool ReplaceAdd(const std::string& strKey, T&& value) 145 | { 146 | if (KeyExist(strKey)) 147 | { 148 | return(Replace(strKey, std::forward(value))); 149 | } 150 | return(Add(strKey, std::forward(value))); 151 | } 152 | #endif 153 | 154 | public: // method of json array 155 | int GetArraySize() const; 156 | CJsonObject& operator[](unsigned int uiWhich); 157 | std::string operator()(unsigned int uiWhich) const; 158 | bool Get(int iWhich, CJsonObject& oJsonObject) const; 159 | bool Get(int iWhich, std::string& strValue) const; 160 | bool Get(int iWhich, int32& iValue) const; 161 | bool Get(int iWhich, uint32& uiValue) const; 162 | bool Get(int iWhich, int64& llValue) const; 163 | bool Get(int iWhich, uint64& ullValue) const; 164 | bool Get(int iWhich, bool& bValue) const; 165 | bool Get(int iWhich, float& fValue) const; 166 | bool Get(int iWhich, double& dValue) const; 167 | int GetValueType(int iWhich) const; 168 | bool IsNull(int iWhich) const; 169 | bool Add(const CJsonObject& oJsonObject); 170 | #if __cplusplus < 201101L 171 | bool AddWithMove(CJsonObject& oJsonObject); 172 | #else 173 | bool Add(CJsonObject&& oJsonObject); 174 | #endif 175 | bool Add(const std::string& strValue); 176 | bool Add(int32 iValue); 177 | bool Add(uint32 uiValue); 178 | bool Add(int64 llValue); 179 | bool Add(uint64 ullValue); 180 | bool Add(int iAnywhere, bool bValue); 181 | bool Add(float fValue); 182 | bool Add(double dValue); 183 | bool AddNull(); // add a null value 184 | bool AddAsFirst(const CJsonObject& oJsonObject); 185 | #if __cplusplus < 201101L 186 | bool AddAsFirstWithMove(CJsonObject& oJsonObject); 187 | #else 188 | bool AddAsFirst(CJsonObject&& oJsonObject); 189 | #endif 190 | bool AddAsFirst(const std::string& strValue); 191 | bool AddAsFirst(int32 iValue); 192 | bool AddAsFirst(uint32 uiValue); 193 | bool AddAsFirst(int64 llValue); 194 | bool AddAsFirst(uint64 ullValue); 195 | bool AddAsFirst(int iAnywhere, bool bValue); 196 | bool AddAsFirst(float fValue); 197 | bool AddAsFirst(double dValue); 198 | bool AddNullAsFirst(); // add a null value 199 | bool Delete(int iWhich); 200 | bool Replace(int iWhich, const CJsonObject& oJsonObject); 201 | #if __cplusplus < 201101L 202 | bool ReplaceWithMove(int iWhich, CJsonObject& oJsonObject); 203 | #else 204 | bool Replace(int iWhich, CJsonObject&& oJsonObject); 205 | #endif 206 | bool Replace(int iWhich, const std::string& strValue); 207 | bool Replace(int iWhich, int32 iValue); 208 | bool Replace(int iWhich, uint32 uiValue); 209 | bool Replace(int iWhich, int64 llValue); 210 | bool Replace(int iWhich, uint64 ullValue); 211 | bool Replace(int iWhich, bool bValue, bool bValueAgain); 212 | bool Replace(int iWhich, float fValue); 213 | bool Replace(int iWhich, double dValue); 214 | bool ReplaceWithNull(int iWhich); // replace with a null value 215 | 216 | private: 217 | CJsonObject(cJSON* pJsonData); 218 | 219 | private: 220 | cJSON* m_pJsonData; 221 | cJSON* m_pExternJsonDataRef; 222 | cJSON* m_pKeyTravers; 223 | const char* mc_pError; 224 | std::string m_strErrMsg; 225 | #if __cplusplus < 201101L 226 | std::map m_mapJsonArrayRef; 227 | std::map::iterator m_array_iter; 228 | std::map m_mapJsonObjectRef; 229 | std::map::iterator m_object_iter; 230 | #else 231 | std::unordered_map m_mapJsonArrayRef; 232 | std::unordered_map::iterator m_object_iter; 233 | std::unordered_map m_mapJsonObjectRef; 234 | std::unordered_map::iterator m_array_iter; 235 | #endif 236 | }; 237 | 238 | } 239 | 240 | #endif /* CJSONHELPER_HPP_ */ 241 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/cJSON.h: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | cJSON.h The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/Bwar/CJsonObject/blob/master/cJSON.h 8 | https://github.com/Bwar/CJsonObject/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef cJSON__h 25 | #define cJSON__h 26 | 27 | #include 28 | 29 | typedef int32_t int32; 30 | typedef uint32_t uint32; 31 | typedef int64_t int64; 32 | typedef uint64_t uint64; 33 | 34 | 35 | #ifdef __cplusplus 36 | extern "C" 37 | { 38 | #endif 39 | 40 | /* cJSON Types: */ 41 | #define cJSON_False 0 42 | #define cJSON_True 1 43 | #define cJSON_NULL 2 44 | #define cJSON_Int 3 45 | #define cJSON_Double 4 46 | #define cJSON_String 5 47 | #define cJSON_Array 6 48 | #define cJSON_Object 7 49 | 50 | #define cJSON_IsReference 256 51 | 52 | /* The cJSON structure: */ 53 | typedef struct cJSON 54 | { 55 | struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 56 | struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 57 | 58 | int type; /* The type of the item, as above. */ 59 | 60 | char *valuestring; /* The item's string, if type==cJSON_String */ 61 | int64 valueint; /* The item's number, if type==cJSON_Number */ 62 | double valuedouble; /* The item's number, if type==cJSON_Number */ 63 | int sign; /* sign of valueint, 1(unsigned), -1(signed) */ 64 | 65 | char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 66 | } cJSON; 67 | 68 | typedef struct cJSON_Hooks 69 | { 70 | void *(*malloc_fn)(size_t sz); 71 | void (*free_fn)(void *ptr); 72 | } cJSON_Hooks; 73 | 74 | /* Supply malloc, realloc and free functions to cJSON */ 75 | extern void cJSON_InitHooks(cJSON_Hooks* hooks); 76 | 77 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ 78 | extern cJSON *cJSON_Parse(const char *value, const char **ep); 79 | /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ 80 | extern char *cJSON_Print(cJSON *item); 81 | /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ 82 | extern char *cJSON_PrintUnformatted(cJSON *item); 83 | /* Delete a cJSON entity and all subentities. */ 84 | extern void cJSON_Delete(cJSON *c); 85 | 86 | /* Returns the number of items in an array (or object). */ 87 | extern int cJSON_GetArraySize(cJSON *array); 88 | /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ 89 | extern cJSON *cJSON_GetArrayItem(cJSON *array, int item); 90 | /* Get item "string" from object. Case insensitive. */ 91 | extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string); 92 | 93 | /* remove gloal variable for thread safe. --by Bwar on 2020-11-15 */ 94 | /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ 95 | /* extern const char *cJSON_GetErrorPtr(); */ 96 | 97 | /* These calls create a cJSON item of the appropriate type. */ 98 | extern cJSON *cJSON_CreateNull(); 99 | extern cJSON *cJSON_CreateTrue(); 100 | extern cJSON *cJSON_CreateFalse(); 101 | extern cJSON *cJSON_CreateBool(int b); 102 | extern cJSON *cJSON_CreateDouble(double num, int sign); 103 | extern cJSON *cJSON_CreateInt(uint64 num, int sign); 104 | extern cJSON *cJSON_CreateString(const char *string); 105 | extern cJSON *cJSON_CreateArray(); 106 | extern cJSON *cJSON_CreateObject(); 107 | 108 | /* These utilities create an Array of count items. */ 109 | extern cJSON *cJSON_CreateIntArray(int *numbers, int sign, int count); 110 | extern cJSON *cJSON_CreateFloatArray(float *numbers, int count); 111 | extern cJSON *cJSON_CreateDoubleArray(double *numbers, int count); 112 | extern cJSON *cJSON_CreateStringArray(const char **strings, int count); 113 | 114 | /* Append item to the specified array/object. */ 115 | extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); 116 | extern void cJSON_AddItemToArrayHead(cJSON *array, cJSON *item); /* add by Bwar on 2015-01-28 */ 117 | extern void cJSON_AddItemToObject(cJSON *object, const char *string, 118 | cJSON *item); 119 | /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ 120 | extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); 121 | extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, 122 | cJSON *item); 123 | 124 | /* Remove/Detatch items from Arrays/Objects. */ 125 | extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which); 126 | extern void cJSON_DeleteItemFromArray(cJSON *array, int which); 127 | extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string); 128 | extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string); 129 | 130 | /* Update array items. */ 131 | extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); 132 | extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, 133 | cJSON *newitem); 134 | 135 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 136 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 137 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 138 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 139 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 140 | 141 | 142 | #ifdef __cplusplus 143 | } 144 | #endif 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/counter.hpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | counter.hpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/include/counter.hpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef COUNTER_HPP 25 | #define COUNTER_HPP 26 | 27 | #include "lane_compare.hpp" 28 | #include "hungarianGraph.hpp" 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | using namespace std; 36 | using namespace cv; 37 | 38 | // before coming to use functions of this class, the lanes should resize to im_width and im_height using resize_lane() in lane_compare.hpp 39 | class Counter 40 | { 41 | public: 42 | Counter(int _im_width, int _im_height, double _iou_threshold = 0.4, int _lane_width = 10) : tp(0), fp(0), fn(0) 43 | { 44 | im_width = _im_width; 45 | im_height = _im_height; 46 | sim_threshold = _iou_threshold; 47 | lane_compare = new LaneCompare(_im_width, _im_height, _lane_width, LaneCompare::IOU); 48 | }; 49 | double get_precision(void); 50 | double get_recall(void); 51 | long getTP(void); 52 | long getFP(void); 53 | long getFN(void); 54 | void setTP(long); 55 | void setFP(long); 56 | void setFN(long); 57 | // direct add tp, fp, tn and fn 58 | // first match with hungarian 59 | tuple, long, long, long, long> count_im_pair(const vector> &anno_lanes, const vector> &detect_lanes, vector &anno_lanes_flag, vector &detect_lanes_flag, bool category_flag); 60 | void makeMatch(const vector> &similarity, vector &match1, vector &match2); 61 | 62 | private: 63 | double sim_threshold; 64 | int im_width; 65 | int im_height; 66 | long tp; 67 | long fp; 68 | long fn; 69 | LaneCompare *lane_compare; 70 | }; 71 | #endif 72 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/hungarianGraph.hpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | hungarianGraph.hpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/include/hungarianGraph.hpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef HUNGARIAN_GRAPH_HPP 25 | #define HUNGARIAN_GRAPH_HPP 26 | #include 27 | using namespace std; 28 | 29 | struct pipartiteGraph { 30 | vector > mat; 31 | vector leftUsed, rightUsed; 32 | vector leftWeight, rightWeight; 33 | vectorrightMatch, leftMatch; 34 | int leftNum, rightNum; 35 | bool matchDfs(int u) { 36 | leftUsed[u] = true; 37 | for (int v = 0; v < rightNum; v++) { 38 | if (!rightUsed[v] && fabs(leftWeight[u] + rightWeight[v] - mat[u][v]) < 1e-2) { 39 | rightUsed[v] = true; 40 | if (rightMatch[v] == -1 || matchDfs(rightMatch[v])) { 41 | rightMatch[v] = u; 42 | leftMatch[u] = v; 43 | return true; 44 | } 45 | } 46 | } 47 | return false; 48 | } 49 | void resize(int leftNum, int rightNum) { 50 | this->leftNum = leftNum; 51 | this->rightNum = rightNum; 52 | leftMatch.resize(leftNum); 53 | rightMatch.resize(rightNum); 54 | leftUsed.resize(leftNum); 55 | rightUsed.resize(rightNum); 56 | leftWeight.resize(leftNum); 57 | rightWeight.resize(rightNum); 58 | mat.resize(leftNum); 59 | for (int i = 0; i < leftNum; i++) mat[i].resize(rightNum); 60 | } 61 | void match() { 62 | for (int i = 0; i < leftNum; i++) leftMatch[i] = -1; 63 | for (int i = 0; i < rightNum; i++) rightMatch[i] = -1; 64 | for (int i = 0; i < rightNum; i++) rightWeight[i] = 0; 65 | for (int i = 0; i < leftNum; i++) { 66 | leftWeight[i] = -1e5; 67 | for (int j = 0; j < rightNum; j++) { 68 | if (leftWeight[i] < mat[i][j]) leftWeight[i] = mat[i][j]; 69 | } 70 | } 71 | 72 | for (int u = 0; u < leftNum; u++) { 73 | while (1) { 74 | for (int i = 0; i < leftNum; i++) leftUsed[i] = false; 75 | for (int i = 0; i < rightNum; i++) rightUsed[i] = false; 76 | if (matchDfs(u)) break; 77 | double d = 1e10; 78 | for (int i = 0; i < leftNum; i++) { 79 | if (leftUsed[i] ) { 80 | for (int j = 0; j < rightNum; j++) { 81 | if (!rightUsed[j]) d = min(d, leftWeight[i] + rightWeight[j] - mat[i][j]); 82 | } 83 | } 84 | } 85 | if (d == 1e10) return ; 86 | for (int i = 0; i < leftNum; i++) if (leftUsed[i]) leftWeight[i] -= d; 87 | for (int i = 0; i < rightNum; i++) if (rightUsed[i]) rightWeight[i] += d; 88 | } 89 | } 90 | } 91 | }; 92 | 93 | 94 | #endif // HUNGARIAN_GRAPH_HPP 95 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/lane_compare.hpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | lane_compare.hpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/include/lane_compare.hpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef LANE_COMPARE_HPP 25 | #define LANE_COMPARE_HPP 26 | 27 | #include "spline.hpp" 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace std; 34 | using namespace cv; 35 | 36 | class LaneCompare{ 37 | public: 38 | enum CompareMode{ 39 | IOU, 40 | Caltech 41 | }; 42 | 43 | LaneCompare(int _im_width, int _im_height, int _lane_width = 10, CompareMode _compare_mode = IOU){ 44 | im_width = _im_width; 45 | im_height = _im_height; 46 | compare_mode = _compare_mode; 47 | lane_width = _lane_width; 48 | } 49 | 50 | double get_lane_similarity(const vector &lane1, const vector &lane2); 51 | void resize_lane(vector &curr_lane, int curr_width, int curr_height); 52 | private: 53 | CompareMode compare_mode; 54 | int im_width; 55 | int im_height; 56 | int lane_width; 57 | Spline splineSolver; 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/include/spline.hpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | spline.hpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/include/spline.hpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #ifndef SPLINE_HPP 25 | #define SPLINE_HPP 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | using namespace cv; 32 | using namespace std; 33 | 34 | struct Func { 35 | double a_x; 36 | double b_x; 37 | double c_x; 38 | double d_x; 39 | double a_y; 40 | double b_y; 41 | double c_y; 42 | double d_y; 43 | double h; 44 | }; 45 | class Spline { 46 | public: 47 | vector splineInterpTimes(const vector &tmp_line, int times); 48 | vector splineInterpStep(vector tmp_line, double step); 49 | vector cal_fun(const vector &point_v); 50 | }; 51 | #endif 52 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/src/counter.cpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | counter.cpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/src/counter.cpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #include "counter.hpp" 25 | 26 | double Counter::get_precision(void) 27 | { 28 | cerr<<"tp: "<, long, long, long, long> Counter::count_im_pair(const vector > &anno_lanes, const vector > &detect_lanes, vector &anno_lanes_flag, vector &detect_lanes_flag,bool category_flag) 78 | { 79 | vector anno_match(anno_lanes.size(), -1); 80 | vector detect_match; 81 | if(anno_lanes.empty()) 82 | { 83 | return make_tuple(anno_match, 0, detect_lanes.size(), 0, 0); 84 | } 85 | 86 | if(detect_lanes.empty()) 87 | { 88 | return make_tuple(anno_match, 0, 0, 0, anno_lanes.size()); 89 | } 90 | 91 | // hungarian match first 92 | 93 | // first calc similarity matrix 94 | vector > similarity(anno_lanes.size(), vector(detect_lanes.size(), 0)); 95 | for(int i=0; i &curr_anno_lane = anno_lanes[i]; 98 | for(int j=0; j &curr_detect_lane = detect_lanes[j]; 101 | if (category_flag) 102 | { 103 | similarity[i][j] = lane_compare->get_lane_similarity(curr_anno_lane, curr_detect_lane); 104 | } 105 | else 106 | { 107 | 108 | if (((anno_lanes_flag[i] - detect_lanes_flag[j])< 1e-4 ) & ((anno_lanes_flag[i] - detect_lanes_flag[j]) > -1e-4)) 109 | { 110 | similarity[i][j] = lane_compare->get_lane_similarity(curr_anno_lane, curr_detect_lane); 111 | } 112 | else 113 | { 114 | similarity[i][j] = 0; 115 | } 116 | } 117 | } 118 | } 119 | 120 | makeMatch(similarity, anno_match, detect_match); 121 | 122 | int curr_tp = 0; 123 | // count and add 124 | for(int i=0; i=0 && similarity[i][anno_match[i]] > sim_threshold) 127 | { 128 | curr_tp++; 129 | } 130 | else 131 | { 132 | anno_match[i] = -1; 133 | } 134 | } 135 | int curr_fn = anno_lanes.size() - curr_tp; 136 | int curr_fp = detect_lanes.size() - curr_tp; 137 | return make_tuple(anno_match, curr_tp, curr_fp, 0, curr_fn); 138 | } 139 | 140 | 141 | void Counter::makeMatch(const vector > &similarity, vector &match1, vector &match2) { 142 | int m = similarity.size(); 143 | int n = similarity[0].size(); 144 | pipartiteGraph gra; 145 | bool have_exchange = false; 146 | if (m > n) { 147 | have_exchange = true; 148 | swap(m, n); 149 | } 150 | gra.resize(m, n); 151 | for (int i = 0; i < gra.leftNum; i++) { 152 | for (int j = 0; j < gra.rightNum; j++) { 153 | if(have_exchange) 154 | gra.mat[i][j] = similarity[j][i]; 155 | else 156 | gra.mat[i][j] = similarity[i][j]; 157 | } 158 | } 159 | gra.match(); 160 | match1 = gra.leftMatch; 161 | match2 = gra.rightMatch; 162 | if (have_exchange) swap(match1, match2); 163 | } 164 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/src/evaluate.cpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | evaluate.cpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/src/evaluate.cpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #include "counter.hpp" 25 | #include "spline.hpp" 26 | #include "CJsonObject.hpp" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #ifdef WIN32 37 | #include 38 | #include 39 | #else 40 | #include 41 | #include 42 | #endif 43 | #include 44 | #include 45 | #define MAX_PATH_LEN 256 46 | 47 | #ifdef WIN32 48 | #define ACCESS(fileName,accessMode) _access(fileName,accessMode) 49 | #define MKDIR(path) _mkdir(path) 50 | #else 51 | #define ACCESS(fileName,accessMode) access(fileName,accessMode) 52 | #define MKDIR(path) mkdir(path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) 53 | #endif 54 | using namespace std; 55 | using namespace cv; 56 | 57 | bool lessmark(const Point2f& stItem1, const Point2f& stItem2) 58 | { 59 | return stItem1.y < stItem2.y; 60 | } 61 | 62 | void help(void) 63 | { 64 | cout << "./evaluate [OPTIONS]" << endl; 65 | cout << "-h : print usage help" << endl; 66 | cout << "-a : directory for annotation files (default: /data/driving/eval_data/anno_label/)" << endl; 67 | cout << "-d : directory for detection files (default: /data/driving/eval_data/predict_label/)" << endl; 68 | cout << "-i : directory for image files (default: /data/driving/eval_data/img/)" << endl; 69 | cout << "-l : list of images used for evaluation (default: /data/driving/eval_data/img/all.txt)" << endl; 70 | cout << "-w : width of the lanes (default: 10)" << endl; 71 | cout << "-t : threshold of iou (default: 0.4)" << endl; 72 | cout << "-c : cols (max image width) (default: 1920)" << endl; 73 | cout << "-r : rows (max image height) (default: 1280)" << endl; 74 | cout << "-s : show visualization" << endl; 75 | cout << "-f : start frame in the test set (default: 1)" << endl; 76 | cout << "-e : name of current exp (default: exp)" << endl; 77 | } 78 | 79 | void read_lane_file(const string &file_name, vector> &lanes, vector &lane_flags); 80 | void visualize(string &full_im_name, vector> &anno_lanes, vector> &detect_lanes, vector anno_match, int width_lane, string visualize_path); 81 | int32_t createDirectory(const std::string &directoryPath) 82 | { 83 | uint32_t dirPathLen = directoryPath.length(); 84 | if (dirPathLen > MAX_PATH_LEN) 85 | { 86 | return -1; 87 | } 88 | char tmpDirPath[MAX_PATH_LEN] = { 0 }; 89 | for (uint32_t i = 0; i < dirPathLen; ++i) 90 | { 91 | tmpDirPath[i] = directoryPath[i]; 92 | if (tmpDirPath[i] == '\\' || tmpDirPath[i] == '/') 93 | { 94 | if (ACCESS(tmpDirPath, 0) != 0) 95 | { 96 | int32_t ret = MKDIR(tmpDirPath); 97 | if (ret != 0) 98 | { 99 | return ret; 100 | } 101 | } 102 | } 103 | } 104 | return 0; 105 | } 106 | 107 | int main(int argc, char **argv) 108 | { 109 | // process params 110 | string anno_dir = ""; 111 | string detect_dir = "/data/driving/eval_data/predict_label/"; 112 | string im_dir = "/data/driving/eval_data/img/"; 113 | string list_im_file = "/data/driving/eval_data/img/all.txt"; 114 | string output_folder = "./output"; 115 | string exp = "exp"; 116 | 117 | int width_lane = 30; 118 | double iou_threshold = 0.3; 119 | int im_width = 1920; 120 | int im_height = 1280; 121 | int oc; 122 | bool show = true; 123 | int frame = 1; 124 | bool category_flag = false; 125 | while ((oc = getopt(argc, argv, "ha:d:i:l:w:t:c:r:sf:o:k:")) != -1) 126 | { 127 | switch (oc) 128 | { 129 | case 'h': 130 | help(); 131 | return 0; 132 | case 'a': 133 | anno_dir = optarg; 134 | break; 135 | case 'd': 136 | detect_dir = optarg; 137 | break; 138 | case 'i': 139 | im_dir = optarg; 140 | break; 141 | case 'l': 142 | list_im_file = optarg; 143 | break; 144 | case 'w': 145 | width_lane = atoi(optarg); 146 | break; 147 | case 't': 148 | iou_threshold = atof(optarg); 149 | break; 150 | case 'c': 151 | im_width = atoi(optarg); 152 | break; 153 | case 'r': 154 | im_height = atoi(optarg); 155 | break; 156 | case 's': 157 | show = true; 158 | break; 159 | case 'f': 160 | frame = atoi(optarg); 161 | break; 162 | case 'o': 163 | output_folder = optarg; 164 | break; 165 | case 'k': 166 | category_flag = true; 167 | break; 168 | case 'e': 169 | exp = optarg; 170 | break; 171 | } 172 | } 173 | 174 | cout << "------------Configuration---------" << endl; 175 | cout << "anno_dir: " << anno_dir << endl; 176 | cout << "detect_dir: " << detect_dir << endl; 177 | cout << "im_dir: " << im_dir << endl; 178 | cout << "list_im_file: " << list_im_file << endl; 179 | cout << "width_lane: " << width_lane << endl; 180 | cout << "iou_threshold: " << iou_threshold << endl; 181 | cout << "im_width: " << im_width << endl; 182 | cout << "im_height: " << im_height << endl; 183 | cout << "output_folder: " << output_folder + exp<< endl; 184 | cout << "exp: " << exp << endl; 185 | cout << "-----------------------------------" << endl; 186 | // this is the max_width and max_height 187 | if (width_lane < 1) 188 | { 189 | cerr << "width_lane must be positive" << endl; 190 | help(); 191 | return 1; 192 | } 193 | // test 194 | // string path = "/data/images/151992564687014700.json"; 195 | // vector> anno_lanes; 196 | // read_lane_file(path, anno_lanes); 197 | // test 198 | 199 | ifstream ifs_im_list(list_im_file, ios::in); 200 | if (ifs_im_list.fail()) 201 | { 202 | cerr << "Error: file " << list_im_file << " not exist!" << endl; 203 | return 1; 204 | } 205 | Counter counter(im_width, im_height, iou_threshold, width_lane); 206 | 207 | vector anno_match; 208 | string sub_im_name; 209 | // pre-load filelist 210 | vector filelists; 211 | while (getline(ifs_im_list, sub_im_name)) 212 | { 213 | filelists.push_back(sub_im_name); 214 | } 215 | ifs_im_list.close(); 216 | 217 | vector, long, long, long, long>> tuple_lists; 218 | tuple_lists.resize(filelists.size()); 219 | // imwrite( "../../images/Gray_Image.jpg", gray_image ); 220 | string output_file = output_folder + "output.txt"; 221 | 222 | #pragma omp parallel for 223 | for (size_t i = 0; i < filelists.size(); i++) 224 | { 225 | auto sub_im_name = filelists[i]; 226 | string full_im_name = im_dir + sub_im_name; 227 | string sub_json_name = sub_im_name.substr(0, sub_im_name.find_last_of(".")) + ".json"; 228 | string anno_file_name = anno_dir + sub_json_name; 229 | string detect_file_name = detect_dir + sub_json_name; 230 | string visualitation_folder = output_folder + exp; 231 | vector> anno_lanes; 232 | vector> detect_lanes; 233 | vector anno_lane_flags; 234 | vector detect_lane_flags; 235 | read_lane_file(anno_file_name, anno_lanes, anno_lane_flags); 236 | read_lane_file(detect_file_name, detect_lanes, detect_lane_flags); 237 | // add option for category 238 | tuple_lists[i] = counter.count_im_pair(anno_lanes, detect_lanes, anno_lane_flags, detect_lane_flags, category_flag); 239 | if (show) 240 | { 241 | auto anno_match = get<0>(tuple_lists[i]); 242 | string visualize_path = output_folder + "/visual/" + sub_im_name; 243 | visualize(full_im_name, anno_lanes, detect_lanes, anno_match, width_lane, visualize_path); 244 | } 245 | } 246 | 247 | long tp = 0, fp = 0, tn = 0, fn = 0; 248 | for (auto result : tuple_lists) 249 | { 250 | tp += get<1>(result); 251 | fp += get<2>(result); 252 | tn += get<3>(result); 253 | fn += get<4>(result); 254 | } 255 | counter.setTP(tp); 256 | counter.setFP(fp); 257 | counter.setFN(fn); 258 | double precision = counter.get_precision(); 259 | double recall = counter.get_recall(); 260 | double F = 2 * precision * recall / (precision + recall); 261 | cerr << "finished process file" << endl; 262 | cout << "precision: " << precision << endl; 263 | cout << "recall: " << recall << endl; 264 | cout << "Fmeasure: " << F << endl; 265 | cout << "----------------------------------" << endl; 266 | ofstream ofs_out_file; 267 | ofs_out_file.open(output_file, ios::out); 268 | ofs_out_file << "file: " << output_file << endl; 269 | ofs_out_file << "tp: " << counter.getTP() << " fp: " << counter.getFP() << " fn: " << counter.getFN() << endl; 270 | ofs_out_file << "precision: " << precision << endl; 271 | ofs_out_file << "recall: " << recall << endl; 272 | ofs_out_file << "Fmeasure: " << F << endl<< endl; 273 | ofs_out_file.close(); 274 | return 0; 275 | } 276 | 277 | void read_lane_file(const string &file_name, vector> &lanes, vector &lane_flags) 278 | { 279 | lanes.clear(); 280 | std::ifstream fin(file_name); 281 | 282 | neb::CJsonObject oJson; 283 | std::stringstream ssContent; 284 | ssContent << fin.rdbuf(); 285 | oJson.Parse(ssContent.str()); 286 | 287 | for (int j = 0; j < oJson["lane_lines"].GetArraySize(); j++) 288 | { 289 | vector curr_lane; 290 | int category_flag; 291 | if (oJson["lane_lines"][j]["uv"][0].GetArraySize() < 2) { 292 | continue; 293 | } 294 | for (int i = 0; i < oJson["lane_lines"][j]["uv"][0].GetArraySize(); ++i) 295 | { 296 | double u, v; 297 | oJson["lane_lines"][j]["uv"][0].Get(i, u); 298 | oJson["lane_lines"][j]["uv"][1].Get(i, v); 299 | curr_lane.push_back(Point2f(u, v)); 300 | } 301 | 302 | std::sort(curr_lane.begin(), curr_lane.end(), lessmark); 303 | oJson["lane_lines"][j].Get("category", category_flag); 304 | 305 | lane_flags.push_back(uint8_t(category_flag)); 306 | lanes.push_back(curr_lane); 307 | } 308 | 309 | fin.close(); 310 | } 311 | 312 | void visualize(string &full_im_name, vector> &anno_lanes, vector> &detect_lanes, vector anno_match, int width_lane, string visualize_path) 313 | { 314 | cerr< curr_lane; 318 | vector p_interp; 319 | Spline splineSolver; 320 | Scalar color_B = Scalar(255, 0, 0); 321 | Scalar color_G = Scalar(0, 255, 0); 322 | Scalar color_R = Scalar(0, 0, 255); 323 | Scalar color_P = Scalar(255, 0, 255); 324 | Scalar color; 325 | for (int i = 0; i < anno_lanes.size(); i++) 326 | { 327 | curr_lane = anno_lanes[i]; 328 | if (curr_lane.size() == 2) 329 | { 330 | p_interp = curr_lane; 331 | } 332 | else 333 | { 334 | p_interp = splineSolver.splineInterpTimes(curr_lane, 50); 335 | } 336 | if (anno_match[i] >= 0) 337 | { 338 | color = color_G; 339 | } 340 | else 341 | { 342 | color = color_G; 343 | } 344 | for (int n = 0; n < p_interp.size() - 1; n++) 345 | { 346 | line(img, p_interp[n], p_interp[n + 1], color, width_lane); 347 | line(img2, p_interp[n], p_interp[n + 1], color, 2); 348 | } 349 | } 350 | bool detected; 351 | for (int i = 0; i < detect_lanes.size(); i++) 352 | { 353 | detected = false; 354 | curr_lane = detect_lanes[i]; 355 | if (curr_lane.size() == 2) 356 | { 357 | p_interp = curr_lane; 358 | } 359 | else 360 | { 361 | p_interp = splineSolver.splineInterpTimes(curr_lane, 50); 362 | } 363 | for (int n = 0; n < anno_lanes.size(); n++) 364 | { 365 | if (anno_match[n] == i) 366 | { 367 | detected = true; 368 | break; 369 | } 370 | } 371 | if (detected == true) 372 | { 373 | color = color_B; 374 | } 375 | else 376 | { 377 | color = color_R; 378 | } 379 | for (int n = 0; n < p_interp.size() - 1; n++) 380 | { 381 | line(img, p_interp[n], p_interp[n + 1], color, width_lane); 382 | line(img2, p_interp[n], p_interp[n + 1], color, 2); 383 | } 384 | } 385 | string save_folder = visualize_path.substr(0, visualize_path.find_last_of("/")); 386 | createDirectory(save_folder+"/images"); 387 | imwrite(visualize_path, img2); 388 | } 389 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane2d/src/lane_compare.cpp: -------------------------------------------------------------------------------- 1 | /* ============================================================================== 2 | Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | source licenses: 4 | lane_compare.cpp The OpenLane Dataset Authors Apache License, Version 2.0 5 | 6 | See: 7 | https://github.com/XingangPan/SCNN/blob/master/tools/lane_evaluation/src/lane_compare.cpp 8 | https://github.com/XingangPan/SCNN/blob/master/LICENSE 9 | 10 | Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | ============================================================================== */ 23 | 24 | #include "lane_compare.hpp" 25 | 26 | double LaneCompare::get_lane_similarity(const vector &lane1, const vector &lane2) 27 | { 28 | 29 | if(lane1.size()<2 || lane2.size()<2) 30 | { 31 | cerr<<"lane size must be greater or equal to 2"< p_interp1; 38 | vector p_interp2; 39 | if(lane1.size() == 2) 40 | { 41 | p_interp1 = lane1; 42 | } 43 | else 44 | { 45 | p_interp1 = splineSolver.splineInterpTimes(lane1, 50); 46 | } 47 | 48 | if(lane2.size() == 2) 49 | { 50 | p_interp2 = lane2; 51 | } 52 | else 53 | { 54 | p_interp2 = splineSolver.splineInterpTimes(lane2, 50); 55 | } 56 | 57 | Scalar color_white = Scalar(1); 58 | for(int n=0; n &curr_lane, int curr_width, int curr_height) 78 | { 79 | if(curr_width == im_width && curr_height == im_height) 80 | { 81 | return; 82 | } 83 | double x_scale = im_width/(double)curr_width; 84 | double y_scale = im_height/(double)curr_height; 85 | for(int n=0; n 25 | #include 26 | #include "spline.hpp" 27 | using namespace std; 28 | using namespace cv; 29 | 30 | vector Spline::splineInterpTimes(const vector& tmp_line, int times) { 31 | vector res; 32 | if(tmp_line.size() == 2) { 33 | double x1 = tmp_line[0].x; 34 | double y1 = tmp_line[0].y; 35 | double x2 = tmp_line[1].x; 36 | double y2 = tmp_line[1].y; 37 | 38 | for (int k = 0; k <= times; k++) { 39 | double xi = x1 + double((x2 - x1) * k) / times; 40 | double yi = y1 + double((y2 - y1) * k) / times; 41 | res.push_back(Point2f(xi, yi)); 42 | } 43 | } 44 | 45 | else if(tmp_line.size() > 2) 46 | { 47 | vector tmp_func; 48 | tmp_func = this->cal_fun(tmp_line); 49 | if (tmp_func.empty()) { 50 | cout << "in splineInterpTimes: cal_fun failed" << endl; 51 | return res; 52 | } 53 | for(int j = 0; j < tmp_func.size(); j++) 54 | { 55 | double delta = tmp_func[j].h / times; 56 | for(int k = 0; k < times; k++) 57 | { 58 | double t1 = delta*k; 59 | double x1 = tmp_func[j].a_x + tmp_func[j].b_x*t1 + tmp_func[j].c_x*pow(t1,2) + tmp_func[j].d_x*pow(t1,3); 60 | double y1 = tmp_func[j].a_y + tmp_func[j].b_y*t1 + tmp_func[j].c_y*pow(t1,2) + tmp_func[j].d_y*pow(t1,3); 61 | res.push_back(Point2f(x1, y1)); 62 | } 63 | } 64 | res.push_back(tmp_line[tmp_line.size() - 1]); 65 | } 66 | else { 67 | cerr << "in splineInterpTimes: not enough points" << endl; 68 | } 69 | return res; 70 | } 71 | vector Spline::splineInterpStep(vector tmp_line, double step) { 72 | vector res; 73 | /* 74 | if (tmp_line.size() == 2) { 75 | double x1 = tmp_line[0].x; 76 | double y1 = tmp_line[0].y; 77 | double x2 = tmp_line[1].x; 78 | double y2 = tmp_line[1].y; 79 | 80 | for (double yi = std::min(y1, y2); yi < std::max(y1, y2); yi += step) { 81 | double xi; 82 | if (yi == y1) xi = x1; 83 | else xi = (x2 - x1) / (y2 - y1) * (yi - y1) + x1; 84 | res.push_back(Point2f(xi, yi)); 85 | } 86 | }*/ 87 | if (tmp_line.size() == 2) { 88 | double x1 = tmp_line[0].x; 89 | double y1 = tmp_line[0].y; 90 | double x2 = tmp_line[1].x; 91 | double y2 = tmp_line[1].y; 92 | tmp_line[1].x = (x1 + x2) / 2; 93 | tmp_line[1].y = (y1 + y2) / 2; 94 | tmp_line.push_back(Point2f(x2, y2)); 95 | } 96 | if (tmp_line.size() > 2) { 97 | vector tmp_func; 98 | tmp_func = this->cal_fun(tmp_line); 99 | double ystart = tmp_line[0].y; 100 | double yend = tmp_line[tmp_line.size() - 1].y; 101 | bool down; 102 | if (ystart < yend) down = 1; 103 | else down = 0; 104 | if (tmp_func.empty()) { 105 | cerr << "in splineInterpStep: cal_fun failed" << endl; 106 | } 107 | 108 | for(int j = 0; j < tmp_func.size(); j++) 109 | { 110 | for(double t1 = 0; t1 < tmp_func[j].h; t1 += step) 111 | { 112 | double x1 = tmp_func[j].a_x + tmp_func[j].b_x*t1 + tmp_func[j].c_x*pow(t1,2) + tmp_func[j].d_x*pow(t1,3); 113 | double y1 = tmp_func[j].a_y + tmp_func[j].b_y*t1 + tmp_func[j].c_y*pow(t1,2) + tmp_func[j].d_y*pow(t1,3); 114 | res.push_back(Point2f(x1, y1)); 115 | } 116 | } 117 | res.push_back(tmp_line[tmp_line.size() - 1]); 118 | } 119 | else { 120 | cerr << "in splineInterpStep: not enough points" << endl; 121 | } 122 | return res; 123 | } 124 | 125 | vector Spline::cal_fun(const vector &point_v) 126 | { 127 | vector func_v; 128 | int n = point_v.size(); 129 | if(n<=2) { 130 | cout << "in cal_fun: point number less than 3" << endl; 131 | return func_v; 132 | } 133 | 134 | func_v.resize(point_v.size()-1); 135 | 136 | vector Mx(n); 137 | vector My(n); 138 | vector A(n-2); 139 | vector B(n-2); 140 | vector C(n-2); 141 | vector Dx(n-2); 142 | vector Dy(n-2); 143 | vector h(n-1); 144 | //vector func_v(n-1); 145 | 146 | for(int i = 0; i < n-1; i++) 147 | { 148 | h[i] = sqrt(pow(point_v[i+1].x - point_v[i].x, 2) + pow(point_v[i+1].y - point_v[i].y, 2)); 149 | } 150 | 151 | for(int i = 0; i < n-2; i++) 152 | { 153 | A[i] = h[i]; 154 | B[i] = 2*(h[i]+h[i+1]); 155 | C[i] = h[i+1]; 156 | 157 | Dx[i] = 6*( (point_v[i+2].x - point_v[i+1].x)/h[i+1] - (point_v[i+1].x - point_v[i].x)/h[i] ); 158 | Dy[i] = 6*( (point_v[i+2].y - point_v[i+1].y)/h[i+1] - (point_v[i+1].y - point_v[i].y)/h[i] ); 159 | } 160 | 161 | //TDMA 162 | C[0] = C[0] / B[0]; 163 | Dx[0] = Dx[0] / B[0]; 164 | Dy[0] = Dy[0] / B[0]; 165 | for(int i = 1; i < n-2; i++) 166 | { 167 | double tmp = B[i] - A[i]*C[i-1]; 168 | C[i] = C[i] / tmp; 169 | Dx[i] = (Dx[i] - A[i]*Dx[i-1]) / tmp; 170 | Dy[i] = (Dy[i] - A[i]*Dy[i-1]) / tmp; 171 | } 172 | Mx[n-2] = Dx[n-3]; 173 | My[n-2] = Dy[n-3]; 174 | for(int i = n-4; i >= 0; i--) 175 | { 176 | Mx[i+1] = Dx[i] - C[i]*Mx[i+2]; 177 | My[i+1] = Dy[i] - C[i]*My[i+2]; 178 | } 179 | 180 | Mx[0] = 0; 181 | Mx[n-1] = 0; 182 | My[0] = 0; 183 | My[n-1] = 0; 184 | 185 | for(int i = 0; i < n-1; i++) 186 | { 187 | func_v[i].a_x = point_v[i].x; 188 | func_v[i].b_x = (point_v[i+1].x - point_v[i].x)/h[i] - (2*h[i]*Mx[i] + h[i]*Mx[i+1]) / 6; 189 | func_v[i].c_x = Mx[i]/2; 190 | func_v[i].d_x = (Mx[i+1] - Mx[i]) / (6*h[i]); 191 | 192 | func_v[i].a_y = point_v[i].y; 193 | func_v[i].b_y = (point_v[i+1].y - point_v[i].y)/h[i] - (2*h[i]*My[i] + h[i]*My[i+1]) / 6; 194 | func_v[i].c_y = My[i]/2; 195 | func_v[i].d_y = (My[i+1] - My[i]) / (6*h[i]); 196 | 197 | func_v[i].h = h[i]; 198 | } 199 | return func_v; 200 | } 201 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/example/eval_demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python ../eval_3D_lane.py \ 3 | --dataset_dir=./annotations/ \ 4 | --pred_dir=./results/ \ 5 | --test_list=./test_list.txt 6 | -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/example/results/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.json: -------------------------------------------------------------------------------- 1 | {"intrinsic": [[2059.0471439559833, 0.0, 935.1248081874216], [0.0, 2059.0471439559833, 635.052474560227], [0.0, 0.0, 1.0]], "extrinsic": [[0.9998841227217824, 0.015129693588982756, 0.0016833005658143062, 0.0], [-0.0017267926275759344, 0.002862012320402869, 0.9999944135207451, 0.0], [0.01512479144030509, -0.9998814436008807, 0.002887806521551894, 2.1153331179684765], [0.0, 0.0, 0.0, 1.0]], "file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg", "lane_lines": [{"xyz": [[-2.326704680475031, 5.0, -0.29945843181278636], [-2.383390827427654, 10.0, -0.150618040570717], [-2.521979701104893, 15.0, -0.05880890468549327], [-2.7510824402178775, 20.0, 0.014149820336359895], [-3.562614726897876, 30.0, 0.14268395360765093], [-4.763300621992821, 40.0, 0.2224065218095579], [-6.312310299628263, 50.0, 0.28192038575641326], [-8.264841860050602, 60.0, 0.35173204464525715]], "uv": [], "visibility": [], "category": 20, "attribute": 0, "track_id": 0}, {"xyz": [[1.7740352904087988, 5.0, -0.314224257402783], [1.4965295365859175, 10.0, -0.19393865976497038], [1.2332802299684513, 15.0, -0.11954953135682687], [0.925442261380107, 20.0, -0.06496185668677826], [0.0889020725295215, 30.0, 0.019009146757311534], [-1.0935398587710266, 40.0, 0.0718949200432534], [-2.6051690978955024, 50.0, 0.14047355135104328], [-4.4163762396722355, 60.0, 0.19499763711416646], [-8.56806253317381, 80.0, 0.28231091350317356]], "uv": [], "visibility": [], "category": 1, "attribute": 0, "track_id": 0}, {"xyz": [[5.065999073781616, 10.0, -0.23360361148075884], [4.748171248761448, 15.0, -0.1577722537510797], [4.434849558621229, 20.0, -0.10828888902610433], [3.7013049230318975, 30.0, -0.06877446869444986], [2.5942893435757983, 40.0, -0.016168630676721016], [1.0812922346176483, 50.0, 0.053662771407247366], [-0.6973836890669398, 60.0, 0.10869548768227676], [-4.745142012003784, 80.0, 0.20538088778981434]], "uv": [], "visibility": [], "category": 1, "attribute": 0, "track_id": 0}, {"xyz": [[7.907834677091639, 20.0, -0.0827706263268925], [7.057258930727982, 30.0, 0.0004694862367924377], [5.840390700831576, 40.0, 0.05797526004060437], [4.230674178048397, 50.0, 0.1301118294926785], [2.327571550814416, 60.0, 0.186138226443504], [-2.025058866275636, 80.0, 0.27051298380570765]], "uv": [], "visibility": [], "category": 1, "attribute": 0, "track_id": 0}, {"xyz": [[9.784977070279316, 15.0, -0.1654623685209295], [9.753393592239757, 20.0, -0.11515341368208792], [9.093235614318663, 30.0, -0.030632155279861073], [8.0024712741493, 40.0, 0.021311525032222306], [6.337013279219049, 50.0, 0.09088563116277322], [4.382454747402215, 60.0, 0.15037377332334098], [0.12841710476743717, 80.0, 0.22941119593134993], [-3.9831828333875126, 100.0, 0.2518146983936777]], "uv": [], "visibility": [], "category": 2, "attribute": 0, "track_id": 0}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/example/results/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.json: -------------------------------------------------------------------------------- 1 | {"intrinsic": [[2059.0471439559833, 0.0, 935.1248081874216], [0.0, 2059.0471439559833, 635.052474560227], [0.0, 0.0, 1.0]], "extrinsic": [[0.9998841227217824, 0.015129693588982756, 0.0016833005658143062, 0.0], [-0.0017267926275759344, 0.002862012320402869, 0.9999944135207451, 0.0], [0.01512479144030509, -0.9998814436008807, 0.002887806521551894, 2.1153331179684765], [0.0, 0.0, 0.0, 1.0]], "file_path": "validation/segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg", "lane_lines": [{"xyz": [[-2.2848998730468204, 5.0, -0.338967760438946], [-2.3015275993947366, 10.0, -0.17946101826895347], [-2.422596411018705, 15.0, -0.09125665876475611], [-2.6371751800925094, 20.0, -0.03966879930755384], [-3.4209472205373785, 30.0, 0.08060171226713922], [-4.647855391532222, 40.0, 0.14147429046919108], [-6.328969943947831, 50.0, 0.17995060633860013], [-8.448346344656503, 60.0, 0.20668877800818694]], "uv": [], "visibility": [], "category": 20, "attribute": 0, "track_id": 0}, {"xyz": [[1.715130059502486, 5.0, -0.36237297579613004], [1.5100042715724131, 10.0, -0.22974740033355795], [1.3066981985399007, 15.0, -0.16300108417041625], [1.02993946263545, 20.0, -0.12823703015288082], [0.2048703636621756, 30.0, -0.08175562111617006], [-0.9706388575497273, 40.0, -0.052041289459865796], [-2.586770358663809, 50.0, 0.008113442937679507], [-4.6032306705358055, 60.0, 0.045939740121921736], [-9.313039063145705, 80.0, 0.12308104765493935]], "uv": [], "visibility": [], "category": 1, "attribute": 0, "track_id": 0}, {"xyz": [[5.198010310598561, 10.0, -0.26651035014742447], [4.851109208144207, 15.0, -0.19241945102193156], [4.49463410166365, 20.0, -0.15029593143524167], [3.648631402756544, 30.0, -0.1207447171525591], [2.435146893236076, 40.0, -0.08261043724705408], [0.9021831291368132, 50.0, -0.03153189881183228], [-0.8714411137062105, 60.0, -0.006568520659785186]], "uv": [], "visibility": [], "category": 1, "attribute": 0, "track_id": 0}, {"xyz": [[8.65131391724674, 15.0, -0.23932708750630455], [8.115406712045704, 20.0, -0.16628853660499185], [7.0565102615555215, 30.0, -0.09496531451258841], [5.810867079872984, 40.0, -0.050664770905458026], [4.313850183576992, 50.0, -0.011875977350657492], [2.585355778584059, 60.0, 0.00783461311818525]], "uv": [], "visibility": [], "category": 2, "attribute": 0, "track_id": 0}, {"xyz": [[10.221606112645995, 15.0, -0.2125042173933929], [9.786753576929202, 20.0, -0.15848807410461085], [8.791826099675166, 30.0, -0.10570680499007398], [7.666585172666165, 40.0, -0.07244165259073482], [6.28417578517271, 50.0, -0.044643896953575346], [4.487673949780602, 60.0, -0.010358353071818809], [0.15473905155504675, 80.0, 0.05318531381897052]], "uv": [], "visibility": [], "category": 20, "attribute": 0, "track_id": 0}]} -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/example/test_list.txt: -------------------------------------------------------------------------------- 1 | segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801497018700.jpg 2 | segment-10203656353524179475_7625_000_7645_000_with_camera_labels/152268801507012900.jpg -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/utils/MinCostFlow.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # MinCostFlow.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # Contact simachonghao@pjlab.org.cn if you have any issue 7 | # 8 | # See: 9 | # https://github.com/yuliangguo/Pytorch_Generalized_3D_Lane_Detection/blob/master/tools/MinCostFlow.py 10 | # 11 | # Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # ============================================================================== 25 | 26 | from __future__ import print_function 27 | import numpy as np 28 | from ortools.graph import pywrapgraph 29 | import time 30 | 31 | 32 | def SolveMinCostFlow(adj_mat, cost_mat): 33 | """ 34 | Solving an Assignment Problem with MinCostFlow" 35 | :param adj_mat: adjacency matrix with binary values indicating possible matchings between two sets 36 | :param cost_mat: cost matrix recording the matching cost of every possible pair of items from two sets 37 | :return: 38 | """ 39 | 40 | # Instantiate a SimpleMinCostFlow solver. 41 | min_cost_flow = pywrapgraph.SimpleMinCostFlow() 42 | # Define the directed graph for the flow. 43 | 44 | cnt_1, cnt_2 = adj_mat.shape 45 | cnt_nonzero_row = int(np.sum(np.sum(adj_mat, axis=1) > 0)) 46 | cnt_nonzero_col = int(np.sum(np.sum(adj_mat, axis=0) > 0)) 47 | 48 | # prepare directed graph for the flow 49 | start_nodes = np.zeros(cnt_1, dtype=np.int).tolist() +\ 50 | np.repeat(np.array(range(1, cnt_1+1)), cnt_2).tolist() + \ 51 | [i for i in range(cnt_1+1, cnt_1 + cnt_2 + 1)] 52 | end_nodes = [i for i in range(1, cnt_1+1)] + \ 53 | np.repeat(np.array([i for i in range(cnt_1+1, cnt_1 + cnt_2 + 1)]).reshape([1, -1]), cnt_1, axis=0).flatten().tolist() + \ 54 | [cnt_1 + cnt_2 + 1 for i in range(cnt_2)] 55 | capacities = np.ones(cnt_1, dtype=np.int).tolist() + adj_mat.flatten().astype(np.int).tolist() + np.ones(cnt_2, dtype=np.int).tolist() 56 | costs = (np.zeros(cnt_1, dtype=np.int).tolist() + cost_mat.flatten().astype(np.int).tolist() + np.zeros(cnt_2, dtype=np.int).tolist()) 57 | # Define an array of supplies at each node. 58 | supplies = [min(cnt_nonzero_row, cnt_nonzero_col)] + np.zeros(cnt_1 + cnt_2, dtype=np.int).tolist() + [-min(cnt_nonzero_row, cnt_nonzero_col)] 59 | # supplies = [min(cnt_1, cnt_2)] + np.zeros(cnt_1 + cnt_2, dtype=np.int).tolist() + [-min(cnt_1, cnt_2)] 60 | source = 0 61 | sink = cnt_1 + cnt_2 + 1 62 | 63 | # Add each arc. 64 | for i in range(len(start_nodes)): 65 | min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], 66 | capacities[i], costs[i]) 67 | 68 | # Add node supplies. 69 | for i in range(len(supplies)): 70 | min_cost_flow.SetNodeSupply(i, supplies[i]) 71 | 72 | match_results = [] 73 | # Find the minimum cost flow between node 0 and node 10. 74 | if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: 75 | # print('Total cost = ', min_cost_flow.OptimalCost()) 76 | # print() 77 | for arc in range(min_cost_flow.NumArcs()): 78 | 79 | # Can ignore arcs leading out of source or into sink. 80 | if min_cost_flow.Tail(arc)!=source and min_cost_flow.Head(arc)!=sink: 81 | 82 | # Arcs in the solution have a flow value of 1. Their start and end nodes 83 | # give an assignment of worker to task. 84 | 85 | if min_cost_flow.Flow(arc) > 0: 86 | # print('set A item %d assigned to set B item %d. Cost = %d' % ( 87 | # min_cost_flow.Tail(arc)-1, 88 | # min_cost_flow.Head(arc)-cnt_1-1, 89 | # min_cost_flow.UnitCost(arc))) 90 | match_results.append([min_cost_flow.Tail(arc)-1, 91 | min_cost_flow.Head(arc)-cnt_1-1, 92 | min_cost_flow.UnitCost(arc)]) 93 | else: 94 | print('There was an issue with the min cost flow input.') 95 | 96 | return match_results 97 | 98 | 99 | def main(): 100 | """Solving an Assignment Problem with MinCostFlow""" 101 | 102 | # Instantiate a SimpleMinCostFlow solver. 103 | min_cost_flow = pywrapgraph.SimpleMinCostFlow() 104 | # Define the directed graph for the flow. 105 | 106 | start_nodes = [0, 0, 0, 0] + [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4] + [5, 6, 7, 8] 107 | end_nodes = [1, 2, 3, 4] + [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8] + [9, 9, 9, 9] 108 | capacities = [1, 1, 1, 1] + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + [1, 1, 1, 1] 109 | costs = ([0, 0, 0, 0] + [90, 76, 75, 70, 35, 85, 55, 65, 125, 95, 90, 105, 45, 110, 95, 115] + [0, 0, 0, 0]) 110 | # Define an array of supplies at each node. 111 | supplies = [4, 0, 0, 0, 0, 0, 0, 0, 0, -4] 112 | source = 0 113 | sink = 9 114 | tasks = 4 115 | 116 | # Add each arc. 117 | for i in range(len(start_nodes)): 118 | min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i], 119 | capacities[i], costs[i]) 120 | 121 | # Add node supplies. 122 | 123 | for i in range(len(supplies)): 124 | min_cost_flow.SetNodeSupply(i, supplies[i]) 125 | # Find the minimum cost flow between node 0 and node 10. 126 | if min_cost_flow.Solve() == min_cost_flow.OPTIMAL: 127 | print('Total cost = ', min_cost_flow.OptimalCost()) 128 | print() 129 | for arc in range(min_cost_flow.NumArcs()): 130 | 131 | # Can ignore arcs leading out of source or into sink. 132 | if min_cost_flow.Tail(arc)!=source and min_cost_flow.Head(arc)!=sink: 133 | 134 | # Arcs in the solution have a flow value of 1. Their start and end nodes 135 | # give an assignment of worker to task. 136 | 137 | if min_cost_flow.Flow(arc) > 0: 138 | print('Worker %d assigned to task %d. Cost = %d' % ( 139 | min_cost_flow.Tail(arc), 140 | min_cost_flow.Head(arc), 141 | min_cost_flow.UnitCost(arc))) 142 | else: 143 | print('There was an issue with the min cost flow input.') 144 | 145 | 146 | if __name__ == '__main__': 147 | start_time = time.clock() 148 | main() 149 | print() 150 | print("Time =", time.clock() - start_time, "seconds") -------------------------------------------------------------------------------- /eval/LANE_evaluation/lane3d/utils/utils.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Binaries and/or source for the following packages or projects are presented under one or more of the following open 3 | # source licenses: 4 | # utils.py The OpenLane Dataset Authors Apache License, Version 2.0 5 | # 6 | # Contact simachonghao@pjlab.org.cn if you have any issue 7 | # 8 | # See: 9 | # https://github.com/yuliangguo/Pytorch_Generalized_3D_Lane_Detection/blob/master/tools/utils.py 10 | # 11 | # Copyright (c) 2022 The OpenLane Dataset Authors. All Rights Reserved. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # ============================================================================== 25 | 26 | # -*- coding: utf-8 -*- 27 | import argparse 28 | import errno 29 | import os 30 | import numpy as np 31 | from scipy.interpolate import interp1d 32 | 33 | 34 | def define_args(): 35 | parser = argparse.ArgumentParser(description='3D lane evaluation') 36 | # Paths settings 37 | parser.add_argument('--dataset_dir', type=str, help='The path saving actual data') 38 | parser.add_argument('--pred_dir', type=str, help='The path of prediction result') 39 | parser.add_argument('--test_list', type=str, help='The path of test list txt') 40 | # parser.add_argument('--images_dir', type=str, help='The path saving dataset images') 41 | 42 | return parser 43 | 44 | 45 | def prune_3d_lane_by_visibility(lane_3d, visibility): 46 | lane_3d = lane_3d[visibility > 0, ...] 47 | return lane_3d 48 | 49 | 50 | def prune_3d_lane_by_range(lane_3d, x_min, x_max): 51 | # TODO: solve hard coded range later 52 | lane_3d = lane_3d[np.logical_and(lane_3d[:, 1] > 0, lane_3d[:, 1] < 200), ...] 53 | 54 | # remove lane points out of x range 55 | lane_3d = lane_3d[np.logical_and(lane_3d[:, 0] > x_min, 56 | lane_3d[:, 0] < x_max), ...] 57 | return lane_3d 58 | 59 | 60 | def resample_laneline_in_y(input_lane, y_steps, out_vis=False): 61 | """ 62 | Interpolate x, z values at each anchor grid, including those beyond the range of input lnae y range 63 | :param input_lane: N x 2 or N x 3 ndarray, one row for a point (x, y, z-optional). 64 | It requires y values of input lane in ascending order 65 | :param y_steps: a vector of steps in y 66 | :param out_vis: whether to output visibility indicator which only depends on input y range 67 | :return: 68 | """ 69 | 70 | # at least two points are included 71 | assert(input_lane.shape[0] >= 2) 72 | 73 | y_min = np.min(input_lane[:, 1])-5 74 | y_max = np.max(input_lane[:, 1])+5 75 | 76 | if input_lane.shape[1] < 3: 77 | input_lane = np.concatenate([input_lane, np.zeros([input_lane.shape[0], 1], dtype=np.float32)], axis=1) 78 | 79 | f_x = interp1d(input_lane[:, 1], input_lane[:, 0], fill_value="extrapolate") 80 | f_z = interp1d(input_lane[:, 1], input_lane[:, 2], fill_value="extrapolate") 81 | 82 | x_values = f_x(y_steps) 83 | z_values = f_z(y_steps) 84 | 85 | if out_vis: 86 | output_visibility = np.logical_and(y_steps >= y_min, y_steps <= y_max) 87 | return x_values, z_values, output_visibility.astype(np.float32) + 1e-9 88 | return x_values, z_values 89 | 90 | 91 | def projection_g2im_extrinsic(E, K): 92 | E_inv = np.linalg.inv(E)[0:3, :] 93 | P_g2im = np.matmul(K, E_inv) 94 | return P_g2im 95 | 96 | -------------------------------------------------------------------------------- /eval/README.md: -------------------------------------------------------------------------------- 1 | # OpenLane Evaluation Kit 2 | 3 | This is the Official Evaluation Kit for OpenLane Dataset. 4 | 5 | 6 | ## Requirements 7 | - [OpenCV 3.4.2 (C++)](https://docs.opencv.org/3.4.2/d7/d9f/tutorial_linux_install.html) 8 | - numpy 9 | - matplotlib 10 | - scipy 11 | - ortools 12 | - g++ 13 | 14 | ## Install 15 | We provide a requirements.txt to setup the environment of evaluation. To install: 16 | ``` 17 | git clone https://github.com/OpenPerceptionX/OpenLane.git 18 | cd OpenLane/eval 19 | conda create -n openlane_eval python=3.8 -y 20 | conda activate openlane_eval 21 | pip install -r requirements.txt 22 | cd ./CIPO_evaluation 23 | make 24 | cd ../LANE_evaluation/lane2d 25 | # You should install OpenCV 3.4.2 (C++) first following the link and 26 | # specify your opencv path in ./Makefile#L40,41 (OPENCV_INCLUDE and OPENCV_LIB_PATH) 27 | make 28 | ``` 29 | 30 | ## Evaluation 31 | - [CIPO Evaluation](CIPO_evaluation/README.md) 32 | - [Lane Evaluation](LANE_evaluation/README.md) 33 | -------------------------------------------------------------------------------- /eval/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.22.3 2 | ortools==9.2.9972 3 | scipy==1.8.0 4 | matplotlib==3.5.1 5 | -------------------------------------------------------------------------------- /imgs/overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/imgs/overview.gif -------------------------------------------------------------------------------- /imgs/overview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenDriveLab/OpenLane/8a0ce6b0057278729f4753a57be38c12929d7ad9/imgs/overview.jpg --------------------------------------------------------------------------------