onnx models
#12
by SavyaSanchi - opened
This view is limited to 50 files because it contains too many changes. See the raw diff here.
- .gitignore +3 -0
- efficientdet-d0/LICENSE +203 -0
- efficientdet-d0/README.md +62 -0
- efficientdet-d0/convert_to_onnx.py +41 -0
- efficientdet-d0/demo.cpp +127 -0
- efficientdet-d0/demo.py +105 -0
- efficientdet-d0/efficientdet-d0_2026jul.onnx +3 -0
- efficientdet-d0/example_outputs/input_image.png +3 -0
- efficientdet-d0/example_outputs/output_image.png +3 -0
- faster_rcnn_inception_v2_coco_2018_01_28/LICENSE +203 -0
- faster_rcnn_inception_v2_coco_2018_01_28/README.md +49 -0
- faster_rcnn_inception_v2_coco_2018_01_28/convert_to_onnx.py +40 -0
- faster_rcnn_inception_v2_coco_2018_01_28/demo.cpp +83 -0
- faster_rcnn_inception_v2_coco_2018_01_28/demo.py +51 -0
- faster_rcnn_inception_v2_coco_2018_01_28/example_outputs/input_image.png +3 -0
- faster_rcnn_inception_v2_coco_2018_01_28/example_outputs/output_image.png +3 -0
- faster_rcnn_inception_v2_coco_2018_01_28/faster_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx +3 -0
- faster_rcnn_resnet50_coco_2018_01_28/LICENSE +203 -0
- faster_rcnn_resnet50_coco_2018_01_28/README.md +49 -0
- faster_rcnn_resnet50_coco_2018_01_28/convert_to_onnx.py +40 -0
- faster_rcnn_resnet50_coco_2018_01_28/demo.cpp +83 -0
- faster_rcnn_resnet50_coco_2018_01_28/demo.py +51 -0
- faster_rcnn_resnet50_coco_2018_01_28/example_outputs/input_image.png +3 -0
- faster_rcnn_resnet50_coco_2018_01_28/example_outputs/output_image.png +3 -0
- faster_rcnn_resnet50_coco_2018_01_28/faster_rcnn_resnet50_coco_2018_01_28_2026jul.onnx +3 -0
- mask_rcnn_inception_v2_coco_2018_01_28/LICENSE +203 -0
- mask_rcnn_inception_v2_coco_2018_01_28/README.md +51 -0
- mask_rcnn_inception_v2_coco_2018_01_28/convert_to_onnx.py +46 -0
- mask_rcnn_inception_v2_coco_2018_01_28/demo.cpp +109 -0
- mask_rcnn_inception_v2_coco_2018_01_28/demo.py +59 -0
- mask_rcnn_inception_v2_coco_2018_01_28/example_outputs/input_image.png +3 -0
- mask_rcnn_inception_v2_coco_2018_01_28/example_outputs/output_image.png +3 -0
- mask_rcnn_inception_v2_coco_2018_01_28/mask_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx +3 -0
- opencv_face_detector_uint8/LICENSE +203 -0
- opencv_face_detector_uint8/README.md +67 -0
- opencv_face_detector_uint8/convert_to_onnx.py +73 -0
- opencv_face_detector_uint8/demo.cpp +146 -0
- opencv_face_detector_uint8/demo.py +109 -0
- opencv_face_detector_uint8/example_outputs/input_image.png +3 -0
- opencv_face_detector_uint8/example_outputs/output_image.png +3 -0
- opencv_face_detector_uint8/opencv_face_detector_uint8_2026jul.onnx +3 -0
- ssd_inception_v2_coco_2017_11_17/LICENSE +212 -0
- ssd_inception_v2_coco_2017_11_17/README.md +48 -0
- ssd_inception_v2_coco_2017_11_17/convert_to_onnx.py +40 -0
- ssd_inception_v2_coco_2017_11_17/demo.cpp +81 -0
- ssd_inception_v2_coco_2017_11_17/demo.py +52 -0
- ssd_inception_v2_coco_2017_11_17/example_outputs/input_image.png +3 -0
- ssd_inception_v2_coco_2017_11_17/example_outputs/output_image.png +3 -0
- ssd_inception_v2_coco_2017_11_17/ssd_inception_v2_coco_2017_11_17_2026jul.onnx +3 -0
- ssd_mobilenet_v1_coco_2017_11_17/LICENSE +203 -0
.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
ssd_mobilenet_v2_coco_2018_03_29/demo
|
| 2 |
+
|
| 3 |
+
**/demo
|
efficientdet-d0/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2020 Google Research. 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 2020, Google Research.
|
| 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.
|
efficientdet-d0/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# EfficientDet-D0
|
| 2 |
+
|
| 3 |
+
Object detection with EfficientDet-D0 trained on COCO. The model was originally
|
| 4 |
+
distributed as a frozen TensorFlow graph (`efficientdet-d0.pb`) and converted to
|
| 5 |
+
ONNX for use with OpenCV's DNN module. This is a **backbone-only** export: the
|
| 6 |
+
graph emits raw class logits and box regressions, while anchor generation, sigmoid,
|
| 7 |
+
box decoding and non-maximum suppression are performed in host code (see the demos).
|
| 8 |
+
|
| 9 |
+
## Model Details
|
| 10 |
+
- **Architecture**: EfficientDet-D0
|
| 11 |
+
- **Input**: RGB image, 512×512, raw uint8, NHWC layout (`image_arrays:0`, shape `[1, 512, 512, 3]`)
|
| 12 |
+
- **Output**: raw class logits (`concat:0`, shape `[1, 49104, 90]`) and box regression (`concat_1:0`, shape `[1, 49104, 4]`); anchor decode + NMS are done in host code, not in the graph
|
| 13 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
|
| 14 |
+
- **Original weights**: https://www.dropbox.com/s/9mqp99fd2tpuqn6/efficientdet-d0.pb?dl=1
|
| 15 |
+
|
| 16 |
+
The graph outputs are per-anchor predictions only. The demos build the 49104 anchors
|
| 17 |
+
(5 pyramid levels × 9 anchors/cell), apply sigmoid to the logits, decode the box
|
| 18 |
+
regressions relative to the anchors, threshold on confidence and run NMS (IoU 0.6).
|
| 19 |
+
|
| 20 |
+
## Usage
|
| 21 |
+
|
| 22 |
+
### Python
|
| 23 |
+
```bash
|
| 24 |
+
python demo.py --model efficientdet-d0_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.4
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
Or import directly:
|
| 28 |
+
```python
|
| 29 |
+
import cv2
|
| 30 |
+
|
| 31 |
+
net = cv2.dnn.readNet("efficientdet-d0_2026jul.onnx")
|
| 32 |
+
# see demo.py for the full anchor decode + NMS pipeline
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
### C++
|
| 36 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 37 |
+
```bash
|
| 38 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 39 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 40 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 41 |
+
-I$OCV/include \
|
| 42 |
+
-I$OCV/modules/core/include \
|
| 43 |
+
-I$OCV/modules/dnn/include \
|
| 44 |
+
-I$OCV/modules/imgproc/include \
|
| 45 |
+
-I$OCV/modules/imgcodecs/include \
|
| 46 |
+
-I$OCVBUILD \
|
| 47 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 48 |
+
./demo --model efficientdet-d0_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
## Conversion
|
| 52 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18)
|
| 53 |
+
via [convert_to_onnx.py](./convert_to_onnx.py) — input `image_arrays:0`, outputs
|
| 54 |
+
`concat:0` and `concat_1:0`, input shape overridden to `[1, 512, 512, 3]`. Requires
|
| 55 |
+
`tensorflow`, `tf2onnx`, and `onnx`.
|
| 56 |
+
|
| 57 |
+
```bash
|
| 58 |
+
python convert_to_onnx.py --pb ../pb/efficientdet-d0.pb
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
## License
|
| 62 |
+
See [LICENSE](./LICENSE) — released under the Apache License 2.0.
|
efficientdet-d0/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import onnx
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def load_graph_def(pb_path):
|
| 10 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 11 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 12 |
+
graph_def.ParseFromString(f.read())
|
| 13 |
+
return graph_def
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser(description="Export efficientdet-d0.pb to ONNX")
|
| 18 |
+
parser.add_argument("--pb", default="../pb/efficientdet-d0.pb")
|
| 19 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 20 |
+
args = parser.parse_args()
|
| 21 |
+
|
| 22 |
+
graph_def = load_graph_def(args.pb)
|
| 23 |
+
|
| 24 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 25 |
+
graph_def,
|
| 26 |
+
input_names=["image_arrays:0"],
|
| 27 |
+
output_names=["concat:0", "concat_1:0"],
|
| 28 |
+
opset=args.opset,
|
| 29 |
+
shape_override={"image_arrays:0": [1, 512, 512, 3]},
|
| 30 |
+
)
|
| 31 |
+
onnx.checker.check_model(model_proto)
|
| 32 |
+
|
| 33 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 34 |
+
onnx_path = "efficientdet-d0_%s.onnx" % stamp
|
| 35 |
+
with open(onnx_path, "wb") as f:
|
| 36 |
+
f.write(model_proto.SerializeToString())
|
| 37 |
+
print("wrote", onnx_path)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
if __name__ == "__main__":
|
| 41 |
+
main()
|
efficientdet-d0/demo.cpp
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <algorithm>
|
| 5 |
+
#include <array>
|
| 6 |
+
#include <cmath>
|
| 7 |
+
#include <iostream>
|
| 8 |
+
#include <string>
|
| 9 |
+
#include <vector>
|
| 10 |
+
|
| 11 |
+
using namespace cv;
|
| 12 |
+
|
| 13 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 14 |
+
{
|
| 15 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 16 |
+
if (key == argv[i]) return argv[i + 1];
|
| 17 |
+
return def;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
struct Det { float x1, y1, x2, y2, score; int cid; };
|
| 21 |
+
|
| 22 |
+
int main(int argc, char** argv)
|
| 23 |
+
{
|
| 24 |
+
std::string model = argVal(argc, argv, "--model", "efficientdet-d0_2026jul.onnx");
|
| 25 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 26 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 27 |
+
float conf = std::stof(argVal(argc, argv, "--conf", "0.4"));
|
| 28 |
+
|
| 29 |
+
const int sz = 512;
|
| 30 |
+
|
| 31 |
+
Mat img = imread(image);
|
| 32 |
+
if (img.empty()) { std::cerr << "could not read image: " << image << std::endl; return 1; }
|
| 33 |
+
|
| 34 |
+
Mat rgb;
|
| 35 |
+
cvtColor(img, rgb, COLOR_BGR2RGB);
|
| 36 |
+
resize(rgb, rgb, Size(sz, sz));
|
| 37 |
+
if (!rgb.isContinuous()) rgb = rgb.clone();
|
| 38 |
+
|
| 39 |
+
int blobShape[] = {1, sz, sz, 3};
|
| 40 |
+
Mat blob(4, blobShape, CV_8U, rgb.data);
|
| 41 |
+
dnn::Net net = dnn::readNetFromONNX(model);
|
| 42 |
+
net.setInput(blob);
|
| 43 |
+
std::vector<Mat> outs;
|
| 44 |
+
net.forward(outs, net.getUnconnectedOutLayersNames());
|
| 45 |
+
|
| 46 |
+
const float* boxp = nullptr;
|
| 47 |
+
const float* clsp = nullptr;
|
| 48 |
+
int n = 0, nc = 0;
|
| 49 |
+
for (size_t i = 0; i < outs.size(); ++i)
|
| 50 |
+
{
|
| 51 |
+
const Mat& o = outs[i];
|
| 52 |
+
const float* p = (const float*)o.data;
|
| 53 |
+
int last = o.size[o.dims - 1];
|
| 54 |
+
if (last == 4) { boxp = p; n = o.size[o.dims - 2]; }
|
| 55 |
+
else { clsp = p; nc = last; }
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
std::vector<std::array<float, 2>> baseWH;
|
| 59 |
+
double asp[3][2] = {{1.0, 1.0}, {1.4, 0.7}, {0.7, 1.4}};
|
| 60 |
+
for (int i = 0; i < 3; ++i) {
|
| 61 |
+
double s = std::pow(2.0, i / 3.0);
|
| 62 |
+
for (int a = 0; a < 3; ++a)
|
| 63 |
+
baseWH.push_back({(float)(32.0 * s * asp[a][0]), (float)(32.0 * s * asp[a][1])});
|
| 64 |
+
}
|
| 65 |
+
std::vector<float> acx, acy, aw, ah;
|
| 66 |
+
for (int lvl = 0; lvl < 5; ++lvl) {
|
| 67 |
+
int f = sz / (8 << lvl);
|
| 68 |
+
int step = 8 << lvl;
|
| 69 |
+
int m = 1 << lvl;
|
| 70 |
+
for (int y = 0; y < f; ++y)
|
| 71 |
+
for (int x = 0; x < f; ++x) {
|
| 72 |
+
float cx = (x + 0.5f) * step;
|
| 73 |
+
float cy = (y + 0.5f) * step;
|
| 74 |
+
for (auto& b : baseWH) {
|
| 75 |
+
acx.push_back(cx); acy.push_back(cy);
|
| 76 |
+
aw.push_back(b[0] * m); ah.push_back(b[1] * m);
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
std::vector<Det> dets;
|
| 82 |
+
for (int a = 0; a < n; ++a) {
|
| 83 |
+
const float* bp = boxp + (size_t)a * 4;
|
| 84 |
+
float ycenter = bp[0] * ah[a] + acy[a];
|
| 85 |
+
float xcenter = bp[1] * aw[a] + acx[a];
|
| 86 |
+
float bhv = std::exp(bp[2]) * ah[a];
|
| 87 |
+
float bwv = std::exp(bp[3]) * aw[a];
|
| 88 |
+
const float* cp = clsp + (size_t)a * nc;
|
| 89 |
+
int best = 0; float bestLogit = cp[0];
|
| 90 |
+
for (int c = 1; c < nc; ++c) if (cp[c] > bestLogit) { bestLogit = cp[c]; best = c; }
|
| 91 |
+
float score = 1.0f / (1.0f + std::exp(-bestLogit));
|
| 92 |
+
if (score > conf)
|
| 93 |
+
dets.push_back({(xcenter - bwv / 2) / sz, (ycenter - bhv / 2) / sz,
|
| 94 |
+
(xcenter + bwv / 2) / sz, (ycenter + bhv / 2) / sz, score, best});
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
std::sort(dets.begin(), dets.end(), [](const Det& a, const Det& b) { return a.score > b.score; });
|
| 98 |
+
std::vector<char> removed(dets.size(), 0);
|
| 99 |
+
std::vector<int> pick;
|
| 100 |
+
for (size_t i = 0; i < dets.size(); ++i) {
|
| 101 |
+
if (removed[i]) continue;
|
| 102 |
+
pick.push_back((int)i);
|
| 103 |
+
for (size_t j = i + 1; j < dets.size(); ++j) {
|
| 104 |
+
if (removed[j]) continue;
|
| 105 |
+
float xx1 = std::max(dets[i].x1, dets[j].x1);
|
| 106 |
+
float yy1 = std::max(dets[i].y1, dets[j].y1);
|
| 107 |
+
float xx2 = std::min(dets[i].x2, dets[j].x2);
|
| 108 |
+
float yy2 = std::min(dets[i].y2, dets[j].y2);
|
| 109 |
+
float inter = std::max(0.0f, xx2 - xx1) * std::max(0.0f, yy2 - yy1);
|
| 110 |
+
float ai = (dets[i].x2 - dets[i].x1) * (dets[i].y2 - dets[i].y1);
|
| 111 |
+
float aj = (dets[j].x2 - dets[j].x1) * (dets[j].y2 - dets[j].y1);
|
| 112 |
+
if (inter / (ai + aj - inter + 1e-9f) > 0.6f) removed[j] = 1;
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
std::cout << "efficientdet-d0 " << pick.size() << " detections" << std::endl;
|
| 117 |
+
int w = img.cols, h = img.rows;
|
| 118 |
+
for (int idx : pick) {
|
| 119 |
+
const Det& d = dets[idx];
|
| 120 |
+
std::cout << format("%d %.3f %.3f %.3f %.3f %.3f", d.cid, d.score, d.x1, d.y1, d.x2, d.y2) << std::endl;
|
| 121 |
+
rectangle(img, Point((int)(d.x1 * w), (int)(d.y1 * h)), Point((int)(d.x2 * w), (int)(d.y2 * h)), Scalar(0, 255, 0), 2);
|
| 122 |
+
putText(img, format("%d:%.2f", d.cid, d.score), Point((int)(d.x1 * w), (int)(d.y1 * h) - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
|
| 123 |
+
}
|
| 124 |
+
imwrite(output, img);
|
| 125 |
+
std::cout << "wrote " << output << std::endl;
|
| 126 |
+
return 0;
|
| 127 |
+
}
|
efficientdet-d0/demo.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
sz = 512
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def build_anchors():
|
| 13 |
+
scales = [2.0 ** (i / 3.0) for i in range(3)]
|
| 14 |
+
aspects = [(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)]
|
| 15 |
+
base = []
|
| 16 |
+
for s in scales:
|
| 17 |
+
for aw, ah in aspects:
|
| 18 |
+
base.append((32.0 * s * aw, 32.0 * s * ah))
|
| 19 |
+
anchors = []
|
| 20 |
+
for lvl in range(5):
|
| 21 |
+
f = sz // (8 * 2 ** lvl)
|
| 22 |
+
step = 8 * 2 ** lvl
|
| 23 |
+
m = 2 ** lvl
|
| 24 |
+
for y in range(f):
|
| 25 |
+
for x in range(f):
|
| 26 |
+
cx = (x + 0.5) * step
|
| 27 |
+
cy = (y + 0.5) * step
|
| 28 |
+
for bw, bh in base:
|
| 29 |
+
anchors.append((cx, cy, bw * m, bh * m))
|
| 30 |
+
return np.array(anchors, np.float32)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def main():
|
| 34 |
+
parser = argparse.ArgumentParser(description="EfficientDet-D0 (ONNX) object detection demo")
|
| 35 |
+
parser.add_argument("--model", default=None)
|
| 36 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 37 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 38 |
+
parser.add_argument("--conf", type=float, default=0.4)
|
| 39 |
+
args = parser.parse_args()
|
| 40 |
+
|
| 41 |
+
model = args.model
|
| 42 |
+
if model is None:
|
| 43 |
+
found = glob.glob(os.path.join(here, "*.onnx"))
|
| 44 |
+
if not found:
|
| 45 |
+
raise SystemExit("no onnx, run convert_to_onnx.py")
|
| 46 |
+
model = found[0]
|
| 47 |
+
|
| 48 |
+
img = cv.imread(args.image)
|
| 49 |
+
if img is None:
|
| 50 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 51 |
+
|
| 52 |
+
anchors = build_anchors()
|
| 53 |
+
acx, acy, aw, ah = anchors[:, 0], anchors[:, 1], anchors[:, 2], anchors[:, 3]
|
| 54 |
+
|
| 55 |
+
net = cv.dnn.readNetFromONNX(model)
|
| 56 |
+
inp = cv.resize(cv.cvtColor(img, cv.COLOR_BGR2RGB), (sz, sz))
|
| 57 |
+
net.setInput(inp[None].astype(np.uint8))
|
| 58 |
+
res = net.forward(net.getUnconnectedOutLayersNames())
|
| 59 |
+
box = next(a for a in res if a.shape[-1] == 4).reshape(-1, 4)
|
| 60 |
+
cls = next(a for a in res if a.shape[-1] != 4).reshape(box.shape[0], -1)
|
| 61 |
+
|
| 62 |
+
ycenter = box[:, 0] * ah + acy
|
| 63 |
+
xcenter = box[:, 1] * aw + acx
|
| 64 |
+
bh = np.exp(box[:, 2]) * ah
|
| 65 |
+
bw = np.exp(box[:, 3]) * aw
|
| 66 |
+
boxes = np.stack([xcenter - bw / 2, ycenter - bh / 2, xcenter + bw / 2, ycenter + bh / 2], 1) / sz
|
| 67 |
+
|
| 68 |
+
prob = 1.0 / (1.0 + np.exp(-cls))
|
| 69 |
+
cid = prob.argmax(1)
|
| 70 |
+
scores = prob.max(1)
|
| 71 |
+
|
| 72 |
+
keep = scores > args.conf
|
| 73 |
+
boxes = boxes[keep]
|
| 74 |
+
scores = scores[keep]
|
| 75 |
+
cid = cid[keep]
|
| 76 |
+
order = scores.argsort()[::-1]
|
| 77 |
+
pick = []
|
| 78 |
+
while order.size:
|
| 79 |
+
i = order[0]
|
| 80 |
+
pick.append(i)
|
| 81 |
+
xx1 = np.maximum(boxes[i, 0], boxes[order[1:], 0])
|
| 82 |
+
yy1 = np.maximum(boxes[i, 1], boxes[order[1:], 1])
|
| 83 |
+
xx2 = np.minimum(boxes[i, 2], boxes[order[1:], 2])
|
| 84 |
+
yy2 = np.minimum(boxes[i, 3], boxes[order[1:], 3])
|
| 85 |
+
iw = np.maximum(0, xx2 - xx1)
|
| 86 |
+
ih = np.maximum(0, yy2 - yy1)
|
| 87 |
+
inter = iw * ih
|
| 88 |
+
ai = (boxes[i, 2] - boxes[i, 0]) * (boxes[i, 3] - boxes[i, 1])
|
| 89 |
+
aj = (boxes[order[1:], 2] - boxes[order[1:], 0]) * (boxes[order[1:], 3] - boxes[order[1:], 1])
|
| 90 |
+
iou = inter / (ai + aj - inter + 1e-9)
|
| 91 |
+
order = order[1:][iou <= 0.6]
|
| 92 |
+
|
| 93 |
+
print("efficientdet-d0", len(pick), "detections")
|
| 94 |
+
h, w = img.shape[:2]
|
| 95 |
+
for i in pick:
|
| 96 |
+
x1, y1, x2, y2 = boxes[i]
|
| 97 |
+
print(int(cid[i]), round(float(scores[i]), 3), round(float(x1), 3), round(float(y1), 3), round(float(x2), 3), round(float(y2), 3))
|
| 98 |
+
cv.rectangle(img, (int(x1 * w), int(y1 * h)), (int(x2 * w), int(y2 * h)), (0, 255, 0), 2)
|
| 99 |
+
cv.putText(img, "%d:%.2f" % (int(cid[i]), scores[i]), (int(x1 * w), int(y1 * h) - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
| 100 |
+
cv.imwrite(args.output, img)
|
| 101 |
+
print("wrote", args.output)
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
if __name__ == "__main__":
|
| 105 |
+
main()
|
efficientdet-d0/efficientdet-d0_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:db344f69adf1c529e08a36bbaa1779d98b4b81621a2f046656fb966bdfdc6298
|
| 3 |
+
size 15671001
|
efficientdet-d0/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
efficientdet-d0/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
faster_rcnn_inception_v2_coco_2018_01_28/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2015 The TensorFlow 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 2015, The TensorFlow Authors.
|
| 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.
|
faster_rcnn_inception_v2_coco_2018_01_28/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Faster-RCNN InceptionV2 (COCO)
|
| 2 |
+
|
| 3 |
+
Object detection with the Faster-RCNN meta-architecture and an Inception v2 backbone,
|
| 4 |
+
trained on the COCO dataset. The model was originally distributed as a frozen TensorFlow
|
| 5 |
+
graph (`faster_rcnn_inception_v2_coco_2018_01_28.pb`) from the TensorFlow Object Detection
|
| 6 |
+
API and converted to ONNX for inference with OpenCV's DNN module.
|
| 7 |
+
|
| 8 |
+
## Model Details
|
| 9 |
+
- **Architecture**: Faster-RCNN with an Inception v2 backbone
|
| 10 |
+
- **Input**: RGB image, uint8, NHWC layout (`image_tensor:0`, shape `[1, H, W, 3]`)
|
| 11 |
+
- **Output**: `detection_boxes:0` (normalized `[ymin, xmin, ymax, xmax]`), `detection_scores:0`, `detection_classes:0` (1-based COCO ids), `num_detections:0`
|
| 12 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
|
| 13 |
+
- **Original weights**: http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_v2_coco_2018_01_28.tar.gz
|
| 14 |
+
|
| 15 |
+
## Usage
|
| 16 |
+
|
| 17 |
+
### Python
|
| 18 |
+
```bash
|
| 19 |
+
python demo.py --model faster_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.3
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
### C++
|
| 23 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 24 |
+
```bash
|
| 25 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 26 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 27 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 28 |
+
-I$OCV/include \
|
| 29 |
+
-I$OCV/modules/core/include \
|
| 30 |
+
-I$OCV/modules/dnn/include \
|
| 31 |
+
-I$OCV/modules/imgproc/include \
|
| 32 |
+
-I$OCV/modules/imgcodecs/include \
|
| 33 |
+
-I$OCVBUILD \
|
| 34 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 35 |
+
./demo --model faster_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
## Conversion
|
| 39 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18)
|
| 40 |
+
via [convert_to_onnx.py](./convert_to_onnx.py) — input `image_tensor:0`, outputs
|
| 41 |
+
`detection_boxes:0`, `detection_scores:0`, `detection_classes:0`, `num_detections:0`.
|
| 42 |
+
Requires `tensorflow`, `tf2onnx`, and `onnx`.
|
| 43 |
+
|
| 44 |
+
```bash
|
| 45 |
+
python convert_to_onnx.py --pb ../pb/faster_rcnn_inception_v2_coco_2018_01_28.pb
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
## License
|
| 49 |
+
See [LICENSE](./LICENSE) — the model is released by the TensorFlow Authors under the Apache License 2.0.
|
faster_rcnn_inception_v2_coco_2018_01_28/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import onnx
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def load_graph_def(pb_path):
|
| 10 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 11 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 12 |
+
graph_def.ParseFromString(f.read())
|
| 13 |
+
return graph_def
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser(description="Export faster_rcnn_inception_v2_coco_2018_01_28.pb to ONNX")
|
| 18 |
+
parser.add_argument("--pb", default="../pb/faster_rcnn_inception_v2_coco_2018_01_28.pb")
|
| 19 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 20 |
+
args = parser.parse_args()
|
| 21 |
+
|
| 22 |
+
graph_def = load_graph_def(args.pb)
|
| 23 |
+
|
| 24 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 25 |
+
graph_def,
|
| 26 |
+
input_names=["image_tensor:0"],
|
| 27 |
+
output_names=["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"],
|
| 28 |
+
opset=args.opset,
|
| 29 |
+
)
|
| 30 |
+
onnx.checker.check_model(model_proto)
|
| 31 |
+
|
| 32 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 33 |
+
onnx_path = "faster_rcnn_inception_v2_coco_2018_01_28_%s.onnx" % stamp
|
| 34 |
+
with open(onnx_path, "wb") as f:
|
| 35 |
+
f.write(model_proto.SerializeToString())
|
| 36 |
+
print("wrote", onnx_path)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
main()
|
faster_rcnn_inception_v2_coco_2018_01_28/demo.cpp
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <array>
|
| 5 |
+
#include <cstdint>
|
| 6 |
+
#include <iostream>
|
| 7 |
+
#include <string>
|
| 8 |
+
#include <vector>
|
| 9 |
+
|
| 10 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 11 |
+
{
|
| 12 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 13 |
+
if (key == argv[i]) return argv[i + 1];
|
| 14 |
+
return def;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
int main(int argc, char** argv)
|
| 18 |
+
{
|
| 19 |
+
std::string model = argVal(argc, argv, "--model", "faster_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx");
|
| 20 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 21 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 22 |
+
float conf = std::stof(argVal(argc, argv, "--conf", "0.3"));
|
| 23 |
+
|
| 24 |
+
cv::Mat img = cv::imread(image);
|
| 25 |
+
if (img.empty())
|
| 26 |
+
{
|
| 27 |
+
std::cerr << "could not read image: " << image << std::endl;
|
| 28 |
+
return 1;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
const int W = 800, H = 600;
|
| 32 |
+
cv::Mat rgb;
|
| 33 |
+
cv::cvtColor(img, rgb, cv::COLOR_BGR2RGB);
|
| 34 |
+
cv::resize(rgb, rgb, cv::Size(W, H));
|
| 35 |
+
if (!rgb.isContinuous()) rgb = rgb.clone();
|
| 36 |
+
|
| 37 |
+
int blobShape[] = {1, H, W, 3};
|
| 38 |
+
cv::Mat blob(4, blobShape, CV_8U, rgb.data);
|
| 39 |
+
cv::dnn::Net net = cv::dnn::readNetFromONNX(model, cv::dnn::ENGINE_ORT);
|
| 40 |
+
net.setInput(blob);
|
| 41 |
+
std::vector<cv::String> out_strs = {"detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"};
|
| 42 |
+
std::vector<cv::Mat> outs;
|
| 43 |
+
net.forward(outs, out_strs);
|
| 44 |
+
|
| 45 |
+
float* boxes = nullptr;
|
| 46 |
+
float* scores = nullptr;
|
| 47 |
+
float* classes = nullptr;
|
| 48 |
+
float* numd = nullptr;
|
| 49 |
+
for (size_t i = 0; i < out_strs.size(); ++i)
|
| 50 |
+
{
|
| 51 |
+
float* p = (float*)outs[i].data;
|
| 52 |
+
const std::string& n = out_strs[i];
|
| 53 |
+
if (n.find("detection_boxes") != std::string::npos) boxes = p;
|
| 54 |
+
else if (n.find("detection_scores") != std::string::npos) scores = p;
|
| 55 |
+
else if (n.find("detection_classes") != std::string::npos) classes = p;
|
| 56 |
+
else if (n.find("num_detections") != std::string::npos) numd = p;
|
| 57 |
+
}
|
| 58 |
+
int nd = (int)numd[0];
|
| 59 |
+
|
| 60 |
+
int w = img.cols, h = img.rows;
|
| 61 |
+
std::vector<int> kept;
|
| 62 |
+
for (int i = 0; i < nd; ++i)
|
| 63 |
+
if (scores[i] >= conf) kept.push_back(i);
|
| 64 |
+
|
| 65 |
+
std::cout << "faster_rcnn_inception_v2_coco_2018_01_28 " << kept.size() << " detections" << std::endl;
|
| 66 |
+
for (int i : kept)
|
| 67 |
+
{
|
| 68 |
+
int cls = (int)classes[i] - 1;
|
| 69 |
+
float score = scores[i];
|
| 70 |
+
float ymin = boxes[i * 4 + 0], xmin = boxes[i * 4 + 1];
|
| 71 |
+
float ymax = boxes[i * 4 + 2], xmax = boxes[i * 4 + 3];
|
| 72 |
+
cv::Point p1((int)(xmin * w), (int)(ymin * h));
|
| 73 |
+
cv::Point p2((int)(xmax * w), (int)(ymax * h));
|
| 74 |
+
cv::rectangle(img, p1, p2, cv::Scalar(0, 255, 0), 2);
|
| 75 |
+
cv::putText(img, cv::format("%d:%.2f", cls, score), cv::Point(p1.x, p1.y - 5),
|
| 76 |
+
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 1);
|
| 77 |
+
std::cout << cls << " " << cv::format("%.3f %.3f %.3f %.3f %.3f", score, xmin, ymin, xmax, ymax) << std::endl;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
cv::imwrite(output, img);
|
| 81 |
+
std::cout << "wrote " << output << std::endl;
|
| 82 |
+
return 0;
|
| 83 |
+
}
|
faster_rcnn_inception_v2_coco_2018_01_28/demo.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def main():
|
| 12 |
+
parser = argparse.ArgumentParser(description="Faster-RCNN InceptionV2 (COCO) ONNX detection demo")
|
| 13 |
+
parser.add_argument("--model", default=None)
|
| 14 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 15 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 16 |
+
parser.add_argument("--conf", type=float, default=0.3)
|
| 17 |
+
args = parser.parse_args()
|
| 18 |
+
|
| 19 |
+
model = args.model or glob.glob(os.path.join(here, "*.onnx"))[0]
|
| 20 |
+
img = cv.imread(args.image)
|
| 21 |
+
if img is None:
|
| 22 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 23 |
+
|
| 24 |
+
rgb = cv.resize(cv.cvtColor(img, cv.COLOR_BGR2RGB), (800, 600))
|
| 25 |
+
net = cv.dnn.readNetFromONNX(model, cv.dnn.ENGINE_ORT)
|
| 26 |
+
onames = ["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"]
|
| 27 |
+
net.setInput(rgb[None].astype(np.uint8))
|
| 28 |
+
res = net.forward(onames)
|
| 29 |
+
boxes = res[[i for i, n in enumerate(onames) if "detection_boxes" in n][0]].reshape(-1, 4)
|
| 30 |
+
scores = res[[i for i, n in enumerate(onames) if "detection_scores" in n][0]].reshape(-1)
|
| 31 |
+
classes = res[[i for i, n in enumerate(onames) if "detection_classes" in n][0]].reshape(-1)
|
| 32 |
+
nd = int(res[[i for i, n in enumerate(onames) if "num_detections" in n][0]].reshape(-1)[0])
|
| 33 |
+
|
| 34 |
+
out = np.zeros((nd, 7), np.float32)
|
| 35 |
+
out[:, 1] = classes[:nd] - 1
|
| 36 |
+
out[:, 2] = scores[:nd]
|
| 37 |
+
out[:, 3:7] = boxes[:nd][:, [1, 0, 3, 2]]
|
| 38 |
+
|
| 39 |
+
h, w = img.shape[:2]
|
| 40 |
+
kept = [row for row in out if row[2] >= args.conf]
|
| 41 |
+
print(os.path.basename(here), len(kept), "detections")
|
| 42 |
+
for row in kept:
|
| 43 |
+
cv.rectangle(img, (int(row[3] * w), int(row[4] * h)), (int(row[5] * w), int(row[6] * h)), (0, 255, 0), 2)
|
| 44 |
+
cv.putText(img, "%d:%.2f" % (int(row[1]), row[2]), (int(row[3] * w), int(row[4] * h) - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
| 45 |
+
print(int(row[1]), round(float(row[2]), 3), round(float(row[3]), 3), round(float(row[4]), 3), round(float(row[5]), 3), round(float(row[6]), 3))
|
| 46 |
+
cv.imwrite(args.output, img)
|
| 47 |
+
print("wrote", args.output)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
if __name__ == "__main__":
|
| 51 |
+
main()
|
faster_rcnn_inception_v2_coco_2018_01_28/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
faster_rcnn_inception_v2_coco_2018_01_28/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
faster_rcnn_inception_v2_coco_2018_01_28/faster_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bcf541da5a58e9d8ab6c16e4c803ccc4e0da7dd62ad89311ae2a75c36b39835b
|
| 3 |
+
size 57016094
|
faster_rcnn_resnet50_coco_2018_01_28/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2015 The TensorFlow 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 2015, The TensorFlow Authors.
|
| 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.
|
faster_rcnn_resnet50_coco_2018_01_28/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Faster-RCNN ResNet-50 (COCO)
|
| 2 |
+
|
| 3 |
+
Object detection with the Faster-RCNN meta-architecture and a ResNet-50 backbone,
|
| 4 |
+
trained on the COCO dataset. The model was originally distributed as a frozen TensorFlow
|
| 5 |
+
graph (`faster_rcnn_resnet50_coco_2018_01_28.pb`) from the TensorFlow Object Detection
|
| 6 |
+
API and converted to ONNX for inference with OpenCV's DNN module.
|
| 7 |
+
|
| 8 |
+
## Model Details
|
| 9 |
+
- **Architecture**: Faster-RCNN with a ResNet-50 backbone
|
| 10 |
+
- **Input**: RGB image, uint8, NHWC layout (`image_tensor:0`, shape `[1, H, W, 3]`)
|
| 11 |
+
- **Output**: `detection_boxes:0` (normalized `[ymin, xmin, ymax, xmax]`), `detection_scores:0`, `detection_classes:0` (1-based COCO ids), `num_detections:0`
|
| 12 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
|
| 13 |
+
- **Original weights**: http://download.tensorflow.org/models/object_detection/faster_rcnn_resnet50_coco_2018_01_28.tar.gz
|
| 14 |
+
|
| 15 |
+
## Usage
|
| 16 |
+
|
| 17 |
+
### Python
|
| 18 |
+
```bash
|
| 19 |
+
python demo.py --model faster_rcnn_resnet50_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.3
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
### C++
|
| 23 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 24 |
+
```bash
|
| 25 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 26 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 27 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 28 |
+
-I$OCV/include \
|
| 29 |
+
-I$OCV/modules/core/include \
|
| 30 |
+
-I$OCV/modules/dnn/include \
|
| 31 |
+
-I$OCV/modules/imgproc/include \
|
| 32 |
+
-I$OCV/modules/imgcodecs/include \
|
| 33 |
+
-I$OCVBUILD \
|
| 34 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 35 |
+
./demo --model faster_rcnn_resnet50_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
## Conversion
|
| 39 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18)
|
| 40 |
+
via [convert_to_onnx.py](./convert_to_onnx.py) — input `image_tensor:0`, outputs
|
| 41 |
+
`detection_boxes:0`, `detection_scores:0`, `detection_classes:0`, `num_detections:0`.
|
| 42 |
+
Requires `tensorflow`, `tf2onnx`, and `onnx`.
|
| 43 |
+
|
| 44 |
+
```bash
|
| 45 |
+
python convert_to_onnx.py --pb ../pb/faster_rcnn_resnet50_coco_2018_01_28.pb
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
## License
|
| 49 |
+
See [LICENSE](./LICENSE) — the model is released by the TensorFlow Authors under the Apache License 2.0.
|
faster_rcnn_resnet50_coco_2018_01_28/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import onnx
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def load_graph_def(pb_path):
|
| 10 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 11 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 12 |
+
graph_def.ParseFromString(f.read())
|
| 13 |
+
return graph_def
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser(description="Export faster_rcnn_resnet50_coco_2018_01_28.pb to ONNX")
|
| 18 |
+
parser.add_argument("--pb", default="../pb/faster_rcnn_resnet50_coco_2018_01_28.pb")
|
| 19 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 20 |
+
args = parser.parse_args()
|
| 21 |
+
|
| 22 |
+
graph_def = load_graph_def(args.pb)
|
| 23 |
+
|
| 24 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 25 |
+
graph_def,
|
| 26 |
+
input_names=["image_tensor:0"],
|
| 27 |
+
output_names=["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"],
|
| 28 |
+
opset=args.opset,
|
| 29 |
+
)
|
| 30 |
+
onnx.checker.check_model(model_proto)
|
| 31 |
+
|
| 32 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 33 |
+
onnx_path = "faster_rcnn_resnet50_coco_2018_01_28_%s.onnx" % stamp
|
| 34 |
+
with open(onnx_path, "wb") as f:
|
| 35 |
+
f.write(model_proto.SerializeToString())
|
| 36 |
+
print("wrote", onnx_path)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
main()
|
faster_rcnn_resnet50_coco_2018_01_28/demo.cpp
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <array>
|
| 5 |
+
#include <cstdint>
|
| 6 |
+
#include <iostream>
|
| 7 |
+
#include <string>
|
| 8 |
+
#include <vector>
|
| 9 |
+
|
| 10 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 11 |
+
{
|
| 12 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 13 |
+
if (key == argv[i]) return argv[i + 1];
|
| 14 |
+
return def;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
int main(int argc, char** argv)
|
| 18 |
+
{
|
| 19 |
+
std::string model = argVal(argc, argv, "--model", "faster_rcnn_resnet50_coco_2018_01_28_2026jul.onnx");
|
| 20 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 21 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 22 |
+
float conf = std::stof(argVal(argc, argv, "--conf", "0.3"));
|
| 23 |
+
|
| 24 |
+
cv::Mat img = cv::imread(image);
|
| 25 |
+
if (img.empty())
|
| 26 |
+
{
|
| 27 |
+
std::cerr << "could not read image: " << image << std::endl;
|
| 28 |
+
return 1;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
const int W = 800, H = 600;
|
| 32 |
+
cv::Mat rgb;
|
| 33 |
+
cv::cvtColor(img, rgb, cv::COLOR_BGR2RGB);
|
| 34 |
+
cv::resize(rgb, rgb, cv::Size(W, H));
|
| 35 |
+
if (!rgb.isContinuous()) rgb = rgb.clone();
|
| 36 |
+
|
| 37 |
+
int blobShape[] = {1, H, W, 3};
|
| 38 |
+
cv::Mat blob(4, blobShape, CV_8U, rgb.data);
|
| 39 |
+
cv::dnn::Net net = cv::dnn::readNetFromONNX(model, cv::dnn::ENGINE_ORT);
|
| 40 |
+
net.setInput(blob);
|
| 41 |
+
std::vector<cv::String> out_strs = {"detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"};
|
| 42 |
+
std::vector<cv::Mat> outs;
|
| 43 |
+
net.forward(outs, out_strs);
|
| 44 |
+
|
| 45 |
+
float* boxes = nullptr;
|
| 46 |
+
float* scores = nullptr;
|
| 47 |
+
float* classes = nullptr;
|
| 48 |
+
float* numd = nullptr;
|
| 49 |
+
for (size_t i = 0; i < out_strs.size(); ++i)
|
| 50 |
+
{
|
| 51 |
+
float* p = (float*)outs[i].data;
|
| 52 |
+
const std::string& n = out_strs[i];
|
| 53 |
+
if (n.find("detection_boxes") != std::string::npos) boxes = p;
|
| 54 |
+
else if (n.find("detection_scores") != std::string::npos) scores = p;
|
| 55 |
+
else if (n.find("detection_classes") != std::string::npos) classes = p;
|
| 56 |
+
else if (n.find("num_detections") != std::string::npos) numd = p;
|
| 57 |
+
}
|
| 58 |
+
int nd = (int)numd[0];
|
| 59 |
+
|
| 60 |
+
int w = img.cols, h = img.rows;
|
| 61 |
+
std::vector<int> kept;
|
| 62 |
+
for (int i = 0; i < nd; ++i)
|
| 63 |
+
if (scores[i] >= conf) kept.push_back(i);
|
| 64 |
+
|
| 65 |
+
std::cout << "faster_rcnn_resnet50_coco_2018_01_28 " << kept.size() << " detections" << std::endl;
|
| 66 |
+
for (int i : kept)
|
| 67 |
+
{
|
| 68 |
+
int cls = (int)classes[i] - 1;
|
| 69 |
+
float score = scores[i];
|
| 70 |
+
float ymin = boxes[i * 4 + 0], xmin = boxes[i * 4 + 1];
|
| 71 |
+
float ymax = boxes[i * 4 + 2], xmax = boxes[i * 4 + 3];
|
| 72 |
+
cv::Point p1((int)(xmin * w), (int)(ymin * h));
|
| 73 |
+
cv::Point p2((int)(xmax * w), (int)(ymax * h));
|
| 74 |
+
cv::rectangle(img, p1, p2, cv::Scalar(0, 255, 0), 2);
|
| 75 |
+
cv::putText(img, cv::format("%d:%.2f", cls, score), cv::Point(p1.x, p1.y - 5),
|
| 76 |
+
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 1);
|
| 77 |
+
std::cout << cls << " " << cv::format("%.3f %.3f %.3f %.3f %.3f", score, xmin, ymin, xmax, ymax) << std::endl;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
cv::imwrite(output, img);
|
| 81 |
+
std::cout << "wrote " << output << std::endl;
|
| 82 |
+
return 0;
|
| 83 |
+
}
|
faster_rcnn_resnet50_coco_2018_01_28/demo.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def main():
|
| 12 |
+
parser = argparse.ArgumentParser(description="Faster-RCNN ResNet-50 (COCO) ONNX detection demo")
|
| 13 |
+
parser.add_argument("--model", default=None)
|
| 14 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 15 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 16 |
+
parser.add_argument("--conf", type=float, default=0.3)
|
| 17 |
+
args = parser.parse_args()
|
| 18 |
+
|
| 19 |
+
model = args.model or glob.glob(os.path.join(here, "*.onnx"))[0]
|
| 20 |
+
img = cv.imread(args.image)
|
| 21 |
+
if img is None:
|
| 22 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 23 |
+
|
| 24 |
+
rgb = cv.resize(cv.cvtColor(img, cv.COLOR_BGR2RGB), (800, 600))
|
| 25 |
+
net = cv.dnn.readNetFromONNX(model, cv.dnn.ENGINE_ORT)
|
| 26 |
+
onames = ["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"]
|
| 27 |
+
net.setInput(rgb[None].astype(np.uint8))
|
| 28 |
+
res = net.forward(onames)
|
| 29 |
+
boxes = res[[i for i, n in enumerate(onames) if "detection_boxes" in n][0]].reshape(-1, 4)
|
| 30 |
+
scores = res[[i for i, n in enumerate(onames) if "detection_scores" in n][0]].reshape(-1)
|
| 31 |
+
classes = res[[i for i, n in enumerate(onames) if "detection_classes" in n][0]].reshape(-1)
|
| 32 |
+
nd = int(res[[i for i, n in enumerate(onames) if "num_detections" in n][0]].reshape(-1)[0])
|
| 33 |
+
|
| 34 |
+
out = np.zeros((nd, 7), np.float32)
|
| 35 |
+
out[:, 1] = classes[:nd] - 1
|
| 36 |
+
out[:, 2] = scores[:nd]
|
| 37 |
+
out[:, 3:7] = boxes[:nd][:, [1, 0, 3, 2]]
|
| 38 |
+
|
| 39 |
+
h, w = img.shape[:2]
|
| 40 |
+
kept = [row for row in out if row[2] >= args.conf]
|
| 41 |
+
print(os.path.basename(here), len(kept), "detections")
|
| 42 |
+
for row in kept:
|
| 43 |
+
cv.rectangle(img, (int(row[3] * w), int(row[4] * h)), (int(row[5] * w), int(row[6] * h)), (0, 255, 0), 2)
|
| 44 |
+
cv.putText(img, "%d:%.2f" % (int(row[1]), row[2]), (int(row[3] * w), int(row[4] * h) - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
| 45 |
+
print(int(row[1]), round(float(row[2]), 3), round(float(row[3]), 3), round(float(row[4]), 3), round(float(row[5]), 3), round(float(row[6]), 3))
|
| 46 |
+
cv.imwrite(args.output, img)
|
| 47 |
+
print("wrote", args.output)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
if __name__ == "__main__":
|
| 51 |
+
main()
|
faster_rcnn_resnet50_coco_2018_01_28/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
faster_rcnn_resnet50_coco_2018_01_28/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
faster_rcnn_resnet50_coco_2018_01_28/faster_rcnn_resnet50_coco_2018_01_28_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:217613103b36eba4771087bdae63a7c04ed545e7850087f205990db7e5f18b88
|
| 3 |
+
size 120414387
|
mask_rcnn_inception_v2_coco_2018_01_28/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2015 The TensorFlow 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 2015, The TensorFlow Authors.
|
| 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.
|
mask_rcnn_inception_v2_coco_2018_01_28/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Mask-RCNN Inception v2 COCO
|
| 2 |
+
|
| 3 |
+
Instance segmentation with the Mask-RCNN Inception v2 network trained on the COCO dataset.
|
| 4 |
+
The model was originally distributed as a frozen TensorFlow graph
|
| 5 |
+
(`mask_rcnn_inception_v2_coco_2018_01_28.pb`) from the TensorFlow Object Detection API
|
| 6 |
+
and converted to ONNX for use with OpenCV's DNN module.
|
| 7 |
+
|
| 8 |
+
## Model Details
|
| 9 |
+
- **Architecture**: Mask-RCNN with an Inception v2 backbone
|
| 10 |
+
- **Input**: RGB image, uint8, NHWC layout (`image_tensor:0`); the demo resizes to 800×800
|
| 11 |
+
- **Output**: `num_detections:0`, `detection_boxes:0` (normalized `[ymin, xmin, ymax, xmax]`),
|
| 12 |
+
`detection_scores:0`, `detection_classes:0` (COCO ids, subtract 1 for a 0-based label),
|
| 13 |
+
and `detection_masks:0` (a 15×15 mask per detection, resized to its box)
|
| 14 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
|
| 15 |
+
- **Original weights**: http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
|
| 16 |
+
|
| 17 |
+
## Usage
|
| 18 |
+
|
| 19 |
+
### Python
|
| 20 |
+
```bash
|
| 21 |
+
python demo.py --model mask_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.3
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
### C++
|
| 25 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 26 |
+
```bash
|
| 27 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 28 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 29 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 30 |
+
-I$OCV/include \
|
| 31 |
+
-I$OCV/modules/core/include \
|
| 32 |
+
-I$OCV/modules/dnn/include \
|
| 33 |
+
-I$OCV/modules/imgproc/include \
|
| 34 |
+
-I$OCV/modules/imgcodecs/include \
|
| 35 |
+
-I$OCVBUILD \
|
| 36 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 37 |
+
./demo --model mask_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
## Conversion
|
| 41 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18)
|
| 42 |
+
via [convert_to_onnx.py](./convert_to_onnx.py) — input `image_tensor:0`, outputs
|
| 43 |
+
`num_detections:0`, `detection_boxes:0`, `detection_scores:0`, `detection_classes:0`,
|
| 44 |
+
and `detection_masks:0`. Requires `tensorflow`, `tf2onnx`, and `onnx`.
|
| 45 |
+
|
| 46 |
+
```bash
|
| 47 |
+
python convert_to_onnx.py --pb ../pb/mask_rcnn_inception_v2_coco_2018_01_28.pb
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
## License
|
| 51 |
+
See [LICENSE](./LICENSE) — the model is released by the TensorFlow Authors under the Apache License 2.0.
|
mask_rcnn_inception_v2_coco_2018_01_28/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import onnx
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def load_graph_def(pb_path):
|
| 10 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 11 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 12 |
+
graph_def.ParseFromString(f.read())
|
| 13 |
+
return graph_def
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser(description="Export mask_rcnn_inception_v2_coco_2018_01_28.pb to ONNX")
|
| 18 |
+
parser.add_argument("--pb", default="../pb/mask_rcnn_inception_v2_coco_2018_01_28.pb")
|
| 19 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 20 |
+
args = parser.parse_args()
|
| 21 |
+
|
| 22 |
+
graph_def = load_graph_def(args.pb)
|
| 23 |
+
|
| 24 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 25 |
+
graph_def,
|
| 26 |
+
input_names=["image_tensor:0"],
|
| 27 |
+
output_names=[
|
| 28 |
+
"num_detections:0",
|
| 29 |
+
"detection_boxes:0",
|
| 30 |
+
"detection_scores:0",
|
| 31 |
+
"detection_classes:0",
|
| 32 |
+
"detection_masks:0",
|
| 33 |
+
],
|
| 34 |
+
opset=args.opset,
|
| 35 |
+
)
|
| 36 |
+
onnx.checker.check_model(model_proto)
|
| 37 |
+
|
| 38 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 39 |
+
onnx_path = "mask_rcnn_inception_v2_coco_2018_01_28_%s.onnx" % stamp
|
| 40 |
+
with open(onnx_path, "wb") as f:
|
| 41 |
+
f.write(model_proto.SerializeToString())
|
| 42 |
+
print("wrote", onnx_path)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
if __name__ == "__main__":
|
| 46 |
+
main()
|
mask_rcnn_inception_v2_coco_2018_01_28/demo.cpp
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <algorithm>
|
| 5 |
+
#include <array>
|
| 6 |
+
#include <cstdint>
|
| 7 |
+
#include <iostream>
|
| 8 |
+
#include <string>
|
| 9 |
+
#include <vector>
|
| 10 |
+
|
| 11 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 12 |
+
{
|
| 13 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 14 |
+
if (key == argv[i]) return argv[i + 1];
|
| 15 |
+
return def;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
int main(int argc, char** argv)
|
| 19 |
+
{
|
| 20 |
+
std::string model = argVal(argc, argv, "--model", "mask_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx");
|
| 21 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 22 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 23 |
+
float conf = std::stof(argVal(argc, argv, "--conf", "0.3"));
|
| 24 |
+
|
| 25 |
+
cv::Mat img = cv::imread(image);
|
| 26 |
+
if (img.empty())
|
| 27 |
+
{
|
| 28 |
+
std::cerr << "could not read image: " << image << std::endl;
|
| 29 |
+
return 1;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
const int W = 800, H = 800;
|
| 33 |
+
cv::Mat rgb;
|
| 34 |
+
cv::cvtColor(img, rgb, cv::COLOR_BGR2RGB);
|
| 35 |
+
cv::resize(rgb, rgb, cv::Size(W, H));
|
| 36 |
+
if (!rgb.isContinuous()) rgb = rgb.clone();
|
| 37 |
+
|
| 38 |
+
int blobShape[] = {1, H, W, 3};
|
| 39 |
+
cv::Mat blob(4, blobShape, CV_8U, rgb.data);
|
| 40 |
+
cv::dnn::Net net = cv::dnn::readNetFromONNX(model, cv::dnn::ENGINE_ORT);
|
| 41 |
+
net.setInput(blob);
|
| 42 |
+
std::vector<cv::String> out_strs = {"num_detections:0", "detection_boxes:0", "detection_scores:0", "detection_classes:0", "detection_masks:0"};
|
| 43 |
+
std::vector<cv::Mat> outs;
|
| 44 |
+
net.forward(outs, out_strs);
|
| 45 |
+
|
| 46 |
+
float* boxes = nullptr;
|
| 47 |
+
float* scores = nullptr;
|
| 48 |
+
float* classes = nullptr;
|
| 49 |
+
float* numd = nullptr;
|
| 50 |
+
float* masks = nullptr;
|
| 51 |
+
for (size_t i = 0; i < out_strs.size(); ++i)
|
| 52 |
+
{
|
| 53 |
+
float* p = (float*)outs[i].data;
|
| 54 |
+
const std::string& n = out_strs[i];
|
| 55 |
+
if (n.find("detection_boxes") != std::string::npos) boxes = p;
|
| 56 |
+
else if (n.find("detection_scores") != std::string::npos) scores = p;
|
| 57 |
+
else if (n.find("detection_classes") != std::string::npos) classes = p;
|
| 58 |
+
else if (n.find("num_detections") != std::string::npos) numd = p;
|
| 59 |
+
else if (n.find("detection_masks") != std::string::npos) masks = p;
|
| 60 |
+
}
|
| 61 |
+
int nd = (int)numd[0];
|
| 62 |
+
|
| 63 |
+
int w = img.cols, h = img.rows;
|
| 64 |
+
cv::Mat out = img.clone();
|
| 65 |
+
std::vector<int> kept;
|
| 66 |
+
for (int i = 0; i < nd; ++i)
|
| 67 |
+
if (scores[i] >= conf) kept.push_back(i);
|
| 68 |
+
|
| 69 |
+
std::cout << "mask_rcnn_inception_v2_coco_2018_01_28 " << kept.size() << " detections" << std::endl;
|
| 70 |
+
for (int i : kept)
|
| 71 |
+
{
|
| 72 |
+
int cls = (int)classes[i] - 1;
|
| 73 |
+
float score = scores[i];
|
| 74 |
+
float y1 = boxes[i * 4 + 0], x1 = boxes[i * 4 + 1];
|
| 75 |
+
float y2 = boxes[i * 4 + 2], x2 = boxes[i * 4 + 3];
|
| 76 |
+
int px1 = std::max(0, (int)(x1 * w)), py1 = std::max(0, (int)(y1 * h));
|
| 77 |
+
int px2 = std::min(w, (int)(x2 * w)), py2 = std::min(h, (int)(y2 * h));
|
| 78 |
+
|
| 79 |
+
unsigned s = (unsigned)i * 2654435761u + 1u;
|
| 80 |
+
int col[3];
|
| 81 |
+
for (int c = 0; c < 3; ++c) { s = s * 1664525u + 1013904223u; col[c] = 80 + (int)((s >> 8) % 176u); }
|
| 82 |
+
cv::Scalar color(col[0], col[1], col[2]);
|
| 83 |
+
|
| 84 |
+
if (px2 > px1 && py2 > py1)
|
| 85 |
+
{
|
| 86 |
+
cv::Mat m15(15, 15, CV_32F, masks + (size_t)i * 225);
|
| 87 |
+
cv::Mat mr;
|
| 88 |
+
cv::resize(m15, mr, cv::Size(px2 - px1, py2 - py1));
|
| 89 |
+
cv::Mat roi = out(cv::Rect(px1, py1, px2 - px1, py2 - py1));
|
| 90 |
+
for (int y = 0; y < roi.rows; ++y)
|
| 91 |
+
{
|
| 92 |
+
cv::Vec3b* rp = roi.ptr<cv::Vec3b>(y);
|
| 93 |
+
const float* mp = mr.ptr<float>(y);
|
| 94 |
+
for (int x = 0; x < roi.cols; ++x)
|
| 95 |
+
if (mp[x] > 0.5f)
|
| 96 |
+
for (int c = 0; c < 3; ++c)
|
| 97 |
+
rp[x][c] = (uchar)(0.5 * rp[x][c] + 0.5 * col[c]);
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
cv::rectangle(out, cv::Point(px1, py1), cv::Point(px2, py2), color, 2);
|
| 101 |
+
cv::putText(out, cv::format("%d:%.2f", cls, score), cv::Point(px1, py1 - 5),
|
| 102 |
+
cv::FONT_HERSHEY_SIMPLEX, 0.5, color, 1);
|
| 103 |
+
std::cout << cls << " " << cv::format("%.3f %.3f %.3f %.3f %.3f", score, x1, y1, x2, y2) << std::endl;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
cv::imwrite(output, out);
|
| 107 |
+
std::cout << "wrote " << output << std::endl;
|
| 108 |
+
return 0;
|
| 109 |
+
}
|
mask_rcnn_inception_v2_coco_2018_01_28/demo.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def main():
|
| 12 |
+
parser = argparse.ArgumentParser(description="Mask-RCNN Inception v2 COCO (OpenCV DNN) detection + mask demo")
|
| 13 |
+
found = glob.glob(os.path.join(here, "*.onnx"))
|
| 14 |
+
parser.add_argument("--model", default=found[0] if found else None)
|
| 15 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 16 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 17 |
+
parser.add_argument("--conf", type=float, default=0.3)
|
| 18 |
+
args = parser.parse_args()
|
| 19 |
+
|
| 20 |
+
img = cv.imread(args.image)
|
| 21 |
+
if img is None:
|
| 22 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 23 |
+
|
| 24 |
+
net = cv.dnn.readNetFromONNX(args.model, cv.dnn.ENGINE_ORT)
|
| 25 |
+
rgb = cv.resize(cv.cvtColor(img, cv.COLOR_BGR2RGB), (800, 800))
|
| 26 |
+
onames = ["num_detections:0", "detection_boxes:0", "detection_scores:0", "detection_classes:0", "detection_masks:0"]
|
| 27 |
+
net.setInput(rgb[None].astype(np.uint8))
|
| 28 |
+
res = net.forward(onames)
|
| 29 |
+
boxes = res[[i for i, n in enumerate(onames) if "detection_boxes" in n][0]].reshape(-1, 4)
|
| 30 |
+
scores = res[[i for i, n in enumerate(onames) if "detection_scores" in n][0]].reshape(-1)
|
| 31 |
+
classes = res[[i for i, n in enumerate(onames) if "detection_classes" in n][0]].reshape(-1)
|
| 32 |
+
nd = int(res[[i for i, n in enumerate(onames) if "num_detections" in n][0]].reshape(-1)[0])
|
| 33 |
+
masks = res[[i for i, n in enumerate(onames) if "detection_masks" in n][0]].reshape(-1, 15, 15)
|
| 34 |
+
|
| 35 |
+
h, w = img.shape[:2]
|
| 36 |
+
out = img.copy()
|
| 37 |
+
kept = [i for i in range(nd) if scores[i] >= args.conf]
|
| 38 |
+
print("mask_rcnn_inception_v2_coco_2018_01_28", len(kept), "detections")
|
| 39 |
+
for i in kept:
|
| 40 |
+
cls = int(classes[i]) - 1
|
| 41 |
+
score = float(scores[i])
|
| 42 |
+
y1, x1, y2, x2 = boxes[i]
|
| 43 |
+
px1, py1 = max(0, int(x1 * w)), max(0, int(y1 * h))
|
| 44 |
+
px2, py2 = min(w, int(x2 * w)), min(h, int(y2 * h))
|
| 45 |
+
color = tuple(int(c) for c in np.random.default_rng(i).integers(80, 256, 3))
|
| 46 |
+
if px2 > px1 and py2 > py1:
|
| 47 |
+
m = cv.resize(masks[i], (px2 - px1, py2 - py1)) > 0.5
|
| 48 |
+
roi = out[py1:py2, px1:px2]
|
| 49 |
+
roi[m] = (0.5 * roi[m] + 0.5 * np.array(color)).astype(np.uint8)
|
| 50 |
+
cv.rectangle(out, (px1, py1), (px2, py2), color, 2)
|
| 51 |
+
cv.putText(out, "%d:%.2f" % (cls, score), (px1, py1 - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
|
| 52 |
+
print(cls, round(score, 3), round(float(x1), 3), round(float(y1), 3), round(float(x2), 3), round(float(y2), 3))
|
| 53 |
+
|
| 54 |
+
cv.imwrite(args.output, out)
|
| 55 |
+
print("wrote", args.output)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
if __name__ == "__main__":
|
| 59 |
+
main()
|
mask_rcnn_inception_v2_coco_2018_01_28/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
mask_rcnn_inception_v2_coco_2018_01_28/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
mask_rcnn_inception_v2_coco_2018_01_28/mask_rcnn_inception_v2_coco_2018_01_28_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:27cdd89df33ab94f61fd278350f66996efec3437937b5679a311ba55e386690f
|
| 3 |
+
size 66728941
|
opencv_face_detector_uint8/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) OpenCV team and the opencv_3rdparty contributors. 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 (c) OpenCV team and the opencv_3rdparty contributors.
|
| 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.
|
opencv_face_detector_uint8/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# OpenCV SSD Face Detector (UINT8)
|
| 2 |
+
|
| 3 |
+
Single-shot face detection with the OpenCV SSD ResNet-10 network. The model ships in the
|
| 4 |
+
OpenCV project as a quantized frozen TensorFlow graph (`opencv_face_detector_uint8.pb`) and is
|
| 5 |
+
converted here to ONNX for use with OpenCV's DNN module. Only the backbone is
|
| 6 |
+
exported — PriorBox generation, the confidence softmax, variance decode, score threshold and NMS
|
| 7 |
+
are run in host code (see `demo.py` / `demo.cpp`).
|
| 8 |
+
|
| 9 |
+
## Model Details
|
| 10 |
+
- **Architecture**: SSD with a ResNet-10 backbone (face detector)
|
| 11 |
+
- **Input**: BGR image, 300×300, mean-subtracted by `[104, 177, 123]` (no scaling, no RGB swap),
|
| 12 |
+
NHWC layout (`data:0`, shape `[1, 300, 300, 3]`)
|
| 13 |
+
- **Output**: `mbox_loc` (`[1, 35568]`, box regressions) and `mbox_conf_flatten`
|
| 14 |
+
(`[1, 17784]`, 2-class face/background logits); PriorBox decode + softmax + NMS are done in the demo
|
| 15 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph — uint8 weights with the
|
| 16 |
+
`Dequantize` nodes folded to float `Const` — via tf2onnx, opset 18)
|
| 17 |
+
- **Original weights**: https://github.com/opencv/opencv_3rdparty/raw/8033c2bc31b3256f0d461c919ecc01c2428ca03b/opencv_face_detector_uint8.pb
|
| 18 |
+
|
| 19 |
+
The 6 SSD prior layers (min/max size, aspect ratios, step, feature-map size), the variances
|
| 20 |
+
`[0.1, 0.1, 0.2, 0.2]`, the default confidence threshold `0.4` and the NMS IoU `0.3` are all
|
| 21 |
+
defined in the demo scripts.
|
| 22 |
+
|
| 23 |
+
## Usage
|
| 24 |
+
|
| 25 |
+
### Python
|
| 26 |
+
```bash
|
| 27 |
+
python demo.py --model opencv_face_detector_uint8_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.4
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
Or import directly:
|
| 31 |
+
```python
|
| 32 |
+
import cv2
|
| 33 |
+
|
| 34 |
+
net = cv2.dnn.readNet("opencv_face_detector_uint8_2026jul.onnx")
|
| 35 |
+
# see demo.py for the full PriorBox decode + softmax + NMS pipeline
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
### C++
|
| 39 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 40 |
+
```bash
|
| 41 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 42 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 43 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 44 |
+
-I$OCV/include \
|
| 45 |
+
-I$OCV/modules/core/include \
|
| 46 |
+
-I$OCV/modules/dnn/include \
|
| 47 |
+
-I$OCV/modules/imgproc/include \
|
| 48 |
+
-I$OCV/modules/imgcodecs/include \
|
| 49 |
+
-I$OCVBUILD \
|
| 50 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 51 |
+
./demo --model opencv_face_detector_uint8_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
## Conversion
|
| 55 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18) via
|
| 56 |
+
[convert_to_onnx.py](./convert_to_onnx.py). The `.pb` stores its weights behind `Dequantize`
|
| 57 |
+
nodes, so the script first folds every `Dequantize` node to a float `Const` before conversion.
|
| 58 |
+
Inputs `data:0`, outputs `mbox_loc:0` and `mbox_conf_flatten:0`, input shape overridden to
|
| 59 |
+
`[1, 300, 300, 3]`. Requires `tensorflow`, `tf2onnx`, and `onnx`.
|
| 60 |
+
|
| 61 |
+
```bash
|
| 62 |
+
python convert_to_onnx.py --pb ../pb/opencv_face_detector_uint8.pb
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
## License
|
| 66 |
+
See [LICENSE](./LICENSE) — this is the OpenCV face detector distributed via `opencv_3rdparty`
|
| 67 |
+
under the Apache License 2.0.
|
opencv_face_detector_uint8/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
import onnx
|
| 8 |
+
from tensorflow.python.framework import graph_util, tensor_util
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def dequantize(graph_def, outputs):
|
| 12 |
+
dmin = {n.name: n.input[1] for n in graph_def.node if n.op == "Dequantize"}
|
| 13 |
+
folded = {}
|
| 14 |
+
with tf.Graph().as_default() as g:
|
| 15 |
+
tf.import_graph_def(graph_def, name="")
|
| 16 |
+
deq = list(dmin)
|
| 17 |
+
with tf.compat.v1.Session(graph=g) as sess:
|
| 18 |
+
for name in deq:
|
| 19 |
+
v = np.asarray(sess.run(g.get_tensor_by_name(name + ":0")), np.float32)
|
| 20 |
+
if not np.isfinite(v).all():
|
| 21 |
+
mn = np.float32(sess.run(g.get_tensor_by_name(dmin[name] + ":0")))
|
| 22 |
+
v = np.full(v.shape, mn, np.float32)
|
| 23 |
+
folded[name] = v
|
| 24 |
+
new = tf.compat.v1.GraphDef()
|
| 25 |
+
for n in graph_def.node:
|
| 26 |
+
if n.op == "Dequantize":
|
| 27 |
+
v = folded[n.name]
|
| 28 |
+
c = new.node.add()
|
| 29 |
+
c.op = "Const"
|
| 30 |
+
c.name = n.name
|
| 31 |
+
c.attr["dtype"].type = tf.float32.as_datatype_enum
|
| 32 |
+
c.attr["value"].tensor.CopyFrom(tensor_util.make_tensor_proto(v, tf.float32, v.shape))
|
| 33 |
+
else:
|
| 34 |
+
new.node.add().CopyFrom(n)
|
| 35 |
+
return graph_util.extract_sub_graph(new, [o.split(":")[0] for o in outputs])
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def load_graph_def(pb_path):
|
| 39 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 40 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 41 |
+
graph_def.ParseFromString(f.read())
|
| 42 |
+
return graph_def
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def main():
|
| 46 |
+
parser = argparse.ArgumentParser(description="Export opencv_face_detector_uint8.pb (backbone) to ONNX")
|
| 47 |
+
parser.add_argument("--pb", default="../pb/opencv_face_detector_uint8.pb")
|
| 48 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 49 |
+
args = parser.parse_args()
|
| 50 |
+
|
| 51 |
+
output_names = ["mbox_loc:0", "mbox_conf_flatten:0"]
|
| 52 |
+
|
| 53 |
+
graph_def = load_graph_def(args.pb)
|
| 54 |
+
graph_def = dequantize(graph_def, output_names)
|
| 55 |
+
|
| 56 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 57 |
+
graph_def,
|
| 58 |
+
input_names=["data:0"],
|
| 59 |
+
output_names=output_names,
|
| 60 |
+
opset=args.opset,
|
| 61 |
+
shape_override={"data:0": [1, 300, 300, 3]},
|
| 62 |
+
)
|
| 63 |
+
onnx.checker.check_model(model_proto)
|
| 64 |
+
|
| 65 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 66 |
+
onnx_path = "opencv_face_detector_uint8_%s.onnx" % stamp
|
| 67 |
+
with open(onnx_path, "wb") as f:
|
| 68 |
+
f.write(model_proto.SerializeToString())
|
| 69 |
+
print("wrote", onnx_path)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
if __name__ == "__main__":
|
| 73 |
+
main()
|
opencv_face_detector_uint8/demo.cpp
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <algorithm>
|
| 5 |
+
#include <array>
|
| 6 |
+
#include <cmath>
|
| 7 |
+
#include <iostream>
|
| 8 |
+
#include <string>
|
| 9 |
+
#include <vector>
|
| 10 |
+
|
| 11 |
+
using namespace cv;
|
| 12 |
+
|
| 13 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 14 |
+
{
|
| 15 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 16 |
+
if (key == argv[i]) return argv[i + 1];
|
| 17 |
+
return def;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
struct Layer { float mn, mx; std::vector<int> ars; int step, fm; };
|
| 21 |
+
|
| 22 |
+
int main(int argc, char** argv)
|
| 23 |
+
{
|
| 24 |
+
std::string model = argVal(argc, argv, "--model", "opencv_face_detector_uint8_2026jul.onnx");
|
| 25 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 26 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 27 |
+
float thr = std::stof(argVal(argc, argv, "--conf", "0.4"));
|
| 28 |
+
|
| 29 |
+
const int sz = 300;
|
| 30 |
+
Mat img = imread(image);
|
| 31 |
+
if (img.empty())
|
| 32 |
+
{
|
| 33 |
+
std::cerr << "could not read image: " << image << std::endl;
|
| 34 |
+
return 1;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
Mat inp;
|
| 38 |
+
resize(img, inp, Size(sz, sz));
|
| 39 |
+
inp.convertTo(inp, CV_32F);
|
| 40 |
+
subtract(inp, Scalar(104, 177, 123), inp);
|
| 41 |
+
if (!inp.isContinuous()) inp = inp.clone();
|
| 42 |
+
|
| 43 |
+
int blobShape[] = {1, sz, sz, 3};
|
| 44 |
+
Mat blob(4, blobShape, CV_32F, inp.data);
|
| 45 |
+
dnn::Net net = dnn::readNetFromONNX(model);
|
| 46 |
+
net.setInput(blob);
|
| 47 |
+
std::vector<Mat> outs;
|
| 48 |
+
net.forward(outs, net.getUnconnectedOutLayersNames());
|
| 49 |
+
|
| 50 |
+
const float* loc = nullptr;
|
| 51 |
+
const float* conf = nullptr;
|
| 52 |
+
for (size_t i = 0; i < outs.size(); ++i)
|
| 53 |
+
{
|
| 54 |
+
const Mat& o = outs[i];
|
| 55 |
+
size_t tot = o.total();
|
| 56 |
+
const float* p = (const float*)o.data;
|
| 57 |
+
if (tot == 35568) loc = p;
|
| 58 |
+
else if (tot == 17784) conf = p;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
std::vector<Layer> layers = {
|
| 62 |
+
{30, 60, {2}, 8, 38},
|
| 63 |
+
{60, 111, {2, 3}, 16, 19},
|
| 64 |
+
{111, 162, {2, 3}, 32, 10},
|
| 65 |
+
{162, 213, {2, 3}, 64, 5},
|
| 66 |
+
{213, 264, {2}, 100, 5},
|
| 67 |
+
{264, 315, {2}, 300, 5},
|
| 68 |
+
};
|
| 69 |
+
std::vector<Vec4f> priors;
|
| 70 |
+
for (const Layer& L : layers)
|
| 71 |
+
{
|
| 72 |
+
std::vector<float> ratios = {1.0f};
|
| 73 |
+
for (int a : L.ars) { ratios.push_back((float)a); ratios.push_back(1.0f / a); }
|
| 74 |
+
for (int y = 0; y < L.fm; ++y)
|
| 75 |
+
for (int x = 0; x < L.fm; ++x)
|
| 76 |
+
{
|
| 77 |
+
float cx = (x + 0.5f) * L.step;
|
| 78 |
+
float cy = (y + 0.5f) * L.step;
|
| 79 |
+
std::vector<Vec2f> boxes = {{L.mn, L.mn}, {std::sqrt(L.mn * L.mx), std::sqrt(L.mn * L.mx)}};
|
| 80 |
+
for (size_t k = 1; k < ratios.size(); ++k)
|
| 81 |
+
{
|
| 82 |
+
float a = ratios[k];
|
| 83 |
+
boxes.push_back({L.mn * std::sqrt(a), L.mn / std::sqrt(a)});
|
| 84 |
+
}
|
| 85 |
+
for (const Vec2f& b : boxes)
|
| 86 |
+
priors.push_back({cx, cy, b[0], b[1]});
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
const float var[4] = {0.1f, 0.1f, 0.2f, 0.2f};
|
| 91 |
+
int n = (int)priors.size();
|
| 92 |
+
std::vector<Rect2f> boxes;
|
| 93 |
+
std::vector<float> scores;
|
| 94 |
+
for (int i = 0; i < n; ++i)
|
| 95 |
+
{
|
| 96 |
+
float c0 = conf[i * 2], c1 = conf[i * 2 + 1];
|
| 97 |
+
float m = std::max(c0, c1);
|
| 98 |
+
float e0 = std::exp(c0 - m), e1 = std::exp(c1 - m);
|
| 99 |
+
float s = e1 / (e0 + e1);
|
| 100 |
+
if (s <= thr) continue;
|
| 101 |
+
float pcx = priors[i][0] / sz, pcy = priors[i][1] / sz;
|
| 102 |
+
float pw = priors[i][2] / sz, ph = priors[i][3] / sz;
|
| 103 |
+
float cx = pcx + loc[i * 4] * var[0] * pw;
|
| 104 |
+
float cy = pcy + loc[i * 4 + 1] * var[1] * ph;
|
| 105 |
+
float bw = pw * std::exp(loc[i * 4 + 2] * var[2]);
|
| 106 |
+
float bh = ph * std::exp(loc[i * 4 + 3] * var[3]);
|
| 107 |
+
boxes.push_back(Rect2f(cx - bw / 2, cy - bh / 2, bw, bh));
|
| 108 |
+
scores.push_back(s);
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
std::vector<int> order(scores.size());
|
| 112 |
+
for (size_t i = 0; i < order.size(); ++i) order[i] = (int)i;
|
| 113 |
+
std::sort(order.begin(), order.end(), [&](int a, int b){ return scores[a] > scores[b]; });
|
| 114 |
+
std::vector<char> removed(order.size(), 0);
|
| 115 |
+
std::vector<int> pick;
|
| 116 |
+
for (size_t oi = 0; oi < order.size(); ++oi)
|
| 117 |
+
{
|
| 118 |
+
if (removed[oi]) continue;
|
| 119 |
+
int i = order[oi];
|
| 120 |
+
pick.push_back(i);
|
| 121 |
+
for (size_t oj = oi + 1; oj < order.size(); ++oj)
|
| 122 |
+
{
|
| 123 |
+
if (removed[oj]) continue;
|
| 124 |
+
int j = order[oj];
|
| 125 |
+
const Rect2f& a = boxes[i];
|
| 126 |
+
const Rect2f& b = boxes[j];
|
| 127 |
+
float xx1 = std::max(a.x, b.x), yy1 = std::max(a.y, b.y);
|
| 128 |
+
float xx2 = std::min(a.x + a.width, b.x + b.width);
|
| 129 |
+
float yy2 = std::min(a.y + a.height, b.y + b.height);
|
| 130 |
+
float inter = std::max(0.f, xx2 - xx1) * std::max(0.f, yy2 - yy1);
|
| 131 |
+
float iou = inter / (a.area() + b.area() - inter + 1e-9f);
|
| 132 |
+
if (iou > 0.3f) removed[oj] = 1;
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
int W = img.cols, H = img.rows;
|
| 137 |
+
for (int i : pick)
|
| 138 |
+
{
|
| 139 |
+
const Rect2f& b = boxes[i];
|
| 140 |
+
rectangle(img, Point(int(b.x * W), int(b.y * H)),
|
| 141 |
+
Point(int((b.x + b.width) * W), int((b.y + b.height) * H)), Scalar(0, 255, 0), 2);
|
| 142 |
+
}
|
| 143 |
+
imwrite(output, img);
|
| 144 |
+
std::cout << "opencv_face_detector_uint8 " << pick.size() << " faces" << std::endl;
|
| 145 |
+
return 0;
|
| 146 |
+
}
|
opencv_face_detector_uint8/demo.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
|
| 10 |
+
sz = 300
|
| 11 |
+
layers = [
|
| 12 |
+
(30, 60, [2], 8, 38),
|
| 13 |
+
(60, 111, [2, 3], 16, 19),
|
| 14 |
+
(111, 162, [2, 3], 32, 10),
|
| 15 |
+
(162, 213, [2, 3], 64, 5),
|
| 16 |
+
(213, 264, [2], 100, 5),
|
| 17 |
+
(264, 315, [2], 300, 5),
|
| 18 |
+
]
|
| 19 |
+
var = [0.1, 0.1, 0.2, 0.2]
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def build_priors():
|
| 23 |
+
p = []
|
| 24 |
+
for mn, mx, ars, step, fm in layers:
|
| 25 |
+
ratios = [1.0]
|
| 26 |
+
for a in ars:
|
| 27 |
+
ratios += [a, 1.0 / a]
|
| 28 |
+
for y in range(fm):
|
| 29 |
+
for x in range(fm):
|
| 30 |
+
cx = (x + 0.5) * step
|
| 31 |
+
cy = (y + 0.5) * step
|
| 32 |
+
boxes = [(mn, mn), ((mn * mx) ** 0.5, (mn * mx) ** 0.5)]
|
| 33 |
+
for a in ratios[1:]:
|
| 34 |
+
boxes.append((mn * a ** 0.5, mn / a ** 0.5))
|
| 35 |
+
for bw, bh in boxes:
|
| 36 |
+
p.append([cx, cy, bw, bh])
|
| 37 |
+
return np.array(p, np.float32)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def default_model():
|
| 41 |
+
files = [f for f in glob.glob(os.path.join(here, "*.onnx")) if "known_good" not in os.path.basename(f)]
|
| 42 |
+
return files[0] if files else os.path.join(here, "opencv_face_detector_uint8.onnx")
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def main():
|
| 46 |
+
parser = argparse.ArgumentParser(description="OpenCV SSD face detector (ONNX) demo")
|
| 47 |
+
parser.add_argument("--model", default=default_model())
|
| 48 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 49 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 50 |
+
parser.add_argument("--conf", type=float, default=0.4)
|
| 51 |
+
args = parser.parse_args()
|
| 52 |
+
|
| 53 |
+
img = cv.imread(args.image)
|
| 54 |
+
if img is None:
|
| 55 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 56 |
+
|
| 57 |
+
inp = cv.resize(img, (sz, sz)).astype(np.float32) - np.array([104.0, 177.0, 123.0], np.float32)
|
| 58 |
+
|
| 59 |
+
net = cv.dnn.readNetFromONNX(args.model)
|
| 60 |
+
onames = net.getUnconnectedOutLayersNames()
|
| 61 |
+
net.setInput(inp[None])
|
| 62 |
+
res = net.forward(onames)
|
| 63 |
+
loc = res[[i for i, n in enumerate(onames) if "mbox_loc" in n][0]].reshape(-1, 4)
|
| 64 |
+
conf = res[[i for i, n in enumerate(onames) if "mbox_conf" in n][0]].reshape(-1, 2)
|
| 65 |
+
|
| 66 |
+
priors = build_priors()
|
| 67 |
+
pcx = priors[:, 0] / sz
|
| 68 |
+
pcy = priors[:, 1] / sz
|
| 69 |
+
pw = priors[:, 2] / sz
|
| 70 |
+
ph = priors[:, 3] / sz
|
| 71 |
+
|
| 72 |
+
e = np.exp(conf - conf.max(1, keepdims=True))
|
| 73 |
+
sm = e / e.sum(1, keepdims=True)
|
| 74 |
+
scores = sm[:, 1]
|
| 75 |
+
|
| 76 |
+
cx = pcx + loc[:, 0] * var[0] * pw
|
| 77 |
+
cy = pcy + loc[:, 1] * var[1] * ph
|
| 78 |
+
bw = pw * np.exp(loc[:, 2] * var[2])
|
| 79 |
+
bh = ph * np.exp(loc[:, 3] * var[3])
|
| 80 |
+
boxes = np.stack([cx - bw / 2, cy - bh / 2, cx + bw / 2, cy + bh / 2], 1)
|
| 81 |
+
|
| 82 |
+
keep = scores > args.conf
|
| 83 |
+
boxes = boxes[keep]
|
| 84 |
+
scores = scores[keep]
|
| 85 |
+
order = scores.argsort()[::-1]
|
| 86 |
+
pick = []
|
| 87 |
+
while order.size:
|
| 88 |
+
i = order[0]
|
| 89 |
+
pick.append(i)
|
| 90 |
+
xx1 = np.maximum(boxes[i, 0], boxes[order[1:], 0])
|
| 91 |
+
yy1 = np.maximum(boxes[i, 1], boxes[order[1:], 1])
|
| 92 |
+
xx2 = np.minimum(boxes[i, 2], boxes[order[1:], 2])
|
| 93 |
+
yy2 = np.minimum(boxes[i, 3], boxes[order[1:], 3])
|
| 94 |
+
inter = np.maximum(0, xx2 - xx1) * np.maximum(0, yy2 - yy1)
|
| 95 |
+
ai = (boxes[i, 2] - boxes[i, 0]) * (boxes[i, 3] - boxes[i, 1])
|
| 96 |
+
aj = (boxes[order[1:], 2] - boxes[order[1:], 0]) * (boxes[order[1:], 3] - boxes[order[1:], 1])
|
| 97 |
+
iou = inter / (ai + aj - inter + 1e-9)
|
| 98 |
+
order = order[1:][iou <= 0.3]
|
| 99 |
+
|
| 100 |
+
h, w = img.shape[:2]
|
| 101 |
+
for i in pick:
|
| 102 |
+
x1, y1, x2, y2 = boxes[i]
|
| 103 |
+
cv.rectangle(img, (int(x1 * w), int(y1 * h)), (int(x2 * w), int(y2 * h)), (0, 255, 0), 2)
|
| 104 |
+
cv.imwrite(args.output, img)
|
| 105 |
+
print("opencv_face_detector_uint8", len(pick), "faces")
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
if __name__ == "__main__":
|
| 109 |
+
main()
|
opencv_face_detector_uint8/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
opencv_face_detector_uint8/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
opencv_face_detector_uint8/opencv_face_detector_uint8_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f5b1efe9c4e792a010ac36248d92b64c3d94f9bdec764951d1e8684d919b1e40
|
| 3 |
+
size 10671719
|
ssd_inception_v2_coco_2017_11_17/LICENSE
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2022 Google LLC. All rights reserved.
|
| 2 |
+
|
| 3 |
+
All files in the following folders:
|
| 4 |
+
/community
|
| 5 |
+
/official
|
| 6 |
+
/orbit
|
| 7 |
+
/research
|
| 8 |
+
/tensorflow_models
|
| 9 |
+
|
| 10 |
+
Are licensed as follows:
|
| 11 |
+
|
| 12 |
+
Apache License
|
| 13 |
+
Version 2.0, January 2004
|
| 14 |
+
http://www.apache.org/licenses/
|
| 15 |
+
|
| 16 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 17 |
+
|
| 18 |
+
1. Definitions.
|
| 19 |
+
|
| 20 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 21 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 22 |
+
|
| 23 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 24 |
+
the copyright owner that is granting the License.
|
| 25 |
+
|
| 26 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 27 |
+
other entities that control, are controlled by, or are under common
|
| 28 |
+
control with that entity. For the purposes of this definition,
|
| 29 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 30 |
+
direction or management of such entity, whether by contract or
|
| 31 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 32 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 33 |
+
|
| 34 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 35 |
+
exercising permissions granted by this License.
|
| 36 |
+
|
| 37 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 38 |
+
including but not limited to software source code, documentation
|
| 39 |
+
source, and configuration files.
|
| 40 |
+
|
| 41 |
+
"Object" form shall mean any form resulting from mechanical
|
| 42 |
+
transformation or translation of a Source form, including but
|
| 43 |
+
not limited to compiled object code, generated documentation,
|
| 44 |
+
and conversions to other media types.
|
| 45 |
+
|
| 46 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 47 |
+
Object form, made available under the License, as indicated by a
|
| 48 |
+
copyright notice that is included in or attached to the work
|
| 49 |
+
(an example is provided in the Appendix below).
|
| 50 |
+
|
| 51 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 52 |
+
form, that is based on (or derived from) the Work and for which the
|
| 53 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 54 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 55 |
+
of this License, Derivative Works shall not include works that remain
|
| 56 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 57 |
+
the Work and Derivative Works thereof.
|
| 58 |
+
|
| 59 |
+
"Contribution" shall mean any work of authorship, including
|
| 60 |
+
the original version of the Work and any modifications or additions
|
| 61 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 62 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 63 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 64 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 65 |
+
means any form of electronic, verbal, or written communication sent
|
| 66 |
+
to the Licensor or its representatives, including but not limited to
|
| 67 |
+
communication on electronic mailing lists, source code control systems,
|
| 68 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 69 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 70 |
+
excluding communication that is conspicuously marked or otherwise
|
| 71 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 72 |
+
|
| 73 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 74 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 75 |
+
subsequently incorporated within the Work.
|
| 76 |
+
|
| 77 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 78 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 79 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 80 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 81 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 82 |
+
Work and such Derivative Works in Source or Object form.
|
| 83 |
+
|
| 84 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 85 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 86 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 87 |
+
(except as stated in this section) patent license to make, have made,
|
| 88 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 89 |
+
where such license applies only to those patent claims licensable
|
| 90 |
+
by such Contributor that are necessarily infringed by their
|
| 91 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 92 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 93 |
+
institute patent litigation against any entity (including a
|
| 94 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 95 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 96 |
+
or contributory patent infringement, then any patent licenses
|
| 97 |
+
granted to You under this License for that Work shall terminate
|
| 98 |
+
as of the date such litigation is filed.
|
| 99 |
+
|
| 100 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 101 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 102 |
+
modifications, and in Source or Object form, provided that You
|
| 103 |
+
meet the following conditions:
|
| 104 |
+
|
| 105 |
+
(a) You must give any other recipients of the Work or
|
| 106 |
+
Derivative Works a copy of this License; and
|
| 107 |
+
|
| 108 |
+
(b) You must cause any modified files to carry prominent notices
|
| 109 |
+
stating that You changed the files; and
|
| 110 |
+
|
| 111 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 112 |
+
that You distribute, all copyright, patent, trademark, and
|
| 113 |
+
attribution notices from the Source form of the Work,
|
| 114 |
+
excluding those notices that do not pertain to any part of
|
| 115 |
+
the Derivative Works; and
|
| 116 |
+
|
| 117 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 118 |
+
distribution, then any Derivative Works that You distribute must
|
| 119 |
+
include a readable copy of the attribution notices contained
|
| 120 |
+
within such NOTICE file, excluding those notices that do not
|
| 121 |
+
pertain to any part of the Derivative Works, in at least one
|
| 122 |
+
of the following places: within a NOTICE text file distributed
|
| 123 |
+
as part of the Derivative Works; within the Source form or
|
| 124 |
+
documentation, if provided along with the Derivative Works; or,
|
| 125 |
+
within a display generated by the Derivative Works, if and
|
| 126 |
+
wherever such third-party notices normally appear. The contents
|
| 127 |
+
of the NOTICE file are for informational purposes only and
|
| 128 |
+
do not modify the License. You may add Your own attribution
|
| 129 |
+
notices within Derivative Works that You distribute, alongside
|
| 130 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 131 |
+
that such additional attribution notices cannot be construed
|
| 132 |
+
as modifying the License.
|
| 133 |
+
|
| 134 |
+
You may add Your own copyright statement to Your modifications and
|
| 135 |
+
may provide additional or different license terms and conditions
|
| 136 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 137 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 138 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 139 |
+
the conditions stated in this License.
|
| 140 |
+
|
| 141 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 142 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 143 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 144 |
+
this License, without any additional terms or conditions.
|
| 145 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 146 |
+
the terms of any separate license agreement you may have executed
|
| 147 |
+
with Licensor regarding such Contributions.
|
| 148 |
+
|
| 149 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 150 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 151 |
+
except as required for reasonable and customary use in describing the
|
| 152 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 153 |
+
|
| 154 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 155 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 156 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 157 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 158 |
+
implied, including, without limitation, any warranties or conditions
|
| 159 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 160 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 161 |
+
appropriateness of using or redistributing the Work and assume any
|
| 162 |
+
risks associated with Your exercise of permissions under this License.
|
| 163 |
+
|
| 164 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 165 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 166 |
+
unless required by applicable law (such as deliberate and grossly
|
| 167 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 168 |
+
liable to You for damages, including any direct, indirect, special,
|
| 169 |
+
incidental, or consequential damages of any character arising as a
|
| 170 |
+
result of this License or out of the use or inability to use the
|
| 171 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 172 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 173 |
+
other commercial damages or losses), even if such Contributor
|
| 174 |
+
has been advised of the possibility of such damages.
|
| 175 |
+
|
| 176 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 177 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 178 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 179 |
+
or other liability obligations and/or rights consistent with this
|
| 180 |
+
License. However, in accepting such obligations, You may act only
|
| 181 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 182 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 183 |
+
defend, and hold each Contributor harmless for any liability
|
| 184 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 185 |
+
of your accepting any such warranty or additional liability.
|
| 186 |
+
|
| 187 |
+
END OF TERMS AND CONDITIONS
|
| 188 |
+
|
| 189 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 190 |
+
|
| 191 |
+
To apply the Apache License to your work, attach the following
|
| 192 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 193 |
+
replaced with your own identifying information. (Don't include
|
| 194 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 195 |
+
comment syntax for the file format. We also recommend that a
|
| 196 |
+
file or class name and description of purpose be included on the
|
| 197 |
+
same "printed page" as the copyright notice for easier
|
| 198 |
+
identification within third-party archives.
|
| 199 |
+
|
| 200 |
+
Copyright 2016, The Authors.
|
| 201 |
+
|
| 202 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 203 |
+
you may not use this file except in compliance with the License.
|
| 204 |
+
You may obtain a copy of the License at
|
| 205 |
+
|
| 206 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 207 |
+
|
| 208 |
+
Unless required by applicable law or agreed to in writing, software
|
| 209 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 210 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 211 |
+
See the License for the specific language governing permissions and
|
| 212 |
+
limitations under the License.
|
ssd_inception_v2_coco_2017_11_17/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SSD Inception v2 COCO
|
| 2 |
+
|
| 3 |
+
Object detection with a Single Shot MultiBox Detector (SSD) built on an Inception v2 backbone,
|
| 4 |
+
trained on the COCO dataset. The model was originally distributed as a frozen TensorFlow graph
|
| 5 |
+
(`ssd_inception_v2_coco_2017_11_17.pb`) and converted to ONNX for use with OpenCV's DNN module.
|
| 6 |
+
|
| 7 |
+
## Model Details
|
| 8 |
+
- **Architecture**: SSD (Single Shot MultiBox Detector) with Inception v2 backbone
|
| 9 |
+
- **Input**: RGB image, 300×300, raw uint8, NHWC layout (`image_tensor:0`, shape `[1, 300, 300, 3]`)
|
| 10 |
+
- **Output**: `detection_boxes:0` (normalized `ymin, xmin, ymax, xmax`), `detection_scores:0`, `detection_classes:0` (COCO class ids), `num_detections:0`
|
| 11 |
+
- **Framework**: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
|
| 12 |
+
- **Original weights**: http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz
|
| 13 |
+
|
| 14 |
+
## Usage
|
| 15 |
+
|
| 16 |
+
### Python
|
| 17 |
+
```bash
|
| 18 |
+
python demo.py --model ssd_inception_v2_coco_2017_11_17_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.3
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
### C++
|
| 22 |
+
The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup:
|
| 23 |
+
```bash
|
| 24 |
+
OCV=/path/to/opencv # OpenCV source tree
|
| 25 |
+
OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs)
|
| 26 |
+
g++ -std=c++17 demo.cpp -o demo \
|
| 27 |
+
-I$OCV/include \
|
| 28 |
+
-I$OCV/modules/core/include \
|
| 29 |
+
-I$OCV/modules/dnn/include \
|
| 30 |
+
-I$OCV/modules/imgproc/include \
|
| 31 |
+
-I$OCV/modules/imgcodecs/include \
|
| 32 |
+
-I$OCVBUILD \
|
| 33 |
+
-L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
|
| 34 |
+
./demo --model ssd_inception_v2_coco_2017_11_17_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
## Conversion
|
| 38 |
+
The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18)
|
| 39 |
+
via [convert_to_onnx.py](./convert_to_onnx.py) — input `image_tensor:0`, outputs
|
| 40 |
+
`detection_boxes:0`, `detection_scores:0`, `detection_classes:0`, `num_detections:0`.
|
| 41 |
+
Requires `tensorflow`, `tf2onnx`, and `onnx`.
|
| 42 |
+
|
| 43 |
+
```bash
|
| 44 |
+
python convert_to_onnx.py --pb ../pb/ssd_inception_v2_coco_2017_11_17.pb
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
## License
|
| 48 |
+
See [LICENSE](./LICENSE) — the model is released by the TensorFlow Authors under the Apache License 2.0.
|
ssd_inception_v2_coco_2017_11_17/convert_to_onnx.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import datetime
|
| 3 |
+
|
| 4 |
+
import onnx
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
import tf2onnx
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def load_graph_def(pb_path):
|
| 10 |
+
with tf.io.gfile.GFile(pb_path, "rb") as f:
|
| 11 |
+
graph_def = tf.compat.v1.GraphDef()
|
| 12 |
+
graph_def.ParseFromString(f.read())
|
| 13 |
+
return graph_def
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser(description="Export ssd_inception_v2_coco_2017_11_17.pb to ONNX")
|
| 18 |
+
parser.add_argument("--pb", default="../pb/ssd_inception_v2_coco_2017_11_17.pb")
|
| 19 |
+
parser.add_argument("--opset", type=int, default=18)
|
| 20 |
+
args = parser.parse_args()
|
| 21 |
+
|
| 22 |
+
graph_def = load_graph_def(args.pb)
|
| 23 |
+
|
| 24 |
+
model_proto, _ = tf2onnx.convert.from_graph_def(
|
| 25 |
+
graph_def,
|
| 26 |
+
input_names=["image_tensor:0"],
|
| 27 |
+
output_names=["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"],
|
| 28 |
+
opset=args.opset,
|
| 29 |
+
)
|
| 30 |
+
onnx.checker.check_model(model_proto)
|
| 31 |
+
|
| 32 |
+
stamp = datetime.datetime.now().strftime("%Y%b").lower()
|
| 33 |
+
onnx_path = "ssd_inception_v2_coco_2017_11_17_%s.onnx" % stamp
|
| 34 |
+
with open(onnx_path, "wb") as f:
|
| 35 |
+
f.write(model_proto.SerializeToString())
|
| 36 |
+
print("wrote", onnx_path)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
main()
|
ssd_inception_v2_coco_2017_11_17/demo.cpp
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <opencv2/dnn.hpp>
|
| 2 |
+
#include <opencv2/imgproc.hpp>
|
| 3 |
+
#include <opencv2/imgcodecs.hpp>
|
| 4 |
+
#include <array>
|
| 5 |
+
#include <cstdint>
|
| 6 |
+
#include <iostream>
|
| 7 |
+
#include <string>
|
| 8 |
+
#include <vector>
|
| 9 |
+
|
| 10 |
+
using namespace cv;
|
| 11 |
+
|
| 12 |
+
static std::string argVal(int argc, char** argv, const std::string& key, const std::string& def)
|
| 13 |
+
{
|
| 14 |
+
for (int i = 1; i + 1 < argc; ++i)
|
| 15 |
+
if (key == argv[i]) return argv[i + 1];
|
| 16 |
+
return def;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
int main(int argc, char** argv)
|
| 20 |
+
{
|
| 21 |
+
std::string model = argVal(argc, argv, "--model", "ssd_inception_v2_coco_2017_11_17_2026jul.onnx");
|
| 22 |
+
std::string image = argVal(argc, argv, "--image", "example_outputs/input_image.png");
|
| 23 |
+
std::string output = argVal(argc, argv, "--output", "example_outputs/output_image.png");
|
| 24 |
+
float conf = std::stof(argVal(argc, argv, "--conf", "0.3"));
|
| 25 |
+
|
| 26 |
+
Mat img = imread(image);
|
| 27 |
+
if (img.empty())
|
| 28 |
+
{
|
| 29 |
+
std::cerr << "could not read image: " << image << std::endl;
|
| 30 |
+
return 1;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
Mat rgb;
|
| 34 |
+
cvtColor(img, rgb, COLOR_BGR2RGB);
|
| 35 |
+
resize(rgb, rgb, Size(300, 300));
|
| 36 |
+
if (!rgb.isContinuous()) rgb = rgb.clone();
|
| 37 |
+
|
| 38 |
+
int blobShape[] = {1, 300, 300, 3};
|
| 39 |
+
Mat blob(4, blobShape, CV_8U, rgb.data);
|
| 40 |
+
dnn::Net net = dnn::readNetFromONNX(model, dnn::ENGINE_ORT);
|
| 41 |
+
net.setInput(blob);
|
| 42 |
+
std::vector<String> out_str = {"detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"};
|
| 43 |
+
std::vector<Mat> outs;
|
| 44 |
+
net.forward(outs, out_str);
|
| 45 |
+
|
| 46 |
+
const float *boxes = 0, *scores = 0, *classes = 0, *num = 0;
|
| 47 |
+
for (size_t i = 0; i < out_str.size(); ++i)
|
| 48 |
+
{
|
| 49 |
+
const std::string& n = out_str[i];
|
| 50 |
+
if (n.find("detection_boxes") != std::string::npos) boxes = (const float*)outs[i].data;
|
| 51 |
+
else if (n.find("detection_scores") != std::string::npos) scores = (const float*)outs[i].data;
|
| 52 |
+
else if (n.find("detection_classes") != std::string::npos) classes = (const float*)outs[i].data;
|
| 53 |
+
else if (n.find("num_detections") != std::string::npos) num = (const float*)outs[i].data;
|
| 54 |
+
}
|
| 55 |
+
if (!boxes || !scores || !classes || !num)
|
| 56 |
+
{
|
| 57 |
+
std::cerr << "missing expected output tensors" << std::endl;
|
| 58 |
+
return 1;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
int nd = (int)num[0];
|
| 62 |
+
int h = img.rows, w = img.cols;
|
| 63 |
+
Mat out = img.clone();
|
| 64 |
+
std::vector<std::string> lines;
|
| 65 |
+
for (int k = 0; k < nd; ++k)
|
| 66 |
+
{
|
| 67 |
+
if (scores[k] < conf) continue;
|
| 68 |
+
float ymin = boxes[k * 4 + 0], xmin = boxes[k * 4 + 1];
|
| 69 |
+
float ymax = boxes[k * 4 + 2], xmax = boxes[k * 4 + 3];
|
| 70 |
+
int cls = (int)classes[k];
|
| 71 |
+
rectangle(out, Point(int(xmin * w), int(ymin * h)), Point(int(xmax * w), int(ymax * h)), Scalar(0, 255, 0), 2);
|
| 72 |
+
putText(out, format("%d:%.2f", cls, scores[k]), Point(int(xmin * w), int(ymin * h) - 5),
|
| 73 |
+
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
|
| 74 |
+
lines.push_back(format("%d %.3f %.3f %.3f %.3f %.3f", cls, scores[k], xmin, ymin, xmax, ymax));
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
imwrite(output, out);
|
| 78 |
+
std::cout << "ssd_inception_v2_coco_2017_11_17 " << lines.size() << " detections" << std::endl;
|
| 79 |
+
for (const auto& l : lines) std::cout << l << std::endl;
|
| 80 |
+
return 0;
|
| 81 |
+
}
|
ssd_inception_v2_coco_2017_11_17/demo.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
import cv2 as cv
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def main():
|
| 12 |
+
parser = argparse.ArgumentParser(description="SSD Inception v2 COCO (ONNX) object detection demo")
|
| 13 |
+
parser.add_argument("--model", default=(glob.glob(os.path.join(here, "*.onnx")) or [""])[0])
|
| 14 |
+
parser.add_argument("--image", default=os.path.join(here, "example_outputs", "input_image.png"))
|
| 15 |
+
parser.add_argument("--output", default=os.path.join(here, "example_outputs", "output_image.png"))
|
| 16 |
+
parser.add_argument("--conf", type=float, default=0.3)
|
| 17 |
+
args = parser.parse_args()
|
| 18 |
+
|
| 19 |
+
img = cv.imread(args.image)
|
| 20 |
+
if img is None:
|
| 21 |
+
raise SystemExit("could not read image: %s" % args.image)
|
| 22 |
+
|
| 23 |
+
rgb = cv.resize(cv.cvtColor(img, cv.COLOR_BGR2RGB), (300, 300))
|
| 24 |
+
|
| 25 |
+
net = cv.dnn.readNetFromONNX(args.model, cv.dnn.ENGINE_ORT)
|
| 26 |
+
onames = ["detection_boxes:0", "detection_scores:0", "detection_classes:0", "num_detections:0"]
|
| 27 |
+
net.setInput(rgb[None].astype(np.uint8))
|
| 28 |
+
res = net.forward(onames)
|
| 29 |
+
boxes = res[[i for i, n in enumerate(onames) if "detection_boxes" in n][0]].reshape(-1, 4)
|
| 30 |
+
scores = res[[i for i, n in enumerate(onames) if "detection_scores" in n][0]].reshape(-1)
|
| 31 |
+
classes = res[[i for i, n in enumerate(onames) if "detection_classes" in n][0]].reshape(-1)
|
| 32 |
+
nd = int(res[[i for i, n in enumerate(onames) if "num_detections" in n][0]].reshape(-1)[0])
|
| 33 |
+
|
| 34 |
+
h, w = img.shape[:2]
|
| 35 |
+
out = img.copy()
|
| 36 |
+
kept = []
|
| 37 |
+
for k in range(nd):
|
| 38 |
+
if scores[k] < args.conf:
|
| 39 |
+
continue
|
| 40 |
+
ymin, xmin, ymax, xmax = boxes[k]
|
| 41 |
+
kept.append((int(classes[k]), float(scores[k]), float(xmin), float(ymin), float(xmax), float(ymax)))
|
| 42 |
+
cv.rectangle(out, (int(xmin * w), int(ymin * h)), (int(xmax * w), int(ymax * h)), (0, 255, 0), 2)
|
| 43 |
+
cv.putText(out, "%d:%.2f" % (int(classes[k]), scores[k]), (int(xmin * w), int(ymin * h) - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
| 44 |
+
|
| 45 |
+
cv.imwrite(args.output, out)
|
| 46 |
+
print("ssd_inception_v2_coco_2017_11_17", len(kept), "detections")
|
| 47 |
+
for c, s, xmin, ymin, xmax, ymax in kept:
|
| 48 |
+
print(c, round(s, 3), round(xmin, 3), round(ymin, 3), round(xmax, 3), round(ymax, 3))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
if __name__ == "__main__":
|
| 52 |
+
main()
|
ssd_inception_v2_coco_2017_11_17/example_outputs/input_image.png
ADDED
|
Git LFS Details
|
ssd_inception_v2_coco_2017_11_17/example_outputs/output_image.png
ADDED
|
Git LFS Details
|
ssd_inception_v2_coco_2017_11_17/ssd_inception_v2_coco_2017_11_17_2026jul.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5834f7214c7b9d80a9f708d23a3539d93e632fb346aeb5b1d013e63443354009
|
| 3 |
+
size 102207336
|
ssd_mobilenet_v1_coco_2017_11_17/LICENSE
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2015 The TensorFlow 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 2015, The TensorFlow Authors.
|
| 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.
|