正在显示
29 个修改的文件
包含
4899 行增加
和
0 行删除
.gitignore
0 → 100644
CMakeLists.txt
0 → 100644
| 1 | +cmake_minimum_required(VERSION 3.17) | ||
| 2 | +project(RobustVideoMatting.lite.ai.toolkit) | ||
| 3 | + | ||
| 4 | +set(CMAKE_CXX_STANDARD 11) | ||
| 5 | + | ||
| 6 | +# setting up lite.ai.toolkit | ||
| 7 | +set(LITE_AI_DIR ${CMAKE_SOURCE_DIR}/lite.ai.toolkit) | ||
| 8 | +set(LITE_AI_INCLUDE_DIR ${LITE_AI_DIR}/include) | ||
| 9 | +set(LITE_AI_LIBRARY_DIR ${LITE_AI_DIR}/lib) | ||
| 10 | +include_directories(${LITE_AI_INCLUDE_DIR}) | ||
| 11 | +link_directories(${LITE_AI_LIBRARY_DIR}) | ||
| 12 | + | ||
| 13 | +#set(OpenCV_LIBS | ||
| 14 | + # opencv_highgui | ||
| 15 | + # opencv_core | ||
| 16 | + # opencv_imgcodecs | ||
| 17 | + # opencv_imgproc | ||
| 18 | + # opencv_video | ||
| 19 | + # opencv_videoio | ||
| 20 | + # ) | ||
| 21 | +set(OpenCV_LIBS | ||
| 22 | + opencv_world4110d | ||
| 23 | + opencv_world4110 | ||
| 24 | + ) | ||
| 25 | +# add your executable | ||
| 26 | +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/examples/build) | ||
| 27 | + | ||
| 28 | +file(GLOB ALL_LIBS ${LITE_AI_LIBRARY_DIR}/*dll) | ||
| 29 | +file(INSTALL ${ALL_LIBS} DESTINATION ${EXECUTABLE_OUTPUT_PATH}) | ||
| 30 | + | ||
| 31 | +add_executable(lite_rvm examples/test_lite_rvm.cpp) | ||
| 32 | +target_link_libraries(lite_rvm | ||
| 33 | + lite.ai.toolkit | ||
| 34 | + onnxruntime | ||
| 35 | + # MNN # need, if built lite.ai.toolkit with ENABLE_MNN=ON, default OFF | ||
| 36 | + # ncnn # need, if built lite.ai.toolkit with ENABLE_NCNN=ON, default OFF | ||
| 37 | + # TNN # need, if built lite.ai.toolkit with ENABLE_TNN=ON, default OFF | ||
| 38 | + ${OpenCV_LIBS}) # link lite.ai.toolkit & other libs. |
LICENSE
0 → 100644
| 1 | + GNU GENERAL PUBLIC LICENSE | ||
| 2 | + Version 3, 29 June 2007 | ||
| 3 | + | ||
| 4 | + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> | ||
| 5 | + Everyone is permitted to copy and distribute verbatim copies | ||
| 6 | + of this license document, but changing it is not allowed. | ||
| 7 | + | ||
| 8 | + Preamble | ||
| 9 | + | ||
| 10 | + The GNU General Public License is a free, copyleft license for | ||
| 11 | +software and other kinds of works. | ||
| 12 | + | ||
| 13 | + The licenses for most software and other practical works are designed | ||
| 14 | +to take away your freedom to share and change the works. By contrast, | ||
| 15 | +the GNU General Public License is intended to guarantee your freedom to | ||
| 16 | +share and change all versions of a program--to make sure it remains free | ||
| 17 | +software for all its users. We, the Free Software Foundation, use the | ||
| 18 | +GNU General Public License for most of our software; it applies also to | ||
| 19 | +any other work released this way by its authors. You can apply it to | ||
| 20 | +your programs, too. | ||
| 21 | + | ||
| 22 | + When we speak of free software, we are referring to freedom, not | ||
| 23 | +price. Our General Public Licenses are designed to make sure that you | ||
| 24 | +have the freedom to distribute copies of free software (and charge for | ||
| 25 | +them if you wish), that you receive source code or can get it if you | ||
| 26 | +want it, that you can change the software or use pieces of it in new | ||
| 27 | +free programs, and that you know you can do these things. | ||
| 28 | + | ||
| 29 | + To protect your rights, we need to prevent others from denying you | ||
| 30 | +these rights or asking you to surrender the rights. Therefore, you have | ||
| 31 | +certain responsibilities if you distribute copies of the software, or if | ||
| 32 | +you modify it: responsibilities to respect the freedom of others. | ||
| 33 | + | ||
| 34 | + For example, if you distribute copies of such a program, whether | ||
| 35 | +gratis or for a fee, you must pass on to the recipients the same | ||
| 36 | +freedoms that you received. You must make sure that they, too, receive | ||
| 37 | +or can get the source code. And you must show them these terms so they | ||
| 38 | +know their rights. | ||
| 39 | + | ||
| 40 | + Developers that use the GNU GPL protect your rights with two steps: | ||
| 41 | +(1) assert copyright on the software, and (2) offer you this License | ||
| 42 | +giving you legal permission to copy, distribute and/or modify it. | ||
| 43 | + | ||
| 44 | + For the developers' and authors' protection, the GPL clearly explains | ||
| 45 | +that there is no warranty for this free software. For both users' and | ||
| 46 | +authors' sake, the GPL requires that modified versions be marked as | ||
| 47 | +changed, so that their problems will not be attributed erroneously to | ||
| 48 | +authors of previous versions. | ||
| 49 | + | ||
| 50 | + Some devices are designed to deny users access to install or run | ||
| 51 | +modified versions of the software inside them, although the manufacturer | ||
| 52 | +can do so. This is fundamentally incompatible with the aim of | ||
| 53 | +protecting users' freedom to change the software. The systematic | ||
| 54 | +pattern of such abuse occurs in the area of products for individuals to | ||
| 55 | +use, which is precisely where it is most unacceptable. Therefore, we | ||
| 56 | +have designed this version of the GPL to prohibit the practice for those | ||
| 57 | +products. If such problems arise substantially in other domains, we | ||
| 58 | +stand ready to extend this provision to those domains in future versions | ||
| 59 | +of the GPL, as needed to protect the freedom of users. | ||
| 60 | + | ||
| 61 | + Finally, every program is threatened constantly by software patents. | ||
| 62 | +States should not allow patents to restrict development and use of | ||
| 63 | +software on general-purpose computers, but in those that do, we wish to | ||
| 64 | +avoid the special danger that patents applied to a free program could | ||
| 65 | +make it effectively proprietary. To prevent this, the GPL assures that | ||
| 66 | +patents cannot be used to render the program non-free. | ||
| 67 | + | ||
| 68 | + The precise terms and conditions for copying, distribution and | ||
| 69 | +modification follow. | ||
| 70 | + | ||
| 71 | + TERMS AND CONDITIONS | ||
| 72 | + | ||
| 73 | + 0. Definitions. | ||
| 74 | + | ||
| 75 | + "This License" refers to version 3 of the GNU General Public License. | ||
| 76 | + | ||
| 77 | + "Copyright" also means copyright-like laws that apply to other kinds of | ||
| 78 | +works, such as semiconductor masks. | ||
| 79 | + | ||
| 80 | + "The Program" refers to any copyrightable work licensed under this | ||
| 81 | +License. Each licensee is addressed as "you". "Licensees" and | ||
| 82 | +"recipients" may be individuals or organizations. | ||
| 83 | + | ||
| 84 | + To "modify" a work means to copy from or adapt all or part of the work | ||
| 85 | +in a fashion requiring copyright permission, other than the making of an | ||
| 86 | +exact copy. The resulting work is called a "modified version" of the | ||
| 87 | +earlier work or a work "based on" the earlier work. | ||
| 88 | + | ||
| 89 | + A "covered work" means either the unmodified Program or a work based | ||
| 90 | +on the Program. | ||
| 91 | + | ||
| 92 | + To "propagate" a work means to do anything with it that, without | ||
| 93 | +permission, would make you directly or secondarily liable for | ||
| 94 | +infringement under applicable copyright law, except executing it on a | ||
| 95 | +computer or modifying a private copy. Propagation includes copying, | ||
| 96 | +distribution (with or without modification), making available to the | ||
| 97 | +public, and in some countries other activities as well. | ||
| 98 | + | ||
| 99 | + To "convey" a work means any kind of propagation that enables other | ||
| 100 | +parties to make or receive copies. Mere interaction with a user through | ||
| 101 | +a computer network, with no transfer of a copy, is not conveying. | ||
| 102 | + | ||
| 103 | + An interactive user interface displays "Appropriate Legal Notices" | ||
| 104 | +to the extent that it includes a convenient and prominently visible | ||
| 105 | +feature that (1) displays an appropriate copyright notice, and (2) | ||
| 106 | +tells the user that there is no warranty for the work (except to the | ||
| 107 | +extent that warranties are provided), that licensees may convey the | ||
| 108 | +work under this License, and how to view a copy of this License. If | ||
| 109 | +the interface presents a list of user commands or options, such as a | ||
| 110 | +menu, a prominent item in the list meets this criterion. | ||
| 111 | + | ||
| 112 | + 1. Source Code. | ||
| 113 | + | ||
| 114 | + The "source code" for a work means the preferred form of the work | ||
| 115 | +for making modifications to it. "Object code" means any non-source | ||
| 116 | +form of a work. | ||
| 117 | + | ||
| 118 | + A "Standard Interface" means an interface that either is an official | ||
| 119 | +standard defined by a recognized standards body, or, in the case of | ||
| 120 | +interfaces specified for a particular programming language, one that | ||
| 121 | +is widely used among developers working in that language. | ||
| 122 | + | ||
| 123 | + The "System Libraries" of an executable work include anything, other | ||
| 124 | +than the work as a whole, that (a) is included in the normal form of | ||
| 125 | +packaging a Major Component, but which is not part of that Major | ||
| 126 | +Component, and (b) serves only to enable use of the work with that | ||
| 127 | +Major Component, or to implement a Standard Interface for which an | ||
| 128 | +implementation is available to the public in source code form. A | ||
| 129 | +"Major Component", in this context, means a major essential component | ||
| 130 | +(kernel, window system, and so on) of the specific operating system | ||
| 131 | +(if any) on which the executable work runs, or a compiler used to | ||
| 132 | +produce the work, or an object code interpreter used to run it. | ||
| 133 | + | ||
| 134 | + The "Corresponding Source" for a work in object code form means all | ||
| 135 | +the source code needed to generate, install, and (for an executable | ||
| 136 | +work) run the object code and to modify the work, including scripts to | ||
| 137 | +control those activities. However, it does not include the work's | ||
| 138 | +System Libraries, or general-purpose tools or generally available free | ||
| 139 | +programs which are used unmodified in performing those activities but | ||
| 140 | +which are not part of the work. For example, Corresponding Source | ||
| 141 | +includes interface definition files associated with source files for | ||
| 142 | +the work, and the source code for shared libraries and dynamically | ||
| 143 | +linked subprograms that the work is specifically designed to require, | ||
| 144 | +such as by intimate data communication or control flow between those | ||
| 145 | +subprograms and other parts of the work. | ||
| 146 | + | ||
| 147 | + The Corresponding Source need not include anything that users | ||
| 148 | +can regenerate automatically from other parts of the Corresponding | ||
| 149 | +Source. | ||
| 150 | + | ||
| 151 | + The Corresponding Source for a work in source code form is that | ||
| 152 | +same work. | ||
| 153 | + | ||
| 154 | + 2. Basic Permissions. | ||
| 155 | + | ||
| 156 | + All rights granted under this License are granted for the term of | ||
| 157 | +copyright on the Program, and are irrevocable provided the stated | ||
| 158 | +conditions are met. This License explicitly affirms your unlimited | ||
| 159 | +permission to run the unmodified Program. The output from running a | ||
| 160 | +covered work is covered by this License only if the output, given its | ||
| 161 | +content, constitutes a covered work. This License acknowledges your | ||
| 162 | +rights of fair use or other equivalent, as provided by copyright law. | ||
| 163 | + | ||
| 164 | + You may make, run and propagate covered works that you do not | ||
| 165 | +convey, without conditions so long as your license otherwise remains | ||
| 166 | +in force. You may convey covered works to others for the sole purpose | ||
| 167 | +of having them make modifications exclusively for you, or provide you | ||
| 168 | +with facilities for running those works, provided that you comply with | ||
| 169 | +the terms of this License in conveying all material for which you do | ||
| 170 | +not control copyright. Those thus making or running the covered works | ||
| 171 | +for you must do so exclusively on your behalf, under your direction | ||
| 172 | +and control, on terms that prohibit them from making any copies of | ||
| 173 | +your copyrighted material outside their relationship with you. | ||
| 174 | + | ||
| 175 | + Conveying under any other circumstances is permitted solely under | ||
| 176 | +the conditions stated below. Sublicensing is not allowed; section 10 | ||
| 177 | +makes it unnecessary. | ||
| 178 | + | ||
| 179 | + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | ||
| 180 | + | ||
| 181 | + No covered work shall be deemed part of an effective technological | ||
| 182 | +measure under any applicable law fulfilling obligations under article | ||
| 183 | +11 of the WIPO copyright treaty adopted on 20 December 1996, or | ||
| 184 | +similar laws prohibiting or restricting circumvention of such | ||
| 185 | +measures. | ||
| 186 | + | ||
| 187 | + When you convey a covered work, you waive any legal power to forbid | ||
| 188 | +circumvention of technological measures to the extent such circumvention | ||
| 189 | +is effected by exercising rights under this License with respect to | ||
| 190 | +the covered work, and you disclaim any intention to limit operation or | ||
| 191 | +modification of the work as a means of enforcing, against the work's | ||
| 192 | +users, your or third parties' legal rights to forbid circumvention of | ||
| 193 | +technological measures. | ||
| 194 | + | ||
| 195 | + 4. Conveying Verbatim Copies. | ||
| 196 | + | ||
| 197 | + You may convey verbatim copies of the Program's source code as you | ||
| 198 | +receive it, in any medium, provided that you conspicuously and | ||
| 199 | +appropriately publish on each copy an appropriate copyright notice; | ||
| 200 | +keep intact all notices stating that this License and any | ||
| 201 | +non-permissive terms added in accord with section 7 apply to the code; | ||
| 202 | +keep intact all notices of the absence of any warranty; and give all | ||
| 203 | +recipients a copy of this License along with the Program. | ||
| 204 | + | ||
| 205 | + You may charge any price or no price for each copy that you convey, | ||
| 206 | +and you may offer support or warranty protection for a fee. | ||
| 207 | + | ||
| 208 | + 5. Conveying Modified Source Versions. | ||
| 209 | + | ||
| 210 | + You may convey a work based on the Program, or the modifications to | ||
| 211 | +produce it from the Program, in the form of source code under the | ||
| 212 | +terms of section 4, provided that you also meet all of these conditions: | ||
| 213 | + | ||
| 214 | + a) The work must carry prominent notices stating that you modified | ||
| 215 | + it, and giving a relevant date. | ||
| 216 | + | ||
| 217 | + b) The work must carry prominent notices stating that it is | ||
| 218 | + released under this License and any conditions added under section | ||
| 219 | + 7. This requirement modifies the requirement in section 4 to | ||
| 220 | + "keep intact all notices". | ||
| 221 | + | ||
| 222 | + c) You must license the entire work, as a whole, under this | ||
| 223 | + License to anyone who comes into possession of a copy. This | ||
| 224 | + License will therefore apply, along with any applicable section 7 | ||
| 225 | + additional terms, to the whole of the work, and all its parts, | ||
| 226 | + regardless of how they are packaged. This License gives no | ||
| 227 | + permission to license the work in any other way, but it does not | ||
| 228 | + invalidate such permission if you have separately received it. | ||
| 229 | + | ||
| 230 | + d) If the work has interactive user interfaces, each must display | ||
| 231 | + Appropriate Legal Notices; however, if the Program has interactive | ||
| 232 | + interfaces that do not display Appropriate Legal Notices, your | ||
| 233 | + work need not make them do so. | ||
| 234 | + | ||
| 235 | + A compilation of a covered work with other separate and independent | ||
| 236 | +works, which are not by their nature extensions of the covered work, | ||
| 237 | +and which are not combined with it such as to form a larger program, | ||
| 238 | +in or on a volume of a storage or distribution medium, is called an | ||
| 239 | +"aggregate" if the compilation and its resulting copyright are not | ||
| 240 | +used to limit the access or legal rights of the compilation's users | ||
| 241 | +beyond what the individual works permit. Inclusion of a covered work | ||
| 242 | +in an aggregate does not cause this License to apply to the other | ||
| 243 | +parts of the aggregate. | ||
| 244 | + | ||
| 245 | + 6. Conveying Non-Source Forms. | ||
| 246 | + | ||
| 247 | + You may convey a covered work in object code form under the terms | ||
| 248 | +of sections 4 and 5, provided that you also convey the | ||
| 249 | +machine-readable Corresponding Source under the terms of this License, | ||
| 250 | +in one of these ways: | ||
| 251 | + | ||
| 252 | + a) Convey the object code in, or embodied in, a physical product | ||
| 253 | + (including a physical distribution medium), accompanied by the | ||
| 254 | + Corresponding Source fixed on a durable physical medium | ||
| 255 | + customarily used for software interchange. | ||
| 256 | + | ||
| 257 | + b) Convey the object code in, or embodied in, a physical product | ||
| 258 | + (including a physical distribution medium), accompanied by a | ||
| 259 | + written offer, valid for at least three years and valid for as | ||
| 260 | + long as you offer spare parts or customer support for that product | ||
| 261 | + model, to give anyone who possesses the object code either (1) a | ||
| 262 | + copy of the Corresponding Source for all the software in the | ||
| 263 | + product that is covered by this License, on a durable physical | ||
| 264 | + medium customarily used for software interchange, for a price no | ||
| 265 | + more than your reasonable cost of physically performing this | ||
| 266 | + conveying of source, or (2) access to copy the | ||
| 267 | + Corresponding Source from a network server at no charge. | ||
| 268 | + | ||
| 269 | + c) Convey individual copies of the object code with a copy of the | ||
| 270 | + written offer to provide the Corresponding Source. This | ||
| 271 | + alternative is allowed only occasionally and noncommercially, and | ||
| 272 | + only if you received the object code with such an offer, in accord | ||
| 273 | + with subsection 6b. | ||
| 274 | + | ||
| 275 | + d) Convey the object code by offering access from a designated | ||
| 276 | + place (gratis or for a charge), and offer equivalent access to the | ||
| 277 | + Corresponding Source in the same way through the same place at no | ||
| 278 | + further charge. You need not require recipients to copy the | ||
| 279 | + Corresponding Source along with the object code. If the place to | ||
| 280 | + copy the object code is a network server, the Corresponding Source | ||
| 281 | + may be on a different server (operated by you or a third party) | ||
| 282 | + that supports equivalent copying facilities, provided you maintain | ||
| 283 | + clear directions next to the object code saying where to find the | ||
| 284 | + Corresponding Source. Regardless of what server hosts the | ||
| 285 | + Corresponding Source, you remain obligated to ensure that it is | ||
| 286 | + available for as long as needed to satisfy these requirements. | ||
| 287 | + | ||
| 288 | + e) Convey the object code using peer-to-peer transmission, provided | ||
| 289 | + you inform other peers where the object code and Corresponding | ||
| 290 | + Source of the work are being offered to the general public at no | ||
| 291 | + charge under subsection 6d. | ||
| 292 | + | ||
| 293 | + A separable portion of the object code, whose source code is excluded | ||
| 294 | +from the Corresponding Source as a System Library, need not be | ||
| 295 | +included in conveying the object code work. | ||
| 296 | + | ||
| 297 | + A "User Product" is either (1) a "consumer product", which means any | ||
| 298 | +tangible personal property which is normally used for personal, family, | ||
| 299 | +or household purposes, or (2) anything designed or sold for incorporation | ||
| 300 | +into a dwelling. In determining whether a product is a consumer product, | ||
| 301 | +doubtful cases shall be resolved in favor of coverage. For a particular | ||
| 302 | +product received by a particular user, "normally used" refers to a | ||
| 303 | +typical or common use of that class of product, regardless of the status | ||
| 304 | +of the particular user or of the way in which the particular user | ||
| 305 | +actually uses, or expects or is expected to use, the product. A product | ||
| 306 | +is a consumer product regardless of whether the product has substantial | ||
| 307 | +commercial, industrial or non-consumer uses, unless such uses represent | ||
| 308 | +the only significant mode of use of the product. | ||
| 309 | + | ||
| 310 | + "Installation Information" for a User Product means any methods, | ||
| 311 | +procedures, authorization keys, or other information required to install | ||
| 312 | +and execute modified versions of a covered work in that User Product from | ||
| 313 | +a modified version of its Corresponding Source. The information must | ||
| 314 | +suffice to ensure that the continued functioning of the modified object | ||
| 315 | +code is in no case prevented or interfered with solely because | ||
| 316 | +modification has been made. | ||
| 317 | + | ||
| 318 | + If you convey an object code work under this section in, or with, or | ||
| 319 | +specifically for use in, a User Product, and the conveying occurs as | ||
| 320 | +part of a transaction in which the right of possession and use of the | ||
| 321 | +User Product is transferred to the recipient in perpetuity or for a | ||
| 322 | +fixed term (regardless of how the transaction is characterized), the | ||
| 323 | +Corresponding Source conveyed under this section must be accompanied | ||
| 324 | +by the Installation Information. But this requirement does not apply | ||
| 325 | +if neither you nor any third party retains the ability to install | ||
| 326 | +modified object code on the User Product (for example, the work has | ||
| 327 | +been installed in ROM). | ||
| 328 | + | ||
| 329 | + The requirement to provide Installation Information does not include a | ||
| 330 | +requirement to continue to provide support service, warranty, or updates | ||
| 331 | +for a work that has been modified or installed by the recipient, or for | ||
| 332 | +the User Product in which it has been modified or installed. Access to a | ||
| 333 | +network may be denied when the modification itself materially and | ||
| 334 | +adversely affects the operation of the network or violates the rules and | ||
| 335 | +protocols for communication across the network. | ||
| 336 | + | ||
| 337 | + Corresponding Source conveyed, and Installation Information provided, | ||
| 338 | +in accord with this section must be in a format that is publicly | ||
| 339 | +documented (and with an implementation available to the public in | ||
| 340 | +source code form), and must require no special password or key for | ||
| 341 | +unpacking, reading or copying. | ||
| 342 | + | ||
| 343 | + 7. Additional Terms. | ||
| 344 | + | ||
| 345 | + "Additional permissions" are terms that supplement the terms of this | ||
| 346 | +License by making exceptions from one or more of its conditions. | ||
| 347 | +Additional permissions that are applicable to the entire Program shall | ||
| 348 | +be treated as though they were included in this License, to the extent | ||
| 349 | +that they are valid under applicable law. If additional permissions | ||
| 350 | +apply only to part of the Program, that part may be used separately | ||
| 351 | +under those permissions, but the entire Program remains governed by | ||
| 352 | +this License without regard to the additional permissions. | ||
| 353 | + | ||
| 354 | + When you convey a copy of a covered work, you may at your option | ||
| 355 | +remove any additional permissions from that copy, or from any part of | ||
| 356 | +it. (Additional permissions may be written to require their own | ||
| 357 | +removal in certain cases when you modify the work.) You may place | ||
| 358 | +additional permissions on material, added by you to a covered work, | ||
| 359 | +for which you have or can give appropriate copyright permission. | ||
| 360 | + | ||
| 361 | + Notwithstanding any other provision of this License, for material you | ||
| 362 | +add to a covered work, you may (if authorized by the copyright holders of | ||
| 363 | +that material) supplement the terms of this License with terms: | ||
| 364 | + | ||
| 365 | + a) Disclaiming warranty or limiting liability differently from the | ||
| 366 | + terms of sections 15 and 16 of this License; or | ||
| 367 | + | ||
| 368 | + b) Requiring preservation of specified reasonable legal notices or | ||
| 369 | + author attributions in that material or in the Appropriate Legal | ||
| 370 | + Notices displayed by works containing it; or | ||
| 371 | + | ||
| 372 | + c) Prohibiting misrepresentation of the origin of that material, or | ||
| 373 | + requiring that modified versions of such material be marked in | ||
| 374 | + reasonable ways as different from the original version; or | ||
| 375 | + | ||
| 376 | + d) Limiting the use for publicity purposes of names of licensors or | ||
| 377 | + authors of the material; or | ||
| 378 | + | ||
| 379 | + e) Declining to grant rights under trademark law for use of some | ||
| 380 | + trade names, trademarks, or service marks; or | ||
| 381 | + | ||
| 382 | + f) Requiring indemnification of licensors and authors of that | ||
| 383 | + material by anyone who conveys the material (or modified versions of | ||
| 384 | + it) with contractual assumptions of liability to the recipient, for | ||
| 385 | + any liability that these contractual assumptions directly impose on | ||
| 386 | + those licensors and authors. | ||
| 387 | + | ||
| 388 | + All other non-permissive additional terms are considered "further | ||
| 389 | +restrictions" within the meaning of section 10. If the Program as you | ||
| 390 | +received it, or any part of it, contains a notice stating that it is | ||
| 391 | +governed by this License along with a term that is a further | ||
| 392 | +restriction, you may remove that term. If a license document contains | ||
| 393 | +a further restriction but permits relicensing or conveying under this | ||
| 394 | +License, you may add to a covered work material governed by the terms | ||
| 395 | +of that license document, provided that the further restriction does | ||
| 396 | +not survive such relicensing or conveying. | ||
| 397 | + | ||
| 398 | + If you add terms to a covered work in accord with this section, you | ||
| 399 | +must place, in the relevant source files, a statement of the | ||
| 400 | +additional terms that apply to those files, or a notice indicating | ||
| 401 | +where to find the applicable terms. | ||
| 402 | + | ||
| 403 | + Additional terms, permissive or non-permissive, may be stated in the | ||
| 404 | +form of a separately written license, or stated as exceptions; | ||
| 405 | +the above requirements apply either way. | ||
| 406 | + | ||
| 407 | + 8. Termination. | ||
| 408 | + | ||
| 409 | + You may not propagate or modify a covered work except as expressly | ||
| 410 | +provided under this License. Any attempt otherwise to propagate or | ||
| 411 | +modify it is void, and will automatically terminate your rights under | ||
| 412 | +this License (including any patent licenses granted under the third | ||
| 413 | +paragraph of section 11). | ||
| 414 | + | ||
| 415 | + However, if you cease all violation of this License, then your | ||
| 416 | +license from a particular copyright holder is reinstated (a) | ||
| 417 | +provisionally, unless and until the copyright holder explicitly and | ||
| 418 | +finally terminates your license, and (b) permanently, if the copyright | ||
| 419 | +holder fails to notify you of the violation by some reasonable means | ||
| 420 | +prior to 60 days after the cessation. | ||
| 421 | + | ||
| 422 | + Moreover, your license from a particular copyright holder is | ||
| 423 | +reinstated permanently if the copyright holder notifies you of the | ||
| 424 | +violation by some reasonable means, this is the first time you have | ||
| 425 | +received notice of violation of this License (for any work) from that | ||
| 426 | +copyright holder, and you cure the violation prior to 30 days after | ||
| 427 | +your receipt of the notice. | ||
| 428 | + | ||
| 429 | + Termination of your rights under this section does not terminate the | ||
| 430 | +licenses of parties who have received copies or rights from you under | ||
| 431 | +this License. If your rights have been terminated and not permanently | ||
| 432 | +reinstated, you do not qualify to receive new licenses for the same | ||
| 433 | +material under section 10. | ||
| 434 | + | ||
| 435 | + 9. Acceptance Not Required for Having Copies. | ||
| 436 | + | ||
| 437 | + You are not required to accept this License in order to receive or | ||
| 438 | +run a copy of the Program. Ancillary propagation of a covered work | ||
| 439 | +occurring solely as a consequence of using peer-to-peer transmission | ||
| 440 | +to receive a copy likewise does not require acceptance. However, | ||
| 441 | +nothing other than this License grants you permission to propagate or | ||
| 442 | +modify any covered work. These actions infringe copyright if you do | ||
| 443 | +not accept this License. Therefore, by modifying or propagating a | ||
| 444 | +covered work, you indicate your acceptance of this License to do so. | ||
| 445 | + | ||
| 446 | + 10. Automatic Licensing of Downstream Recipients. | ||
| 447 | + | ||
| 448 | + Each time you convey a covered work, the recipient automatically | ||
| 449 | +receives a license from the original licensors, to run, modify and | ||
| 450 | +propagate that work, subject to this License. You are not responsible | ||
| 451 | +for enforcing compliance by third parties with this License. | ||
| 452 | + | ||
| 453 | + An "entity transaction" is a transaction transferring control of an | ||
| 454 | +organization, or substantially all assets of one, or subdividing an | ||
| 455 | +organization, or merging organizations. If propagation of a covered | ||
| 456 | +work results from an entity transaction, each party to that | ||
| 457 | +transaction who receives a copy of the work also receives whatever | ||
| 458 | +licenses to the work the party's predecessor in interest had or could | ||
| 459 | +give under the previous paragraph, plus a right to possession of the | ||
| 460 | +Corresponding Source of the work from the predecessor in interest, if | ||
| 461 | +the predecessor has it or can get it with reasonable efforts. | ||
| 462 | + | ||
| 463 | + You may not impose any further restrictions on the exercise of the | ||
| 464 | +rights granted or affirmed under this License. For example, you may | ||
| 465 | +not impose a license fee, royalty, or other charge for exercise of | ||
| 466 | +rights granted under this License, and you may not initiate litigation | ||
| 467 | +(including a cross-claim or counterclaim in a lawsuit) alleging that | ||
| 468 | +any patent claim is infringed by making, using, selling, offering for | ||
| 469 | +sale, or importing the Program or any portion of it. | ||
| 470 | + | ||
| 471 | + 11. Patents. | ||
| 472 | + | ||
| 473 | + A "contributor" is a copyright holder who authorizes use under this | ||
| 474 | +License of the Program or a work on which the Program is based. The | ||
| 475 | +work thus licensed is called the contributor's "contributor version". | ||
| 476 | + | ||
| 477 | + A contributor's "essential patent claims" are all patent claims | ||
| 478 | +owned or controlled by the contributor, whether already acquired or | ||
| 479 | +hereafter acquired, that would be infringed by some manner, permitted | ||
| 480 | +by this License, of making, using, or selling its contributor version, | ||
| 481 | +but do not include claims that would be infringed only as a | ||
| 482 | +consequence of further modification of the contributor version. For | ||
| 483 | +purposes of this definition, "control" includes the right to grant | ||
| 484 | +patent sublicenses in a manner consistent with the requirements of | ||
| 485 | +this License. | ||
| 486 | + | ||
| 487 | + Each contributor grants you a non-exclusive, worldwide, royalty-free | ||
| 488 | +patent license under the contributor's essential patent claims, to | ||
| 489 | +make, use, sell, offer for sale, import and otherwise run, modify and | ||
| 490 | +propagate the contents of its contributor version. | ||
| 491 | + | ||
| 492 | + In the following three paragraphs, a "patent license" is any express | ||
| 493 | +agreement or commitment, however denominated, not to enforce a patent | ||
| 494 | +(such as an express permission to practice a patent or covenant not to | ||
| 495 | +sue for patent infringement). To "grant" such a patent license to a | ||
| 496 | +party means to make such an agreement or commitment not to enforce a | ||
| 497 | +patent against the party. | ||
| 498 | + | ||
| 499 | + If you convey a covered work, knowingly relying on a patent license, | ||
| 500 | +and the Corresponding Source of the work is not available for anyone | ||
| 501 | +to copy, free of charge and under the terms of this License, through a | ||
| 502 | +publicly available network server or other readily accessible means, | ||
| 503 | +then you must either (1) cause the Corresponding Source to be so | ||
| 504 | +available, or (2) arrange to deprive yourself of the benefit of the | ||
| 505 | +patent license for this particular work, or (3) arrange, in a manner | ||
| 506 | +consistent with the requirements of this License, to extend the patent | ||
| 507 | +license to downstream recipients. "Knowingly relying" means you have | ||
| 508 | +actual knowledge that, but for the patent license, your conveying the | ||
| 509 | +covered work in a country, or your recipient's use of the covered work | ||
| 510 | +in a country, would infringe one or more identifiable patents in that | ||
| 511 | +country that you have reason to believe are valid. | ||
| 512 | + | ||
| 513 | + If, pursuant to or in connection with a single transaction or | ||
| 514 | +arrangement, you convey, or propagate by procuring conveyance of, a | ||
| 515 | +covered work, and grant a patent license to some of the parties | ||
| 516 | +receiving the covered work authorizing them to use, propagate, modify | ||
| 517 | +or convey a specific copy of the covered work, then the patent license | ||
| 518 | +you grant is automatically extended to all recipients of the covered | ||
| 519 | +work and works based on it. | ||
| 520 | + | ||
| 521 | + A patent license is "discriminatory" if it does not include within | ||
| 522 | +the scope of its coverage, prohibits the exercise of, or is | ||
| 523 | +conditioned on the non-exercise of one or more of the rights that are | ||
| 524 | +specifically granted under this License. You may not convey a covered | ||
| 525 | +work if you are a party to an arrangement with a third party that is | ||
| 526 | +in the business of distributing software, under which you make payment | ||
| 527 | +to the third party based on the extent of your activity of conveying | ||
| 528 | +the work, and under which the third party grants, to any of the | ||
| 529 | +parties who would receive the covered work from you, a discriminatory | ||
| 530 | +patent license (a) in connection with copies of the covered work | ||
| 531 | +conveyed by you (or copies made from those copies), or (b) primarily | ||
| 532 | +for and in connection with specific products or compilations that | ||
| 533 | +contain the covered work, unless you entered into that arrangement, | ||
| 534 | +or that patent license was granted, prior to 28 March 2007. | ||
| 535 | + | ||
| 536 | + Nothing in this License shall be construed as excluding or limiting | ||
| 537 | +any implied license or other defenses to infringement that may | ||
| 538 | +otherwise be available to you under applicable patent law. | ||
| 539 | + | ||
| 540 | + 12. No Surrender of Others' Freedom. | ||
| 541 | + | ||
| 542 | + If conditions are imposed on you (whether by court order, agreement or | ||
| 543 | +otherwise) that contradict the conditions of this License, they do not | ||
| 544 | +excuse you from the conditions of this License. If you cannot convey a | ||
| 545 | +covered work so as to satisfy simultaneously your obligations under this | ||
| 546 | +License and any other pertinent obligations, then as a consequence you may | ||
| 547 | +not convey it at all. For example, if you agree to terms that obligate you | ||
| 548 | +to collect a royalty for further conveying from those to whom you convey | ||
| 549 | +the Program, the only way you could satisfy both those terms and this | ||
| 550 | +License would be to refrain entirely from conveying the Program. | ||
| 551 | + | ||
| 552 | + 13. Use with the GNU Affero General Public License. | ||
| 553 | + | ||
| 554 | + Notwithstanding any other provision of this License, you have | ||
| 555 | +permission to link or combine any covered work with a work licensed | ||
| 556 | +under version 3 of the GNU Affero General Public License into a single | ||
| 557 | +combined work, and to convey the resulting work. The terms of this | ||
| 558 | +License will continue to apply to the part which is the covered work, | ||
| 559 | +but the special requirements of the GNU Affero General Public License, | ||
| 560 | +section 13, concerning interaction through a network will apply to the | ||
| 561 | +combination as such. | ||
| 562 | + | ||
| 563 | + 14. Revised Versions of this License. | ||
| 564 | + | ||
| 565 | + The Free Software Foundation may publish revised and/or new versions of | ||
| 566 | +the GNU General Public License from time to time. Such new versions will | ||
| 567 | +be similar in spirit to the present version, but may differ in detail to | ||
| 568 | +address new problems or concerns. | ||
| 569 | + | ||
| 570 | + Each version is given a distinguishing version number. If the | ||
| 571 | +Program specifies that a certain numbered version of the GNU General | ||
| 572 | +Public License "or any later version" applies to it, you have the | ||
| 573 | +option of following the terms and conditions either of that numbered | ||
| 574 | +version or of any later version published by the Free Software | ||
| 575 | +Foundation. If the Program does not specify a version number of the | ||
| 576 | +GNU General Public License, you may choose any version ever published | ||
| 577 | +by the Free Software Foundation. | ||
| 578 | + | ||
| 579 | + If the Program specifies that a proxy can decide which future | ||
| 580 | +versions of the GNU General Public License can be used, that proxy's | ||
| 581 | +public statement of acceptance of a version permanently authorizes you | ||
| 582 | +to choose that version for the Program. | ||
| 583 | + | ||
| 584 | + Later license versions may give you additional or different | ||
| 585 | +permissions. However, no additional obligations are imposed on any | ||
| 586 | +author or copyright holder as a result of your choosing to follow a | ||
| 587 | +later version. | ||
| 588 | + | ||
| 589 | + 15. Disclaimer of Warranty. | ||
| 590 | + | ||
| 591 | + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | ||
| 592 | +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | ||
| 593 | +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | ||
| 594 | +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | ||
| 595 | +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 596 | +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | ||
| 597 | +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | ||
| 598 | +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||
| 599 | + | ||
| 600 | + 16. Limitation of Liability. | ||
| 601 | + | ||
| 602 | + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
| 603 | +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | ||
| 604 | +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | ||
| 605 | +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||
| 606 | +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | ||
| 607 | +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | ||
| 608 | +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | ||
| 609 | +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | ||
| 610 | +SUCH DAMAGES. | ||
| 611 | + | ||
| 612 | + 17. Interpretation of Sections 15 and 16. | ||
| 613 | + | ||
| 614 | + If the disclaimer of warranty and limitation of liability provided | ||
| 615 | +above cannot be given local legal effect according to their terms, | ||
| 616 | +reviewing courts shall apply local law that most closely approximates | ||
| 617 | +an absolute waiver of all civil liability in connection with the | ||
| 618 | +Program, unless a warranty or assumption of liability accompanies a | ||
| 619 | +copy of the Program in return for a fee. | ||
| 620 | + | ||
| 621 | + END OF TERMS AND CONDITIONS | ||
| 622 | + | ||
| 623 | + How to Apply These Terms to Your New Programs | ||
| 624 | + | ||
| 625 | + If you develop a new program, and you want it to be of the greatest | ||
| 626 | +possible use to the public, the best way to achieve this is to make it | ||
| 627 | +free software which everyone can redistribute and change under these terms. | ||
| 628 | + | ||
| 629 | + To do so, attach the following notices to the program. It is safest | ||
| 630 | +to attach them to the start of each source file to most effectively | ||
| 631 | +state the exclusion of warranty; and each file should have at least | ||
| 632 | +the "copyright" line and a pointer to where the full notice is found. | ||
| 633 | + | ||
| 634 | + <one line to give the program's name and a brief idea of what it does.> | ||
| 635 | + Copyright (C) <year> <name of author> | ||
| 636 | + | ||
| 637 | + This program is free software: you can redistribute it and/or modify | ||
| 638 | + it under the terms of the GNU General Public License as published by | ||
| 639 | + the Free Software Foundation, either version 3 of the License, or | ||
| 640 | + (at your option) any later version. | ||
| 641 | + | ||
| 642 | + This program is distributed in the hope that it will be useful, | ||
| 643 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 644 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 645 | + GNU General Public License for more details. | ||
| 646 | + | ||
| 647 | + You should have received a copy of the GNU General Public License | ||
| 648 | + along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| 649 | + | ||
| 650 | +Also add information on how to contact you by electronic and paper mail. | ||
| 651 | + | ||
| 652 | + If the program does terminal interaction, make it output a short | ||
| 653 | +notice like this when it starts in an interactive mode: | ||
| 654 | + | ||
| 655 | + <program> Copyright (C) <year> <name of author> | ||
| 656 | + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
| 657 | + This is free software, and you are welcome to redistribute it | ||
| 658 | + under certain conditions; type `show c' for details. | ||
| 659 | + | ||
| 660 | +The hypothetical commands `show w' and `show c' should show the appropriate | ||
| 661 | +parts of the General Public License. Of course, your program's commands | ||
| 662 | +might be different; for a GUI interface, you would use an "about box". | ||
| 663 | + | ||
| 664 | + You should also get your employer (if you work as a programmer) or school, | ||
| 665 | +if any, to sign a "copyright disclaimer" for the program, if necessary. | ||
| 666 | +For more information on this, and how to apply and follow the GNU GPL, see | ||
| 667 | +<https://www.gnu.org/licenses/>. | ||
| 668 | + | ||
| 669 | + The GNU General Public License does not permit incorporating your program | ||
| 670 | +into proprietary programs. If your program is a subroutine library, you | ||
| 671 | +may consider it more useful to permit linking proprietary applications with | ||
| 672 | +the library. If this is what you want to do, use the GNU Lesser General | ||
| 673 | +Public License instead of this License. But first, please read | ||
| 674 | +<https://www.gnu.org/licenses/why-not-lgpl.html>. |
README.md
0 → 100644
| 1 | +## RVM Inference | ||
| 2 | +<div align='left'> | ||
| 3 | + <img src=https://img.shields.io/github/stars/DefTruth/RobustVideoMatting.lite.ai.toolkit.svg?style=social > | ||
| 4 | + <img src=https://img.shields.io/github/forks/DefTruth/RobustVideoMatting.lite.ai.toolkit.svg?style=social > | ||
| 5 | + <img src=https://img.shields.io/github/watchers/DefTruth/RobustVideoMatting.lite.ai.toolkit.svg?style=social> | ||
| 6 | +</div> | ||
| 7 | + | ||
| 8 | +## News 👇👇 | ||
| 9 | +Most of my time now is focused on **LLM/VLM** Inference. Please check 📖[Awesome-LLM-Inference](https://github.com/DefTruth/Awesome-LLM-Inference) , 📖[Awesome-SD-Inference](https://github.com/DefTruth/Awesome-SD-Inference)  and 📖[CUDA-Learn-Notes](https://github.com/DefTruth/CUDA-Learn-Notes)  for more details. | ||
| 10 | + | ||
| 11 | +## 1. 简介 | ||
| 12 | +使用Lite.AI.ToolKit C++工具箱来跑RobustVideoMatting的一些案例(https://github.com/DefTruth/lite.ai.toolkit) ,ONNXRuntime、MNN、NCNN和TNN四个版本。 | ||
| 13 | + | ||
| 14 | +<div align='center'> | ||
| 15 | + <img src='resources/interviewi.gif' height="80px" width="160px"> | ||
| 16 | + <img src='resources/interview.gif' height="80px" width="160px"> | ||
| 17 | + <img src='resources/dance3i.gif' height="80px" width="160px"> | ||
| 18 | + <img src='resources/dance3.gif' height="80px" width="160px"> | ||
| 19 | + <br> | ||
| 20 | + <img src='resources/teslai.gif' height="80px" width="160px"> | ||
| 21 | + <img src='resources/tesla.gif' height="80px" width="160px"> | ||
| 22 | + <img src='resources/b5i.gif' height="80px" width="160px"> | ||
| 23 | + <img src='resources/b5.gif' height="80px" width="160px"> | ||
| 24 | +</div> | ||
| 25 | + | ||
| 26 | +若是有用,❤️不妨给个⭐️🌟支持一下吧~ 🙃🤪🍀 | ||
| 27 | + | ||
| 28 | +## 2. C++版本源码 | ||
| 29 | + | ||
| 30 | +RobustVideoMatting C++ 版本的源码包含ONNXRuntime、MNN、NCNN和TNN四个版本,可以在 [lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) 工具箱中找到。本项目主要介绍如何基于 [lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) 工具箱,直接使用RobustVideoMatting实现视频抠图和图片抠图。需要说明的是,本项目是基于MacOS下编译的 [liblite.ai.toolkit.v0.1.0.dylib](https://github.com/DefTruth/RobustVideoMatting.lite.ai.toolkit/blob/main/lite.ai.toolkit/lib) 来实现的,对于使用MacOS的用户,可以直接下载本项目包含的*liblite.ai.toolkit.v0.1.0*动态库和其他依赖库进行使用。而非MacOS用户,则需要从[lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) 中下载源码进行编译。[lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) c++工具箱目前包含70+流行的开源模型。 | ||
| 31 | + * [rvm.cpp](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ort/cv/rvm.cpp) | ||
| 32 | + * [rvm.h](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ort/cv/rvm.h) | ||
| 33 | + * [mnn_rvm.cpp](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/mnn/cv/mnn_rvm.cpp) | ||
| 34 | + * [mnn_rvm.h](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/mnn/cv/mnn_rvm.h) | ||
| 35 | + * [ncnn_rvm.cpp](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ncnn/cv/ncnn_rvm.cpp) | ||
| 36 | + * [ncnn_rvm.h](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/ncnn/cv/ncnn_rvm.h) | ||
| 37 | + * [tnn_rvm.cpp](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/tnn/cv/tnn_rvm.cpp) | ||
| 38 | + * [tnn_rvm.h](https://github.com/DefTruth/lite.ai.toolkit/blob/main/lite/tnn/cv/tnn_rvm.h) | ||
| 39 | + | ||
| 40 | +NCNN版本的测试没有通过,转换的模型可能有问题,这里先放出代码。这里案例使用的接口是默认版本,即ONNXRuntime. 目前ONNXRuntime、MNN和TNN版本均已测试通过。 | ||
| 41 | + | ||
| 42 | +## 3. 模型文件 | ||
| 43 | + | ||
| 44 | +### 3.1 ONNX模型文件 | ||
| 45 | +可以从我提供的链接下载 ([Baidu Drive](https://pan.baidu.com/s/1elUGcx7CZkkjEoYhTMwTRQ) code: 8gin) , 也可以从 [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) 官方仓库下载。 | ||
| 46 | + | ||
| 47 | +| Class | Pretrained ONNX Files | Rename or Converted From (Repo) | Size | | ||
| 48 | +| :---------------------------------: | :-------------------: | :-------------------------------------------------------: | :---: | | ||
| 49 | +| *lite::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32.onnx | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 50 | +| *lite::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp16.onnx | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 7.2Mb | | ||
| 51 | +| *lite::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32.onnx | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 52 | +| *lite::cv::matting::RobustVideoMatting* | rvm_resnet50_fp16.onnx | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 100Mb | | ||
| 53 | + | ||
| 54 | +### 3.2 MNN模型文件 | ||
| 55 | +可以从我提供的链接下载 ([Baidu Drive](https://pan.baidu.com/s/1KyO-bCYUv6qPq2M8BH_Okg) code: 9v63) | ||
| 56 | + | ||
| 57 | +| Class | Pretrained MNN Files | Rename or Converted From (Repo) | Size | | ||
| 58 | +| :---------------------------------: | :-------------------: | :-------------------------------------------------------: | :---: | | ||
| 59 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 60 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-480.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 61 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-640.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 62 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-640-480.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 63 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-1080-1920.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 64 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 65 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-480.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 66 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-640.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 67 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-640-480.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 68 | +| *lite::mnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-1080-1920.mnn | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 69 | + | ||
| 70 | +### 3.3 NCNN模型文件 | ||
| 71 | +可以从我提供的链接下载 ([Baidu Drive](https://pan.baidu.com/s/1hlnqyNsFbMseGFWscgVhgQ) code: sc7f) | ||
| 72 | + | ||
| 73 | +| Class | Pretrained NCNN Files | Rename or Converted From (Repo) | Size | | ||
| 74 | +| :---------------------------------: | :-------------------: | :-------------------------------------------------------: | :---: | | ||
| 75 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 76 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-480-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 77 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-640-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 78 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-640-480-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 79 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-1080-1920-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 80 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 81 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-480-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 82 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-640-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 83 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-640-480-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 84 | +| *lite::ncnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-1080-1920-opt.param&bin | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 85 | + | ||
| 86 | +### 3.4 TNN模型文件 | ||
| 87 | +可以从我提供的链接下载 ([Baidu Drive](https://pan.baidu.com/s/1lvM2YKyUbEc5HKVtqITpcw) code: 6o6k) | ||
| 88 | + | ||
| 89 | +| Class | Pretrained TNN Files | Rename or Converted From (Repo) | Size | | ||
| 90 | +| :---------------------------------: | :-------------------: | :-------------------------------------------------------: | :---: | | ||
| 91 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-480-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 92 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-480-640-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 93 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-640-480-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 94 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_mobilenetv3_fp32-1080-1920-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 14Mb | | ||
| 95 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-480-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 96 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-480-640-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 97 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-640-480-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 98 | +| *lite::tnn::cv::matting::RobustVideoMatting* | rvm_resnet50_fp32-1080-1920-sim.tnnproto&tnnmodel | [RobustVideoMatting](https://github.com/PeterL1n/RobustVideoMatting) | 50Mb | | ||
| 99 | + | ||
| 100 | + | ||
| 101 | +## 4. 接口文档 | ||
| 102 | + | ||
| 103 | +在[lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) 中,RobustVideoMatting的实现类为: | ||
| 104 | + | ||
| 105 | +```c++ | ||
| 106 | +class LITE_EXPORTS lite::cv::matting::RobustVideoMatting; | ||
| 107 | +class LITE_EXPORTS lite::mnn::cv::matting::RobustVideoMatting; | ||
| 108 | +class LITE_EXPORTS lite::tnn::cv::matting::RobustVideoMatting; | ||
| 109 | +class LITE_EXPORTS lite::ncnn::cv::matting::RobustVideoMatting; | ||
| 110 | +``` | ||
| 111 | + | ||
| 112 | +该类型目前包含两个公共接口,分别是`detect`和`detect_video`,前者用于图像抠图,后者用于视频抠图。不同推理引擎的实现,接口基本相同。TNN、MNN和NCNN版本的接口不含downsample_ratio,因为转换时,我是按照静态维度转换的,并且在转换模型时固定了一个合适的downsample_ratio,不需要再推理时再设置。具体区别可以跳转到c++实现的源码查看。 | ||
| 113 | +```c++ | ||
| 114 | + /** | ||
| 115 | + * Image Matting Using RVM(https://github.com/PeterL1n/RobustVideoMatting) | ||
| 116 | + * @param mat: cv::Mat BGR HWC | ||
| 117 | + * @param content: types::MattingContent to catch the detected results. | ||
| 118 | + * @param downsample_ratio: 0.25 by default. | ||
| 119 | + * See https://github.com/PeterL1n/RobustVideoMatting/blob/master/documentation/inference_zh_Hans.md | ||
| 120 | + */ | ||
| 121 | + void detect(const cv::Mat &mat, types::MattingContent &content, | ||
| 122 | + float downsample_ratio = 0.25f); | ||
| 123 | + /** | ||
| 124 | + * Video Matting Using RVM(https://github.com/PeterL1n/RobustVideoMatting) | ||
| 125 | + * @param video_path: eg. xxx/xxx/input.mp4 | ||
| 126 | + * @param output_path: eg. xxx/xxx/output.mp4 | ||
| 127 | + * @param contents: vector of MattingContent to catch the detected results. | ||
| 128 | + * @param save_contents: false by default, whether to save MattingContent. | ||
| 129 | + * @param downsample_ratio: 0.25 by default. | ||
| 130 | + * See https://github.com/PeterL1n/RobustVideoMatting/blob/master/documentation/inference_zh_Hans.md | ||
| 131 | + * @param writer_fps: FPS for VideoWriter, 20 by default. | ||
| 132 | + */ | ||
| 133 | + void detect_video(const std::string &video_path, | ||
| 134 | + const std::string &output_path, | ||
| 135 | + std::vector<types::MattingContent> &contents, | ||
| 136 | + bool save_contents = false, | ||
| 137 | + float downsample_ratio = 0.25f, | ||
| 138 | + unsigned int writer_fps = 20); | ||
| 139 | +``` | ||
| 140 | + | ||
| 141 | +* `detect`接口输入参数说明: | ||
| 142 | + * mat: cv::Mat BGR格式图像 | ||
| 143 | + * content: types::MattingContent类型,用来保存检测的结果,包含类型为cv::Mat的三个成员,分别是 | ||
| 144 | + * `fgr_mat`: `cv::Mat (H,W,C=3) BGR` 格式,值范围为0~255 的 `CV_8UC3`, 用于保存估计的前景 | ||
| 145 | + * `pha_mat`:` cv::Mat (H,W,C=1)` 值范围为0.~1.的 `CV_32FC1`, 用于保存估计的alpha(matte)值 | ||
| 146 | + * `merge_mat`: `cv::Mat (H,W,C=3) BGR` 格式,值范围为0~255 的 `CV_8UC3`, 用于保存根据pha融合前景背景的合成图像 | ||
| 147 | + * `flag`: bool 类型标志位,表示是否检测成功 | ||
| 148 | + * downsample_ratio: float,下采样比率,默认0.25f,值的设置可以参考[官方文档](https://github.com/PeterL1n/RobustVideoMatting/blob/master/documentation/inference_zh_Hans.md) , 如下: | ||
| 149 | + | ||
| 150 | + | 分辨率 | 人像 | 全身 | | ||
| 151 | + | ------------- | ------------- | -------------- | | ||
| 152 | + | <= 512x512 | 1 | 1 | | ||
| 153 | + | 1280x720 | 0.375 | 0.6 | | ||
| 154 | + | 1920x1080 | 0.25 | 0.4 | | ||
| 155 | + | 3840x2160 | 0.125 | 0.2 | | ||
| 156 | + | ||
| 157 | + 模型在内部将高分辨率输入缩小做初步的处理,然后再放大做细分处理。 建议设置 `downsample_ratio` 使缩小后的分辨率维持在 256 到 512 像素之间. 例如,`1920x1080` 的输入用 `downsample_ratio=0.25`,缩小后的分辨率 `480x270` 在 256 到 512 像素之间。 根据视频内容调整 `downsample_ratio`。若视频是上身人像,低 `downsample_ratio` 足矣。若视频是全身像,建议尝试更高的 `downsample_ratio`。但注意,过高的 `downsample_ratio` 反而会降低效果。 | ||
| 158 | + | ||
| 159 | + | ||
| 160 | +* `detect_video`接口输入参数说明: | ||
| 161 | + * video_path: string, 输入的视频路径 | ||
| 162 | + * output_path: string, 输出的视频路径 | ||
| 163 | + * contents:MattingContent类型的vector,用来保存每帧检测的结果 | ||
| 164 | + * save_contents:bool,是否保存每一帧的结果,默认false。当分辨率很大时,保存所有的结果将会占用非常多内存 | ||
| 165 | + * downsample_ratio: float,下采样比率,默认0.25f,同上。 | ||
| 166 | + * writer_fps:int 视频写出的帧率,默认20 | ||
| 167 | + | ||
| 168 | +## 5. 使用案例 | ||
| 169 | +这里测试使用的是mobilenetv3版本的rvm模型,如果你使用resnet50版本的模型,将会得到更高精度的结果。 | ||
| 170 | + | ||
| 171 | +### 5.1 图像抠图案例 | ||
| 172 | + | ||
| 173 | +```c++ | ||
| 174 | +#include "lite/lite.h" | ||
| 175 | + | ||
| 176 | +// Image Matting Interface | ||
| 177 | +static void test_image() | ||
| 178 | +{ | ||
| 179 | + std::string onnx_path = "../hub/onnx/cv/rvm_mobilenetv3_fp32.onnx"; | ||
| 180 | + std::string img_path = "../examples/lite/resources/test.jpg"; | ||
| 181 | + std::string save_fgr_path = "../logs/test_lite_rvm_fgr.jpg"; | ||
| 182 | + std::string save_pha_path = "../logs/test_rvm_pha.jpg"; | ||
| 183 | + std::string save_merge_path = "../logs/test_lite_rvm_merge.jpg"; | ||
| 184 | + | ||
| 185 | + auto *rvm = new lite::matting::RobustVideoMatting(onnx_path, 16); // 16 threads | ||
| 186 | + lite::types::MattingContent content; | ||
| 187 | + cv::Mat img_bgr = cv::imread(img_path); | ||
| 188 | + | ||
| 189 | + // 1. image matting. | ||
| 190 | + rvm->detect(img_bgr, content, 0.25f); | ||
| 191 | + | ||
| 192 | + if (content.flag) | ||
| 193 | + { | ||
| 194 | + if (!content.fgr_mat.empty()) cv::imwrite(save_fgr_path, content.fgr_mat); // 预测的前景fgr | ||
| 195 | + if (!content.pha_mat.empty()) cv::imwrite(save_pha_path, content.pha_mat * 255.); // 预测的前景pha | ||
| 196 | + if (!content.merge_mat.empty()) cv::imwrite(save_merge_path, content.merge_mat); // 合成图 | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + delete rvm; | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +``` | ||
| 203 | +* 输出结果为: (依次为原图、预测的pha、预测的前景fgr、合成图) | ||
| 204 | + | ||
| 205 | +<div align='center'> | ||
| 206 | + <img src='resources/test.jpg' height="160px" width="160px"> | ||
| 207 | + <img src='resources/test_rvm_pha.jpg' height="160px" width="160px"> | ||
| 208 | + <img src='resources/test_rvm_fgr.jpg' height="160px" width="160px"> | ||
| 209 | + <img src='resources/test_rvm_merge.jpg' height="160px" width="160px"> | ||
| 210 | +</div> | ||
| 211 | + | ||
| 212 | +### 5.2 视频抠图案例 | ||
| 213 | + | ||
| 214 | +#### 5.2.1 ONNXRuntime版本 | ||
| 215 | +```c++ | ||
| 216 | + | ||
| 217 | +#include "lite/lite.h" | ||
| 218 | + | ||
| 219 | +// Video Matting Interface | ||
| 220 | +static void test_video() | ||
| 221 | +{ | ||
| 222 | + std::string onnx_path = "../hub/onnx/cv/rvm_mobilenetv3_fp32.onnx"; | ||
| 223 | + std::string video_path = "../examples/lite/resources/tesla.mp4"; | ||
| 224 | + std::string output_path = "../logs/tesla_onnx.mp4"; | ||
| 225 | + | ||
| 226 | + auto *rvm = new lite::cv::matting::RobustVideoMatting(onnx_path, 16); // 16 threads | ||
| 227 | + std::vector<lite::types::MattingContent> contents; | ||
| 228 | + | ||
| 229 | + // 1. video matting. | ||
| 230 | + rvm->detect_video(video_path, output_path, contents, false, 0.4f); | ||
| 231 | + | ||
| 232 | + delete rvm; | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +``` | ||
| 236 | + | ||
| 237 | +#### 5.2.2 MNN版本 | ||
| 238 | +```c++ | ||
| 239 | +static void test_mnn() | ||
| 240 | +{ | ||
| 241 | +#ifdef ENABLE_MNN | ||
| 242 | + std::string mnn_path = "../hub/mnn/cv/rvm_mobilenetv3_fp32-480-640.mnn"; | ||
| 243 | + std::string video_path = "../examples/lite/resources/tesla.mp4"; | ||
| 244 | + std::string output_path = "../logs/tesla_mnn.mp4"; | ||
| 245 | + | ||
| 246 | + auto *rvm = new lite::mnn::cv::matting::RobustVideoMatting(mnn_path, 16, 0); // 16 threads | ||
| 247 | + std::vector<lite::types::MattingContent> contents; | ||
| 248 | + | ||
| 249 | + // 1. video matting. | ||
| 250 | + rvm->detect_video(video_path, output_path, contents, false); | ||
| 251 | + | ||
| 252 | + delete rvm; | ||
| 253 | +#endif | ||
| 254 | +} | ||
| 255 | +``` | ||
| 256 | +#### 5.2.3 TNN版本 | ||
| 257 | +```C++ | ||
| 258 | +static void test_tnn() | ||
| 259 | +{ | ||
| 260 | +#ifdef ENABLE_TNN | ||
| 261 | + | ||
| 262 | + std::string proto_path = "../hub/tnn/cv/rvm_mobilenetv3_fp32-480-480-sim.opt.tnnproto"; | ||
| 263 | + std::string model_path = "../hub/tnn/cv/rvm_mobilenetv3_fp32-480-480-sim.opt.tnnmodel"; | ||
| 264 | + std::string video_path = "../examples/lite/resources/test_lite_rvm_1.mp4"; | ||
| 265 | + std::string output_path = "../logs/test_lite_rvm_1_tnn.mp4"; | ||
| 266 | + | ||
| 267 | + auto *rvm = new lite::tnn::cv::matting::RobustVideoMatting( | ||
| 268 | + proto_path, model_path, 16); // 16 threads | ||
| 269 | + std::vector<lite::types::MattingContent> contents; | ||
| 270 | + | ||
| 271 | + // 1. video matting. | ||
| 272 | + rvm->detect_video(video_path, output_path, contents, false); | ||
| 273 | + | ||
| 274 | + delete rvm; | ||
| 275 | +#endif | ||
| 276 | +} | ||
| 277 | +``` | ||
| 278 | + | ||
| 279 | +* 输出结果为: | ||
| 280 | + | ||
| 281 | +<div align='center'> | ||
| 282 | + <img src='resources/interviewi.gif' height="80px" width="160px"> | ||
| 283 | + <img src='resources/interview.gif' height="80px" width="160px"> | ||
| 284 | + <img src='resources/dance3i.gif' height="80px" width="160px"> | ||
| 285 | + <img src='resources/dance3.gif' height="80px" width="160px"> | ||
| 286 | + <br> | ||
| 287 | + <img src='resources/teslai.gif' height="80px" width="160px"> | ||
| 288 | + <img src='resources/tesla.gif' height="80px" width="160px"> | ||
| 289 | + <img src='resources/b5i.gif' height="80px" width="160px"> | ||
| 290 | + <img src='resources/b5.gif' height="80px" width="160px"> | ||
| 291 | +</div> | ||
| 292 | + | ||
| 293 | +## 6. 编译运行 | ||
| 294 | +在MacOS下可以直接编译运行本项目,无需下载其他依赖库。其他系统则需要从[lite.ai.toolkit](https://github.com/DefTruth/lite.ai.toolkit) 中下载源码先编译*lite.ai.toolkit.v0.1.0*动态库。 | ||
| 295 | +```shell | ||
| 296 | +git clone --depth=1 https://github.com/DefTruth/RobustVideoMatting.lite.ai.toolkit.git | ||
| 297 | +cd RobustVideoMatting.lite.ai.toolkit | ||
| 298 | +sh ./build.sh | ||
| 299 | +``` | ||
| 300 | +* CMakeLists.txt设置 | ||
| 301 | +```cmake | ||
| 302 | +cmake_minimum_required(VERSION 3.17) | ||
| 303 | +project(RobustVideoMatting.lite.ai.toolkit) | ||
| 304 | + | ||
| 305 | +set(CMAKE_CXX_STANDARD 11) | ||
| 306 | + | ||
| 307 | +# setting up lite.ai.toolkit | ||
| 308 | +set(LITE_AI_DIR ${CMAKE_SOURCE_DIR}/lite.ai.toolkit) | ||
| 309 | +set(LITE_AI_INCLUDE_DIR ${LITE_AI_DIR}/include) | ||
| 310 | +set(LITE_AI_LIBRARY_DIR ${LITE_AI_DIR}/lib) | ||
| 311 | +include_directories(${LITE_AI_INCLUDE_DIR}) | ||
| 312 | +link_directories(${LITE_AI_LIBRARY_DIR}) | ||
| 313 | + | ||
| 314 | +set(OpenCV_LIBS | ||
| 315 | + opencv_highgui | ||
| 316 | + opencv_core | ||
| 317 | + opencv_imgcodecs | ||
| 318 | + opencv_imgproc | ||
| 319 | + opencv_video | ||
| 320 | + opencv_videoio | ||
| 321 | + ) | ||
| 322 | +# add your executable | ||
| 323 | +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/examples/build) | ||
| 324 | + | ||
| 325 | +add_executable(lite_rvm examples/test_lite_rvm.cpp) | ||
| 326 | +target_link_libraries(lite_rvm | ||
| 327 | + lite.ai.toolkit | ||
| 328 | + onnxruntime | ||
| 329 | + MNN # need, if built lite.ai.toolkit with ENABLE_MNN=ON, default OFF | ||
| 330 | + ncnn # need, if built lite.ai.toolkit with ENABLE_NCNN=ON, default OFF | ||
| 331 | + TNN # need, if built lite.ai.toolkit with ENABLE_TNN=ON, default OFF | ||
| 332 | + ${OpenCV_LIBS}) # link lite.ai.toolkit & other libs. | ||
| 333 | +``` | ||
| 334 | + | ||
| 335 | + | ||
| 336 | +* building && testing information: | ||
| 337 | +```shell | ||
| 338 | +-- Generating done | ||
| 339 | +-- Build files have been written to: /Users/xxx/Desktop/xxx/RobustVideoMatting.lite.ai.toolkit/examples/build | ||
| 340 | +[ 50%] Building CXX object CMakeFiles/lite_rvm.dir/examples/test_lite_rvm.cpp.o | ||
| 341 | +[100%] Linking CXX executable lite_rvm | ||
| 342 | +[100%] Built target lite_rvm | ||
| 343 | +Testing Start ... | ||
| 344 | +Load ../hub/onnx/cv/rvm_mobilenetv3_fp32.onnx done! | ||
| 345 | +write done! 1/774 done! | ||
| 346 | +write done! 2/774 done! | ||
| 347 | +write done! 3/774 done! | ||
| 348 | +write done! 4/774 done! | ||
| 349 | +write done! 5/774 done! | ||
| 350 | +write done! 6/774 done! | ||
| 351 | +... | ||
| 352 | +write done! 724/774 done! | ||
| 353 | +Testing Successful ! | ||
| 354 | +``` | ||
| 355 | + | ||
| 356 | + |
build.sh
0 → 100644
| 1 | +#!/bin/bash | ||
| 2 | +if [ ! -d ./examples/build ]; then | ||
| 3 | + mkdir ./examples/build | ||
| 4 | +else | ||
| 5 | + rm -rf ./examples/build/* | ||
| 6 | +fi | ||
| 7 | + | ||
| 8 | +cd ./examples/build && cmake \ | ||
| 9 | + -DCMAKE_BUILD_TYPE=Realese\ | ||
| 10 | + -DINCLUDE_OPENCV=ON\ | ||
| 11 | + -DENABLE_MNN=OFF\ | ||
| 12 | + -DENABLE_NCNN=OFF\ | ||
| 13 | + -DENABLE_TNN=OFF\ | ||
| 14 | + ../.. && make -j1 | ||
| 15 | +echo "Testing Start ..." | ||
| 16 | +./lite_rvm | ||
| 17 | +echo "Testing Successful !" |
examples/hub/onnx/cv/.gitignore
0 → 100644
This file is too large to display.
examples/logs/.gitignore
0 → 100644
examples/resources/.gitignore
0 → 100644
examples/resources/1917.mp4
0 → 100644
This file is too large to display.
examples/resources/asianboss.mp4
0 → 100644
不能预览此文件类型
examples/resources/interview.mp4
0 → 100644
不能预览此文件类型
examples/resources/tesla.mp4
0 → 100644
不能预览此文件类型
examples/resources/test.jpg
0 → 100644
233.6 KB
examples/resources/test2.png
0 → 100644
7.9 MB
examples/test_lite_rvm.cpp
0 → 100644
| 1 | +// | ||
| 2 | +// Created by DefTruth on 2021/9/20. | ||
| 3 | +// | ||
| 4 | + | ||
| 5 | +#include "lite/lite.h" | ||
| 6 | + | ||
| 7 | +// Video Matting Interface | ||
| 8 | +static void test_video() | ||
| 9 | +{ | ||
| 10 | + std::string onnx_path = "../hub/onnx/cv/rvm_mobilenetv3_fp32.onnx"; | ||
| 11 | + std::string video_path = "../resources/interview.mp4"; | ||
| 12 | + std::string output_path = "../logs/interview_onnx.mp4"; | ||
| 13 | + | ||
| 14 | + auto *rvm = new lite::cv::matting::RobustVideoMatting(onnx_path, 16); // 16 threads | ||
| 15 | + std::vector<lite::types::MattingContent> contents; | ||
| 16 | + | ||
| 17 | + // 1. video matting. | ||
| 18 | + rvm->detect_video(video_path, output_path, contents, false, 0.25f); | ||
| 19 | + | ||
| 20 | + delete rvm; | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +// Image Matting Interface | ||
| 25 | +static void test_image() | ||
| 26 | +{ | ||
| 27 | + std::string onnx_path = "../hub/onnx/cv/rvm_mobilenetv3_fp32.onnx"; | ||
| 28 | + std::string img_path = "../resources/test.jpg"; | ||
| 29 | + std::string img_path_2 = "../resources/test2.png"; | ||
| 30 | + std::string save_fgr_path = "../logs/test_rvm_fgr.jpg"; | ||
| 31 | + std::string save_pha_path = "../logs/test_rvm_pha.jpg"; | ||
| 32 | + std::string save_merge_path = "../logs/test_rvm_merge.jpg"; | ||
| 33 | + std::string save_fgr_path_2 = "../logs/test_rvm_fgr_2.jpg"; | ||
| 34 | + std::string save_pha_path_2 = "../logs/test_rvm_pha_2.jpg"; | ||
| 35 | + std::string save_merge_path_2 = "../logs/test_rvm_merge_2.jpg"; | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + auto *rvm = new lite::cv::matting::RobustVideoMatting(onnx_path, 16); // 16 threads | ||
| 39 | + lite::types::MattingContent content, content_2; | ||
| 40 | + cv::Mat img_bgr = cv::imread(img_path); | ||
| 41 | + cv::Mat img_bgr_2 = cv::imread(img_path_2); | ||
| 42 | + | ||
| 43 | + // 1. image matting. | ||
| 44 | + rvm->detect(img_bgr, content, 0.25f); | ||
| 45 | + | ||
| 46 | + rvm->detect(img_bgr_2, content_2, 0.25f); | ||
| 47 | + | ||
| 48 | + if (content.flag) | ||
| 49 | + { | ||
| 50 | + if (!content.fgr_mat.empty()) cv::imwrite(save_fgr_path, content.fgr_mat); | ||
| 51 | + if (!content.pha_mat.empty()) cv::imwrite(save_pha_path, content.pha_mat * 255.); | ||
| 52 | + if (!content.merge_mat.empty()) cv::imwrite(save_merge_path, content.merge_mat); | ||
| 53 | + std::cout << "Saved " << save_merge_path << "\n"; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + if (content_2.flag) | ||
| 57 | + { | ||
| 58 | + if (!content_2.fgr_mat.empty()) cv::imwrite(save_fgr_path_2, content_2.fgr_mat); | ||
| 59 | + if (!content_2.pha_mat.empty()) cv::imwrite(save_pha_path_2, content_2.pha_mat * 255.); | ||
| 60 | + if (!content_2.merge_mat.empty()) cv::imwrite(save_merge_path_2, content_2.merge_mat); | ||
| 61 | + std::cout << "Saved " << save_merge_path_2 << "\n"; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + delete rvm; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | + | ||
| 68 | +static void test_rvm() | ||
| 69 | +{ | ||
| 70 | + test_video(); | ||
| 71 | + test_image(); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +int main(__unused int argc, __unused char *argv[]) | ||
| 75 | +{ | ||
| 76 | + test_rvm(); | ||
| 77 | + return 0; | ||
| 78 | +} |
lite.ai.toolkit/include/MNN/AutoTime.hpp
0 → 100644
| 1 | +// | ||
| 2 | +// AutoTime.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/07/27. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef AutoTime_hpp | ||
| 10 | +#define AutoTime_hpp | ||
| 11 | + | ||
| 12 | +#include <stdint.h> | ||
| 13 | +#include <stdio.h> | ||
| 14 | +#include <MNN/MNNDefine.h> | ||
| 15 | + | ||
| 16 | +namespace MNN { | ||
| 17 | + | ||
| 18 | +class MNN_PUBLIC Timer { | ||
| 19 | +public: | ||
| 20 | + Timer(); | ||
| 21 | + ~Timer(); | ||
| 22 | + Timer(const Timer&) = delete; | ||
| 23 | + Timer(const Timer&&) = delete; | ||
| 24 | + Timer& operator=(const Timer&) = delete; | ||
| 25 | + Timer& operator=(const Timer&&) = delete; | ||
| 26 | + | ||
| 27 | + // reset timer | ||
| 28 | + void reset(); | ||
| 29 | + // get duration (us) from init or latest reset. | ||
| 30 | + uint64_t durationInUs(); | ||
| 31 | + | ||
| 32 | +protected: | ||
| 33 | + uint64_t mLastResetTime; | ||
| 34 | +}; | ||
| 35 | + | ||
| 36 | +/** time tracing util. prints duration between init and deinit. */ | ||
| 37 | +class MNN_PUBLIC AutoTime : Timer { | ||
| 38 | +public: | ||
| 39 | + AutoTime(int line, const char* func); | ||
| 40 | + ~AutoTime(); | ||
| 41 | + AutoTime(const AutoTime&) = delete; | ||
| 42 | + AutoTime(const AutoTime&&) = delete; | ||
| 43 | + AutoTime& operator=(const AutoTime&) = delete; | ||
| 44 | + AutoTime& operator=(const AutoTime&&) = delete; | ||
| 45 | + | ||
| 46 | +private: | ||
| 47 | + int mLine; | ||
| 48 | + char* mName; | ||
| 49 | +}; | ||
| 50 | +} // namespace MNN | ||
| 51 | + | ||
| 52 | +#ifdef MNN_OPEN_TIME_TRACE | ||
| 53 | +#define AUTOTIME MNN::AutoTime ___t(__LINE__, __func__) | ||
| 54 | +#else | ||
| 55 | +#define AUTOTIME | ||
| 56 | +#endif | ||
| 57 | + | ||
| 58 | +#endif /* AutoTime_hpp */ |
lite.ai.toolkit/include/MNN/ErrorCode.hpp
0 → 100644
| 1 | +// | ||
| 2 | +// ErrorCode.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/09/18. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef ErrorCode_h | ||
| 10 | +#define ErrorCode_h | ||
| 11 | + | ||
| 12 | +namespace MNN { | ||
| 13 | +enum ErrorCode { | ||
| 14 | +#ifdef NO_ERROR | ||
| 15 | +#undef NO_ERROR | ||
| 16 | +#endif // NO_ERROR | ||
| 17 | + NO_ERROR = 0, | ||
| 18 | + OUT_OF_MEMORY = 1, | ||
| 19 | + NOT_SUPPORT = 2, | ||
| 20 | + COMPUTE_SIZE_ERROR = 3, | ||
| 21 | + NO_EXECUTION = 4, | ||
| 22 | + INVALID_VALUE = 5, | ||
| 23 | + | ||
| 24 | + // User error | ||
| 25 | + INPUT_DATA_ERROR = 10, | ||
| 26 | + CALL_BACK_STOP = 11, | ||
| 27 | + | ||
| 28 | + // Op Resize Error | ||
| 29 | + TENSOR_NOT_SUPPORT = 20, | ||
| 30 | + TENSOR_NEED_DIVIDE = 21, | ||
| 31 | +}; | ||
| 32 | +} // namespace MNN | ||
| 33 | + | ||
| 34 | +#endif /* ErrorCode_h */ |
lite.ai.toolkit/include/MNN/HalideRuntime.h
0 → 100644
| 1 | +#ifndef HALIDE_HALIDERUNTIME_H | ||
| 2 | +#define HALIDE_HALIDERUNTIME_H | ||
| 3 | + | ||
| 4 | +#include <stddef.h> | ||
| 5 | +#include <stdint.h> | ||
| 6 | +#include <stdbool.h> | ||
| 7 | + | ||
| 8 | +#ifdef __cplusplus | ||
| 9 | +extern "C" { | ||
| 10 | +#endif | ||
| 11 | + | ||
| 12 | +// Note that you should not use "inline" along with HALIDE_ALWAYS_INLINE; | ||
| 13 | +// it is not necessary, and may produce warnings for some build configurations. | ||
| 14 | +#ifdef _MSC_VER | ||
| 15 | +#define HALIDE_ALWAYS_INLINE __forceinline | ||
| 16 | +#define HALIDE_NEVER_INLINE __declspec(noinline) | ||
| 17 | +#else | ||
| 18 | +#define HALIDE_ALWAYS_INLINE __attribute__((always_inline)) inline | ||
| 19 | +#define HALIDE_NEVER_INLINE __attribute__((noinline)) | ||
| 20 | +#endif | ||
| 21 | + | ||
| 22 | +/** \file | ||
| 23 | + * | ||
| 24 | + * This file declares the routines used by Halide internally in its | ||
| 25 | + * runtime. On platforms that support weak linking, these can be | ||
| 26 | + * replaced with user-defined versions by defining an extern "C" | ||
| 27 | + * function with the same name and signature. | ||
| 28 | + * | ||
| 29 | + * When doing Just In Time (JIT) compilation methods on the Func being | ||
| 30 | + * compiled must be called instead. The corresponding methods are | ||
| 31 | + * documented below. | ||
| 32 | + * | ||
| 33 | + * All of these functions take a "void *user_context" parameter as their | ||
| 34 | + * first argument; if the Halide kernel that calls back to any of these | ||
| 35 | + * functions has been compiled with the UserContext feature set on its Target, | ||
| 36 | + * then the value of that pointer passed from the code that calls the | ||
| 37 | + * Halide kernel is piped through to the function. | ||
| 38 | + * | ||
| 39 | + * Some of these are also useful to call when using the default | ||
| 40 | + * implementation. E.g. halide_shutdown_thread_pool. | ||
| 41 | + * | ||
| 42 | + * Note that even on platforms with weak linking, some linker setups | ||
| 43 | + * may not respect the override you provide. E.g. if the override is | ||
| 44 | + * in a shared library and the halide object files are linked directly | ||
| 45 | + * into the output, the builtin versions of the runtime functions will | ||
| 46 | + * be called. See your linker documentation for more details. On | ||
| 47 | + * Linux, LD_DYNAMIC_WEAK=1 may help. | ||
| 48 | + * | ||
| 49 | + */ | ||
| 50 | + | ||
| 51 | +// Forward-declare to suppress warnings if compiling as C. | ||
| 52 | +struct halide_buffer_t; | ||
| 53 | + | ||
| 54 | +/** Types in the halide type system. They can be ints, unsigned ints, | ||
| 55 | + * or floats (of various bit-widths), or a handle (which is always 64-bits). | ||
| 56 | + * Note that the int/uint/float values do not imply a specific bit width | ||
| 57 | + * (the bit width is expected to be encoded in a separate value). | ||
| 58 | + */ | ||
| 59 | +typedef enum halide_type_code_t | ||
| 60 | +{ | ||
| 61 | + halide_type_int = 0, //!< signed integers | ||
| 62 | + halide_type_uint = 1, //!< unsigned integers | ||
| 63 | + halide_type_float = 2, //!< floating point numbers | ||
| 64 | + halide_type_handle = 3 //!< opaque pointer type (void *) | ||
| 65 | +} halide_type_code_t; | ||
| 66 | + | ||
| 67 | +// Note that while __attribute__ can go before or after the declaration, | ||
| 68 | +// __declspec apparently is only allowed before. | ||
| 69 | +#ifndef HALIDE_ATTRIBUTE_ALIGN | ||
| 70 | + #ifdef _MSC_VER | ||
| 71 | + #define HALIDE_ATTRIBUTE_ALIGN(x) __declspec(align(x)) | ||
| 72 | + #else | ||
| 73 | + #define HALIDE_ATTRIBUTE_ALIGN(x) __attribute__((aligned(x))) | ||
| 74 | + #endif | ||
| 75 | +#endif | ||
| 76 | + | ||
| 77 | +/** A runtime tag for a type in the halide type system. Can be ints, | ||
| 78 | + * unsigned ints, or floats of various bit-widths (the 'bits' | ||
| 79 | + * field). Can also be vectors of the same (by setting the 'lanes' | ||
| 80 | + * field to something larger than one). This struct should be | ||
| 81 | + * exactly 32-bits in size. */ | ||
| 82 | +struct halide_type_t { | ||
| 83 | + /** The basic type code: signed integer, unsigned integer, or floating point. */ | ||
| 84 | +#if __cplusplus >= 201103L | ||
| 85 | + HALIDE_ATTRIBUTE_ALIGN(1) halide_type_code_t code; // halide_type_code_t | ||
| 86 | +#else | ||
| 87 | + HALIDE_ATTRIBUTE_ALIGN(1) uint8_t code; // halide_type_code_t | ||
| 88 | +#endif | ||
| 89 | + | ||
| 90 | + /** The number of bits of precision of a single scalar value of this type. */ | ||
| 91 | + HALIDE_ATTRIBUTE_ALIGN(1) uint8_t bits; | ||
| 92 | + | ||
| 93 | + /** How many elements in a vector. This is 1 for scalar types. */ | ||
| 94 | + HALIDE_ATTRIBUTE_ALIGN(2) uint16_t lanes; | ||
| 95 | + | ||
| 96 | +#ifdef __cplusplus | ||
| 97 | + /** Construct a runtime representation of a Halide type from: | ||
| 98 | + * code: The fundamental type from an enum. | ||
| 99 | + * bits: The bit size of one element. | ||
| 100 | + * lanes: The number of vector elements in the type. */ | ||
| 101 | + HALIDE_ALWAYS_INLINE halide_type_t(halide_type_code_t code, uint8_t bits, uint16_t lanes = 1) | ||
| 102 | + : code(code), bits(bits), lanes(lanes) { | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** Default constructor is required e.g. to declare halide_trace_event | ||
| 106 | + * instances. */ | ||
| 107 | + HALIDE_ALWAYS_INLINE halide_type_t() : code((halide_type_code_t)0), bits(0), lanes(0) {} | ||
| 108 | + | ||
| 109 | + /** Compare two types for equality. */ | ||
| 110 | + HALIDE_ALWAYS_INLINE bool operator==(const halide_type_t &other) const { | ||
| 111 | + return (code == other.code && | ||
| 112 | + bits == other.bits && | ||
| 113 | + lanes == other.lanes); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + HALIDE_ALWAYS_INLINE bool operator!=(const halide_type_t &other) const { | ||
| 117 | + return !(*this == other); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + /** Size in bytes for a single element, even if width is not 1, of this type. */ | ||
| 121 | + HALIDE_ALWAYS_INLINE int bytes() const { return (bits + 7) / 8; } | ||
| 122 | +#endif | ||
| 123 | +}; | ||
| 124 | + | ||
| 125 | +/** An opaque struct containing per-GPU API implementations of the | ||
| 126 | + * device functions. */ | ||
| 127 | +struct halide_device_interface_impl_t; | ||
| 128 | + | ||
| 129 | +/** Each GPU API provides a halide_device_interface_t struct pointing | ||
| 130 | + * to the code that manages device allocations. You can access these | ||
| 131 | + * functions directly from the struct member function pointers, or by | ||
| 132 | + * calling the functions declared below. Note that the global | ||
| 133 | + * functions are not available when using Halide as a JIT compiler. | ||
| 134 | + * If you are using raw halide_buffer_t in that context you must use | ||
| 135 | + * the function pointers in the device_interface struct. | ||
| 136 | + * | ||
| 137 | + * The function pointers below are currently the same for every GPU | ||
| 138 | + * API; only the impl field varies. These top-level functions do the | ||
| 139 | + * bookkeeping that is common across all GPU APIs, and then dispatch | ||
| 140 | + * to more API-specific functions via another set of function pointers | ||
| 141 | + * hidden inside the impl field. | ||
| 142 | + */ | ||
| 143 | +struct halide_device_interface_t { | ||
| 144 | + int (*device_malloc)(void *user_context, struct halide_buffer_t *buf, | ||
| 145 | + const struct halide_device_interface_t *device_interface); | ||
| 146 | + int (*device_free)(void *user_context, struct halide_buffer_t *buf); | ||
| 147 | + int (*device_sync)(void *user_context, struct halide_buffer_t *buf); | ||
| 148 | + void (*device_release)(void *user_context, | ||
| 149 | + const struct halide_device_interface_t *device_interface); | ||
| 150 | + int (*copy_to_host)(void *user_context, struct halide_buffer_t *buf); | ||
| 151 | + int (*copy_to_device)(void *user_context, struct halide_buffer_t *buf, | ||
| 152 | + const struct halide_device_interface_t *device_interface); | ||
| 153 | + int (*device_and_host_malloc)(void *user_context, struct halide_buffer_t *buf, | ||
| 154 | + const struct halide_device_interface_t *device_interface); | ||
| 155 | + int (*device_and_host_free)(void *user_context, struct halide_buffer_t *buf); | ||
| 156 | + int (*buffer_copy)(void *user_context, struct halide_buffer_t *src, | ||
| 157 | + const struct halide_device_interface_t *dst_device_interface, struct halide_buffer_t *dst); | ||
| 158 | + int (*device_crop)(void *user_context, const struct halide_buffer_t *src, | ||
| 159 | + struct halide_buffer_t *dst); | ||
| 160 | + int (*device_release_crop)(void *user_context, struct halide_buffer_t *buf); | ||
| 161 | + int (*wrap_native)(void *user_context, struct halide_buffer_t *buf, uint64_t handle, | ||
| 162 | + const struct halide_device_interface_t *device_interface); | ||
| 163 | + int (*detach_native)(void *user_context, struct halide_buffer_t *buf); | ||
| 164 | + const struct halide_device_interface_impl_t *impl; | ||
| 165 | +}; | ||
| 166 | + | ||
| 167 | +typedef struct halide_dimension_t { | ||
| 168 | + int32_t min, extent, stride; | ||
| 169 | + | ||
| 170 | + // Per-dimension flags. None are defined yet (This is reserved for future use). | ||
| 171 | + uint32_t flags; | ||
| 172 | + | ||
| 173 | +#ifdef __cplusplus | ||
| 174 | + HALIDE_ALWAYS_INLINE halide_dimension_t() : min(0), extent(0), stride(0), flags(0) {} | ||
| 175 | + HALIDE_ALWAYS_INLINE halide_dimension_t(int32_t m, int32_t e, int32_t s, uint32_t f = 0) : | ||
| 176 | + min(m), extent(e), stride(s), flags(f) {} | ||
| 177 | + | ||
| 178 | + HALIDE_ALWAYS_INLINE bool operator==(const halide_dimension_t &other) const { | ||
| 179 | + return (min == other.min) && | ||
| 180 | + (extent == other.extent) && | ||
| 181 | + (stride == other.stride) && | ||
| 182 | + (flags == other.flags); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + HALIDE_ALWAYS_INLINE bool operator!=(const halide_dimension_t &other) const { | ||
| 186 | + return !(*this == other); | ||
| 187 | + } | ||
| 188 | +#endif | ||
| 189 | +} halide_dimension_t; | ||
| 190 | + | ||
| 191 | +#ifdef __cplusplus | ||
| 192 | +} // extern "C" | ||
| 193 | +#endif | ||
| 194 | + | ||
| 195 | +typedef enum {halide_buffer_flag_host_dirty = 1, | ||
| 196 | + halide_buffer_flag_device_dirty = 2} halide_buffer_flags; | ||
| 197 | + | ||
| 198 | +/** | ||
| 199 | + * The raw representation of an image passed around by generated | ||
| 200 | + * Halide code. It includes some stuff to track whether the image is | ||
| 201 | + * not actually in main memory, but instead on a device (like a | ||
| 202 | + * GPU). For a more convenient C++ wrapper, use Halide::Buffer<T>. */ | ||
| 203 | +typedef struct halide_buffer_t { | ||
| 204 | + /** A device-handle for e.g. GPU memory used to back this buffer. */ | ||
| 205 | + uint64_t device; | ||
| 206 | + | ||
| 207 | + /** The interface used to interpret the above handle. */ | ||
| 208 | + const struct halide_device_interface_t *device_interface; | ||
| 209 | + | ||
| 210 | + /** A pointer to the start of the data in main memory. In terms of | ||
| 211 | + * the Halide coordinate system, this is the address of the min | ||
| 212 | + * coordinates (defined below). */ | ||
| 213 | + uint8_t* host; | ||
| 214 | + | ||
| 215 | + /** flags with various meanings. */ | ||
| 216 | + uint64_t flags; | ||
| 217 | + | ||
| 218 | + /** The type of each buffer element. */ | ||
| 219 | + struct halide_type_t type; | ||
| 220 | + | ||
| 221 | + /** The dimensionality of the buffer. */ | ||
| 222 | + int32_t dimensions; | ||
| 223 | + | ||
| 224 | + /** The shape of the buffer. Halide does not own this array - you | ||
| 225 | + * must manage the memory for it yourself. */ | ||
| 226 | + halide_dimension_t *dim; | ||
| 227 | + | ||
| 228 | + /** Pads the buffer up to a multiple of 8 bytes */ | ||
| 229 | + void *padding; | ||
| 230 | +} halide_buffer_t; | ||
| 231 | + | ||
| 232 | + | ||
| 233 | +#ifdef __cplusplus | ||
| 234 | + | ||
| 235 | +namespace { | ||
| 236 | +template<typename T> struct check_is_pointer; | ||
| 237 | +template<typename T> struct check_is_pointer<T *> {}; | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | +/** Construct the halide equivalent of a C type */ | ||
| 241 | +template<typename T> | ||
| 242 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of() { | ||
| 243 | + // Create a compile-time error if T is not a pointer (without | ||
| 244 | + // using any includes - this code goes into the runtime). | ||
| 245 | + check_is_pointer<T> check; | ||
| 246 | + (void)check; | ||
| 247 | + return halide_type_t(halide_type_handle, 64); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +template<> | ||
| 251 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<float>() { | ||
| 252 | + return halide_type_t(halide_type_float, 32); | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +template<> | ||
| 256 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<double>() { | ||
| 257 | + return halide_type_t(halide_type_float, 64); | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +template<> | ||
| 261 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<bool>() { | ||
| 262 | + return halide_type_t(halide_type_uint, 1); | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +template<> | ||
| 266 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint8_t>() { | ||
| 267 | + return halide_type_t(halide_type_uint, 8); | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +template<> | ||
| 271 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint16_t>() { | ||
| 272 | + return halide_type_t(halide_type_uint, 16); | ||
| 273 | +} | ||
| 274 | + | ||
| 275 | +template<> | ||
| 276 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint32_t>() { | ||
| 277 | + return halide_type_t(halide_type_uint, 32); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +template<> | ||
| 281 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint64_t>() { | ||
| 282 | + return halide_type_t(halide_type_uint, 64); | ||
| 283 | +} | ||
| 284 | + | ||
| 285 | +template<> | ||
| 286 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int8_t>() { | ||
| 287 | + return halide_type_t(halide_type_int, 8); | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +template<> | ||
| 291 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int16_t>() { | ||
| 292 | + return halide_type_t(halide_type_int, 16); | ||
| 293 | +} | ||
| 294 | + | ||
| 295 | +template<> | ||
| 296 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int32_t>() { | ||
| 297 | + return halide_type_t(halide_type_int, 32); | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +template<> | ||
| 301 | +HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int64_t>() { | ||
| 302 | + return halide_type_t(halide_type_int, 64); | ||
| 303 | +} | ||
| 304 | + | ||
| 305 | +#endif | ||
| 306 | + | ||
| 307 | +#endif // HALIDE_HALIDERUNTIME_H |
lite.ai.toolkit/include/MNN/ImageProcess.hpp
0 → 100644
| 1 | +// | ||
| 2 | +// ImageProcess.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/09/19. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef ImageProcess_hpp | ||
| 10 | +#define ImageProcess_hpp | ||
| 11 | + | ||
| 12 | +#include <MNN/ErrorCode.hpp> | ||
| 13 | +#include <MNN/Matrix.h> | ||
| 14 | +#include <MNN/Tensor.hpp> | ||
| 15 | + | ||
| 16 | +namespace MNN { | ||
| 17 | +namespace CV { | ||
| 18 | +enum ImageFormat { | ||
| 19 | + RGBA = 0, | ||
| 20 | + RGB, | ||
| 21 | + BGR, | ||
| 22 | + GRAY, | ||
| 23 | + BGRA, | ||
| 24 | + YUV_NV21 = 11, | ||
| 25 | + YUV_NV12 = 12, | ||
| 26 | + YUV_I420 = 13, | ||
| 27 | +}; | ||
| 28 | + | ||
| 29 | +enum Filter { NEAREST = 0, BILINEAR = 1, BICUBIC = 2 }; | ||
| 30 | + | ||
| 31 | +enum Wrap { CLAMP_TO_EDGE = 0, ZERO = 1, REPEAT = 2 }; | ||
| 32 | + | ||
| 33 | +/** | ||
| 34 | + * handle image process for tensor. | ||
| 35 | + * step: | ||
| 36 | + * 1: Do transform compute and get points | ||
| 37 | + * 2: Sample line and do format convert | ||
| 38 | + * 3: Turn RGBA to float tensor, and do sub and normalize | ||
| 39 | + */ | ||
| 40 | +class MNN_PUBLIC ImageProcess { | ||
| 41 | +public: | ||
| 42 | + struct Inside; | ||
| 43 | + struct Config { | ||
| 44 | + /** data filter */ | ||
| 45 | + Filter filterType = NEAREST; | ||
| 46 | + /** format of source data */ | ||
| 47 | + ImageFormat sourceFormat = RGBA; | ||
| 48 | + /** format of destination data */ | ||
| 49 | + ImageFormat destFormat = RGBA; | ||
| 50 | + | ||
| 51 | + // Only valid if the dest type is float | ||
| 52 | + float mean[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | ||
| 53 | + float normal[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | ||
| 54 | + | ||
| 55 | + /** edge wrapper */ | ||
| 56 | + Wrap wrap = CLAMP_TO_EDGE; | ||
| 57 | + }; | ||
| 58 | + | ||
| 59 | +public: | ||
| 60 | + /** | ||
| 61 | + * @brief create image process with given config for given tensor. | ||
| 62 | + * @param config given config. | ||
| 63 | + * @param dstTensor given tensor. | ||
| 64 | + * @return image processor. | ||
| 65 | + */ | ||
| 66 | + static ImageProcess* create(const Config& config, const Tensor* dstTensor = nullptr); | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * @brief create image process with given config for given tensor. | ||
| 70 | + * @param means given means | ||
| 71 | + * @param meanCount given means count | ||
| 72 | + * @param normals given normals | ||
| 73 | + * @param normalCount given normal count | ||
| 74 | + * @param sourceFormat format of source data | ||
| 75 | + * @param destFormat format of destination data | ||
| 76 | + * @param dstTensor given tensor. | ||
| 77 | + * @return image processor. | ||
| 78 | + */ | ||
| 79 | + static ImageProcess* create(const ImageFormat sourceFormat = RGBA, const ImageFormat destFormat = RGBA, | ||
| 80 | + const float* means = nullptr, const int meanCount = 0, const float* normals = nullptr, | ||
| 81 | + const int normalCount = 0, const Tensor* dstTensor = nullptr); | ||
| 82 | + | ||
| 83 | + ~ImageProcess(); | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * @brief get affine transform matrix. | ||
| 87 | + * @return affine transform matrix. | ||
| 88 | + */ | ||
| 89 | + inline const Matrix& matrix() const { | ||
| 90 | + return mTransform; | ||
| 91 | + } | ||
| 92 | + void setMatrix(const Matrix& matrix); | ||
| 93 | + | ||
| 94 | + /** | ||
| 95 | + * @brief convert source data to given tensor. | ||
| 96 | + * @param source source data. | ||
| 97 | + * @param iw source width. | ||
| 98 | + * @param ih source height. | ||
| 99 | + * @param stride number of elements per row. eg: 100 width RGB contains at least 300 elements. | ||
| 100 | + * @param dest given tensor. | ||
| 101 | + * @return result code. | ||
| 102 | + */ | ||
| 103 | + ErrorCode convert(const uint8_t* source, int iw, int ih, int stride, Tensor* dest); | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * @brief convert source data to given tensor. | ||
| 107 | + * @param source source data. | ||
| 108 | + * @param iw source width. | ||
| 109 | + * @param ih source height. | ||
| 110 | + * @param stride number of elements per row. eg: 100 width RGB contains at least 300 elements. | ||
| 111 | + * @param dest dest data. | ||
| 112 | + * @param ow output width. | ||
| 113 | + * @param oh output height. | ||
| 114 | + * @param outputBpp output bpp, if 0, set as the save and config.destFormat. | ||
| 115 | + * @param outputStride output stride, if 0, set as ow * outputBpp. | ||
| 116 | + * @param type Only support halide_type_of<uint8_t> and halide_type_of<float>. | ||
| 117 | + * @return result code. | ||
| 118 | + */ | ||
| 119 | + ErrorCode convert(const uint8_t* source, int iw, int ih, int stride, void* dest, int ow, int oh, int outputBpp = 0, | ||
| 120 | + int outputStride = 0, halide_type_t type = halide_type_of<float>()); | ||
| 121 | + | ||
| 122 | + /** | ||
| 123 | + * @brief create tensor with given data. | ||
| 124 | + * @param w image width. | ||
| 125 | + * @param h image height. | ||
| 126 | + * @param bpp bytes per pixel. | ||
| 127 | + * @param p pixel data pointer. | ||
| 128 | + * @return created tensor. | ||
| 129 | + */ | ||
| 130 | + template <typename T> | ||
| 131 | + static Tensor* createImageTensor(int w, int h, int bpp, void* p = nullptr) { | ||
| 132 | + return createImageTensor(halide_type_of<T>(), w, h, bpp, p); | ||
| 133 | + } | ||
| 134 | + static Tensor* createImageTensor(halide_type_t type, int w, int h, int bpp, void* p = nullptr); | ||
| 135 | + | ||
| 136 | + /** | ||
| 137 | + * @brief set padding value when wrap=ZERO. | ||
| 138 | + * @param value padding value. | ||
| 139 | + * @return void. | ||
| 140 | + */ | ||
| 141 | + void setPadding(uint8_t value) { | ||
| 142 | + mPaddingValue = value; | ||
| 143 | + } | ||
| 144 | +private: | ||
| 145 | + ImageProcess(const Config& config); | ||
| 146 | + Matrix mTransform; | ||
| 147 | + Matrix mTransformInvert; | ||
| 148 | + Inside* mInside; | ||
| 149 | + uint8_t mPaddingValue = 0; | ||
| 150 | +}; | ||
| 151 | +} // namespace CV | ||
| 152 | +} // namespace MNN | ||
| 153 | + | ||
| 154 | +#endif /* ImageProcess_hpp */ |
lite.ai.toolkit/include/MNN/Interpreter.hpp
0 → 100644
| 1 | +// | ||
| 2 | +// Interpreter.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/07/23. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef Interpreter_hpp | ||
| 10 | +#define Interpreter_hpp | ||
| 11 | + | ||
| 12 | +#include <functional> | ||
| 13 | +#include <map> | ||
| 14 | +#include <memory> | ||
| 15 | +#include <string> | ||
| 16 | +#include <MNN/ErrorCode.hpp> | ||
| 17 | +#include <MNN/MNNForwardType.h> | ||
| 18 | +#include <MNN/Tensor.hpp> | ||
| 19 | + | ||
| 20 | +namespace MNN { | ||
| 21 | + | ||
| 22 | +/** session schedule config */ | ||
| 23 | +struct ScheduleConfig { | ||
| 24 | + /** which tensor should be kept */ | ||
| 25 | + std::vector<std::string> saveTensors; | ||
| 26 | + /** forward type */ | ||
| 27 | + MNNForwardType type = MNN_FORWARD_CPU; | ||
| 28 | + /** CPU:number of threads in parallel , Or GPU: mode setting*/ | ||
| 29 | + union { | ||
| 30 | + int numThread = 4; | ||
| 31 | + int mode; | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | + /** subpath to run */ | ||
| 35 | + struct Path { | ||
| 36 | + std::vector<std::string> inputs; | ||
| 37 | + std::vector<std::string> outputs; | ||
| 38 | + | ||
| 39 | + enum Mode { | ||
| 40 | + /** | ||
| 41 | + * Op Mode | ||
| 42 | + * - inputs means the source op, can NOT be empty. | ||
| 43 | + * - outputs means the sink op, can be empty. | ||
| 44 | + * The path will start from source op, then flow when encounter the sink op. | ||
| 45 | + * The sink op will not be compute in this path. | ||
| 46 | + */ | ||
| 47 | + Op = 0, | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Tensor Mode | ||
| 51 | + * - inputs means the inputs tensors, can NOT be empty. | ||
| 52 | + * - outputs means the outputs tensors, can NOT be empty. | ||
| 53 | + * It will find the pipeline that compute outputs from inputs. | ||
| 54 | + */ | ||
| 55 | + Tensor = 1 | ||
| 56 | + }; | ||
| 57 | + | ||
| 58 | + /** running mode */ | ||
| 59 | + Mode mode = Op; | ||
| 60 | + }; | ||
| 61 | + Path path; | ||
| 62 | + | ||
| 63 | + /** backup backend used to create execution when desinated backend do NOT support any op */ | ||
| 64 | + MNNForwardType backupType = MNN_FORWARD_CPU; | ||
| 65 | + | ||
| 66 | + /** extra backend config */ | ||
| 67 | + BackendConfig* backendConfig = nullptr; | ||
| 68 | +}; | ||
| 69 | + | ||
| 70 | +class Session; | ||
| 71 | +struct Content; | ||
| 72 | +class Tensor; | ||
| 73 | +class Backend; | ||
| 74 | +class Runtime; | ||
| 75 | + | ||
| 76 | +class MNN_PUBLIC OperatorInfo { | ||
| 77 | + struct Info; | ||
| 78 | + | ||
| 79 | +public: | ||
| 80 | + /** Operator's name*/ | ||
| 81 | + const std::string& name() const; | ||
| 82 | + | ||
| 83 | + /** Operator's type*/ | ||
| 84 | + const std::string& type() const; | ||
| 85 | + | ||
| 86 | + /** Operator's flops, in M*/ | ||
| 87 | + float flops() const; | ||
| 88 | + | ||
| 89 | +protected: | ||
| 90 | + OperatorInfo(); | ||
| 91 | + ~OperatorInfo(); | ||
| 92 | + Info* mContent; | ||
| 93 | +}; | ||
| 94 | + | ||
| 95 | +typedef std::function<bool(const std::vector<Tensor*>&, const std::string& /*opName*/)> TensorCallBack; | ||
| 96 | +typedef std::function<bool(const std::vector<Tensor*>&, const OperatorInfo*)> TensorCallBackWithInfo; | ||
| 97 | +typedef std::pair<std::map<MNNForwardType, std::shared_ptr<Runtime>>, std::shared_ptr<Runtime>> RuntimeInfo; | ||
| 98 | + | ||
| 99 | +/** net data holder. multiple sessions could share same net. */ | ||
| 100 | +class MNN_PUBLIC Interpreter { | ||
| 101 | +public: | ||
| 102 | + /** | ||
| 103 | + * @brief create net from file. | ||
| 104 | + * @param file given file. | ||
| 105 | + * @return created net if success, NULL otherwise. | ||
| 106 | + */ | ||
| 107 | + static Interpreter* createFromFile(const char* file); | ||
| 108 | + /** | ||
| 109 | + * @brief create net from buffer. | ||
| 110 | + * @param buffer given data buffer. | ||
| 111 | + * @param size size of data buffer. | ||
| 112 | + * @return created net if success, NULL otherwise. | ||
| 113 | + */ | ||
| 114 | + static Interpreter* createFromBuffer(const void* buffer, size_t size); | ||
| 115 | + ~Interpreter(); | ||
| 116 | + | ||
| 117 | + enum SessionMode { | ||
| 118 | + /** About CallBack, Default Session_Debug*/ | ||
| 119 | + /** runSessionWithCallBack is allowed and can get internal op info*/ | ||
| 120 | + Session_Debug = 0, | ||
| 121 | + /** runSessionWithCallBack is not valid and can't get any info of op in session*/ | ||
| 122 | + Session_Release = 1, | ||
| 123 | + | ||
| 124 | + /** About input tenosr, Default Session_Input_Inside*/ | ||
| 125 | + /** The input tensor is alloced by session, input data after session resized*/ | ||
| 126 | + Session_Input_Inside = 2, | ||
| 127 | + /** The input tensor is alloced by user, set input data before session resize*/ | ||
| 128 | + Session_Input_User = 3, | ||
| 129 | + }; | ||
| 130 | + /** | ||
| 131 | + * @brief The API shoud be called before create session. | ||
| 132 | + * @param mode session mode | ||
| 133 | + */ | ||
| 134 | + void setSessionMode(SessionMode mode); | ||
| 135 | + | ||
| 136 | + /** | ||
| 137 | + * @brief The API shoud be called before create session. | ||
| 138 | + * If the cache exist, try to load cache from file. | ||
| 139 | + * After createSession, try to save cache to file. | ||
| 140 | + * @param cacheFile cache file name | ||
| 141 | + * @param keySize the first `keySize` bytes used as the key to check if the `cacheFile` exists. | ||
| 142 | + */ | ||
| 143 | + void setCacheFile(const char* cacheFile, size_t keySize = 128); | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * @brief The API shoud be called after last resize session. | ||
| 147 | + * If resize session generate new cache info, try to rewrite cache file. | ||
| 148 | + * If resize session do not generate any new cache info, just do nothing. | ||
| 149 | + * @param session giveb session | ||
| 150 | + * @param flag Protected param, not used now | ||
| 151 | + */ | ||
| 152 | + ErrorCode updateCacheFile(Session *session, int flag = 0); | ||
| 153 | + | ||
| 154 | +public: | ||
| 155 | + /** | ||
| 156 | + * @brief create runtimeInfo seperately with schedule config. | ||
| 157 | + * @param configs session schedule configs. | ||
| 158 | + */ | ||
| 159 | + static RuntimeInfo createRuntime(const std::vector<ScheduleConfig>& configs); | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * @brief create session with schedule config. created session will be managed in net. | ||
| 163 | + * @param config session schedule config. | ||
| 164 | + * @return created session if success, NULL otherwise. | ||
| 165 | + */ | ||
| 166 | + Session* createSession(const ScheduleConfig& config); | ||
| 167 | + | ||
| 168 | + /** | ||
| 169 | + * @brief create session with schedule config and user-specified runtime. | ||
| 170 | + * @param config session schedule config, runtime runtimeInfo used by the created session. | ||
| 171 | + * @return created session if success, NULL otherwise. | ||
| 172 | + */ | ||
| 173 | + Session* createSession(const ScheduleConfig& config, const RuntimeInfo& runtime); | ||
| 174 | + | ||
| 175 | + /** | ||
| 176 | + * @brief create multi-path session with schedule configs. created session will be managed in net. | ||
| 177 | + * @param configs session schedule configs. | ||
| 178 | + * @return created session if success, NULL otherwise. | ||
| 179 | + */ | ||
| 180 | + Session* createMultiPathSession(const std::vector<ScheduleConfig>& configs); | ||
| 181 | + | ||
| 182 | + /** | ||
| 183 | + * @brief create multi-path session with schedule configs and user-specified runtime. | ||
| 184 | + created session will be managed in net. | ||
| 185 | + * @param configs session schedule configs. | ||
| 186 | + * @return created session if success, NULL otherwise. | ||
| 187 | + */ | ||
| 188 | + Session* createMultiPathSession(const std::vector<ScheduleConfig>& configs, const RuntimeInfo& runtime); | ||
| 189 | + | ||
| 190 | + /** | ||
| 191 | + * @brief release session. | ||
| 192 | + * @param session given session. | ||
| 193 | + * @return true if given session is held by net and is freed. | ||
| 194 | + */ | ||
| 195 | + bool releaseSession(Session* session); | ||
| 196 | + | ||
| 197 | + /** | ||
| 198 | + * @brief call this function to get tensors ready. output tensor buffer (host or deviceId) should be retrieved | ||
| 199 | + * after resize of any input tensor. | ||
| 200 | + * @param session given session. | ||
| 201 | + */ | ||
| 202 | + void resizeSession(Session* session); | ||
| 203 | + | ||
| 204 | + /** | ||
| 205 | + * @brief call this function if don't need resize or create session any more, it will save a few memory that equal | ||
| 206 | + * to the size of model buffer | ||
| 207 | + */ | ||
| 208 | + void releaseModel(); | ||
| 209 | + | ||
| 210 | + /** | ||
| 211 | + * @brief Get the model buffer for user to save | ||
| 212 | + * @return std::make_pair(modleBuffer, modelSize). | ||
| 213 | + * @example: | ||
| 214 | + * std::ofstream output("trainResult.alinn") | ||
| 215 | + * auto buffer = net->getModelBuffer(); | ||
| 216 | + * output.write((const char*)buffer.first, buffer.second); | ||
| 217 | + */ | ||
| 218 | + std::pair<const void*, size_t> getModelBuffer() const; | ||
| 219 | + | ||
| 220 | + /** | ||
| 221 | + * @brief update Session's Tensor to model's Const Op | ||
| 222 | + * @param session given session. | ||
| 223 | + * @return result of running. | ||
| 224 | + */ | ||
| 225 | + ErrorCode updateSessionToModel(Session* session); | ||
| 226 | + | ||
| 227 | + /** | ||
| 228 | + * @brief run session. | ||
| 229 | + * @param session given session. | ||
| 230 | + * @return result of running. | ||
| 231 | + */ | ||
| 232 | + ErrorCode runSession(Session* session) const; | ||
| 233 | + | ||
| 234 | + /* | ||
| 235 | + * @brief run session. | ||
| 236 | + * @param session given session. | ||
| 237 | + * @param before callback before each op. return true to run the op; return false to skip the op. | ||
| 238 | + * @param after callback after each op. return true to continue running; return false to interrupt the session. | ||
| 239 | + * @param sync synchronously wait for finish of execution or not. | ||
| 240 | + * @return result of running. | ||
| 241 | + */ | ||
| 242 | + ErrorCode runSessionWithCallBack(const Session* session, const TensorCallBack& before, const TensorCallBack& end, | ||
| 243 | + bool sync = false) const; | ||
| 244 | + | ||
| 245 | + /* | ||
| 246 | + * @brief run session. | ||
| 247 | + * @param session given session. | ||
| 248 | + * @param before callback before each op. return true to run the op; return false to skip the op. | ||
| 249 | + * @param after callback after each op. return true to continue running; return false to interrupt the session. | ||
| 250 | + * @param sync synchronously wait for finish of execution or not. | ||
| 251 | + * @return result of running. | ||
| 252 | + */ | ||
| 253 | + ErrorCode runSessionWithCallBackInfo(const Session* session, const TensorCallBackWithInfo& before, | ||
| 254 | + const TensorCallBackWithInfo& end, bool sync = false) const; | ||
| 255 | + | ||
| 256 | + /** | ||
| 257 | + * @brief get input tensor for given name. | ||
| 258 | + * @param session given session. | ||
| 259 | + * @param name given name. if NULL, return first input. | ||
| 260 | + * @return tensor if found, NULL otherwise. | ||
| 261 | + */ | ||
| 262 | + Tensor* getSessionInput(const Session* session, const char* name); | ||
| 263 | + /** | ||
| 264 | + * @brief get output tensor for given name. | ||
| 265 | + * @param session given session. | ||
| 266 | + * @param name given name. if NULL, return first output. | ||
| 267 | + * @return tensor if found, NULL otherwise. | ||
| 268 | + */ | ||
| 269 | + Tensor* getSessionOutput(const Session* session, const char* name); | ||
| 270 | + | ||
| 271 | + enum SessionInfoCode { | ||
| 272 | + /** memory session used in MB, float* */ | ||
| 273 | + MEMORY = 0, | ||
| 274 | + | ||
| 275 | + /** float operation needed in session in M, float* */ | ||
| 276 | + FLOPS = 1, | ||
| 277 | + | ||
| 278 | + /** Backends in session in M, int*, length >= 1 + number of configs when create session */ | ||
| 279 | + BACKENDS = 2, | ||
| 280 | + | ||
| 281 | + ALL | ||
| 282 | + }; | ||
| 283 | + | ||
| 284 | + /** | ||
| 285 | + * @brief get session info | ||
| 286 | + * @param session given session. | ||
| 287 | + * @param code given info code. | ||
| 288 | + * @param ptr given info ptr, see SessionInfoCode for detail | ||
| 289 | + * @return true if support the code, false otherwise. | ||
| 290 | + */ | ||
| 291 | + bool getSessionInfo(const Session* session, SessionInfoCode code, void* ptr); | ||
| 292 | + | ||
| 293 | + /** | ||
| 294 | + * @brief get all output tensors. | ||
| 295 | + * @param session given session. | ||
| 296 | + * @return all output tensors mapped with name. | ||
| 297 | + */ | ||
| 298 | + const std::map<std::string, Tensor*>& getSessionOutputAll(const Session* session) const; | ||
| 299 | + /** | ||
| 300 | + * @brief get all input tensors. | ||
| 301 | + * @param session given session. | ||
| 302 | + * @return all input tensors mapped with name. | ||
| 303 | + */ | ||
| 304 | + const std::map<std::string, Tensor*>& getSessionInputAll(const Session* session) const; | ||
| 305 | + | ||
| 306 | +public: | ||
| 307 | + /** | ||
| 308 | + * @brief resize given tensor. | ||
| 309 | + * @param tensor given tensor. | ||
| 310 | + * @param dims new dims. at most 6 dims. | ||
| 311 | + */ | ||
| 312 | + void resizeTensor(Tensor* tensor, const std::vector<int>& dims); | ||
| 313 | + | ||
| 314 | + /** | ||
| 315 | + * @brief resize given tensor by nchw. | ||
| 316 | + * @param batch / N. | ||
| 317 | + * @param channel / C. | ||
| 318 | + * @param height / H. | ||
| 319 | + * @param width / W | ||
| 320 | + */ | ||
| 321 | + void resizeTensor(Tensor* tensor, int batch, int channel, int height, int width); | ||
| 322 | + | ||
| 323 | + /** | ||
| 324 | + * @brief get backend used to create given tensor. | ||
| 325 | + * @param session given session. | ||
| 326 | + * @param tensor given tensor. | ||
| 327 | + * @return backend used to create given tensor, may be NULL. | ||
| 328 | + */ | ||
| 329 | + const Backend* getBackend(const Session* session, const Tensor* tensor) const; | ||
| 330 | + | ||
| 331 | + /** | ||
| 332 | + * @brief get business code (model identifier). | ||
| 333 | + * @return business code. | ||
| 334 | + */ | ||
| 335 | + const char* bizCode() const; | ||
| 336 | + | ||
| 337 | +private: | ||
| 338 | + static Interpreter* createFromBufferInternal(Content* net); | ||
| 339 | + | ||
| 340 | + Content* mNet = nullptr; | ||
| 341 | + Interpreter(Content* net); | ||
| 342 | + | ||
| 343 | + Interpreter(const Interpreter&) = delete; | ||
| 344 | + Interpreter(const Interpreter&&) = delete; | ||
| 345 | + Interpreter& operator=(const Interpreter&) = delete; | ||
| 346 | + Interpreter& operator=(const Interpreter&&) = delete; | ||
| 347 | +}; | ||
| 348 | +} // namespace MNN | ||
| 349 | + | ||
| 350 | +#endif /* Interpreter_hpp */ |
lite.ai.toolkit/include/MNN/MNNDefine.h
0 → 100644
| 1 | +// | ||
| 2 | +// MNNDefine.h | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/08/09. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef MNNDefine_h | ||
| 10 | +#define MNNDefine_h | ||
| 11 | + | ||
| 12 | +#include <assert.h> | ||
| 13 | +#include <stdio.h> | ||
| 14 | + | ||
| 15 | +#if defined(__APPLE__) | ||
| 16 | +#include <TargetConditionals.h> | ||
| 17 | +#if TARGET_OS_IPHONE | ||
| 18 | +#define MNN_BUILD_FOR_IOS | ||
| 19 | +#endif | ||
| 20 | +#endif | ||
| 21 | + | ||
| 22 | +#ifdef MNN_USE_LOGCAT | ||
| 23 | +#include <android/log.h> | ||
| 24 | +#define MNN_ERROR(format, ...) __android_log_print(ANDROID_LOG_ERROR, "MNNJNI", format, ##__VA_ARGS__) | ||
| 25 | +#define MNN_PRINT(format, ...) __android_log_print(ANDROID_LOG_INFO, "MNNJNI", format, ##__VA_ARGS__) | ||
| 26 | +#else | ||
| 27 | +#define MNN_PRINT(format, ...) printf(format, ##__VA_ARGS__) | ||
| 28 | +#define MNN_ERROR(format, ...) printf(format, ##__VA_ARGS__) | ||
| 29 | +#endif | ||
| 30 | + | ||
| 31 | +#ifdef DEBUG | ||
| 32 | +#define MNN_ASSERT(x) \ | ||
| 33 | + { \ | ||
| 34 | + int res = (x); \ | ||
| 35 | + if (!res) { \ | ||
| 36 | + MNN_ERROR("Error for %s, %d\n", __FILE__, __LINE__); \ | ||
| 37 | + assert(res); \ | ||
| 38 | + } \ | ||
| 39 | + } | ||
| 40 | +#else | ||
| 41 | +#define MNN_ASSERT(x) | ||
| 42 | +#endif | ||
| 43 | + | ||
| 44 | +#define FUNC_PRINT(x) MNN_PRINT(#x "=%d in %s, %d \n", x, __func__, __LINE__); | ||
| 45 | +#define FUNC_PRINT_ALL(x, type) MNN_PRINT(#x "=" #type " %" #type " in %s, %d \n", x, __func__, __LINE__); | ||
| 46 | + | ||
| 47 | +#define MNN_CHECK(success, log) \ | ||
| 48 | +if(!(success)){ \ | ||
| 49 | +MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \ | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +#if defined(_MSC_VER) | ||
| 53 | +#if defined(BUILDING_MNN_DLL) | ||
| 54 | +#define MNN_PUBLIC __declspec(dllexport) | ||
| 55 | +#elif defined(USING_MNN_DLL) | ||
| 56 | +#define MNN_PUBLIC __declspec(dllimport) | ||
| 57 | +#else | ||
| 58 | +#define MNN_PUBLIC | ||
| 59 | +#endif | ||
| 60 | +#else | ||
| 61 | +#define MNN_PUBLIC __attribute__((visibility("default"))) | ||
| 62 | +#endif | ||
| 63 | + | ||
| 64 | +#endif /* MNNDefine_h */ |
lite.ai.toolkit/include/MNN/MNNForwardType.h
0 → 100644
| 1 | +// | ||
| 2 | +// MNNForwardType.h | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2019/01/19. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef MNNForwardType_h | ||
| 10 | +#define MNNForwardType_h | ||
| 11 | +#include <stdint.h> | ||
| 12 | +#include <stddef.h> | ||
| 13 | + | ||
| 14 | +typedef enum { | ||
| 15 | + MNN_FORWARD_CPU = 0, | ||
| 16 | + | ||
| 17 | + /* | ||
| 18 | + Firtly find the first available backends not equal to CPU | ||
| 19 | + If no other backends, use cpu | ||
| 20 | + */ | ||
| 21 | + MNN_FORWARD_AUTO = 4, | ||
| 22 | + | ||
| 23 | + /*Hand write metal*/ | ||
| 24 | + MNN_FORWARD_METAL = 1, | ||
| 25 | + | ||
| 26 | + /*NVIDIA GPU API*/ | ||
| 27 | + MNN_FORWARD_CUDA = 2, | ||
| 28 | + | ||
| 29 | + /*Android / Common Device GPU API*/ | ||
| 30 | + MNN_FORWARD_OPENCL = 3, | ||
| 31 | + MNN_FORWARD_OPENGL = 6, | ||
| 32 | + MNN_FORWARD_VULKAN = 7, | ||
| 33 | + | ||
| 34 | + /*Android 8.1's NNAPI, Not Support yet. CoreML Now*/ | ||
| 35 | + MNN_FORWARD_NN = 5, | ||
| 36 | + | ||
| 37 | + /*User can use API from Backend.hpp to add or search Backend*/ | ||
| 38 | + MNN_FORWARD_USER_0 = 8, | ||
| 39 | + MNN_FORWARD_USER_1 = 9, | ||
| 40 | + MNN_FORWARD_USER_2 = 10, | ||
| 41 | + MNN_FORWARD_USER_3 = 11, | ||
| 42 | + | ||
| 43 | + MNN_FORWARD_ALL, | ||
| 44 | + | ||
| 45 | + /* Apply arm extension instruction set to accelerate some Ops, this forward type | ||
| 46 | + is only used in MNN internal, and will be active automatically when user set forward type | ||
| 47 | + to be MNN_FORWARD_CPU and extension instruction set is valid on hardware. | ||
| 48 | + */ | ||
| 49 | + MNN_FORWARD_CPU_EXTENSION | ||
| 50 | + | ||
| 51 | +} MNNForwardType; | ||
| 52 | + | ||
| 53 | +typedef enum { | ||
| 54 | + // choose one tuning mode Only | ||
| 55 | + MNN_GPU_TUNING_NONE = 1 << 0,/* Forbidden tuning, performance not good */ | ||
| 56 | + MNN_GPU_TUNING_HEAVY = 1 << 1,/* heavily tuning, usually not suggested */ | ||
| 57 | + MNN_GPU_TUNING_WIDE = 1 << 2,/* widely tuning, performance good. Default */ | ||
| 58 | + MNN_GPU_TUNING_NORMAL = 1 << 3,/* normal tuning, performance may be ok */ | ||
| 59 | + MNN_GPU_TUNING_FAST = 1 << 4,/* fast tuning, performance may not good */ | ||
| 60 | + | ||
| 61 | + // choose one opencl memory mode Only | ||
| 62 | + /* User can try OpenCL_MEMORY_BUFFER and OpenCL_MEMORY_IMAGE both, | ||
| 63 | + then choose the better one according to performance*/ | ||
| 64 | + MNN_GPU_MEMORY_BUFFER = 1 << 6,/* User assign mode */ | ||
| 65 | + MNN_GPU_MEMORY_IMAGE = 1 << 7,/* User assign mode */ | ||
| 66 | +} MNNGpuMode; | ||
| 67 | + | ||
| 68 | +#ifdef __cplusplus | ||
| 69 | +namespace MNN { | ||
| 70 | +struct BackendConfig { | ||
| 71 | + enum MemoryMode { Memory_Normal = 0, Memory_High, Memory_Low }; | ||
| 72 | + | ||
| 73 | + MemoryMode memory = Memory_Normal; | ||
| 74 | + | ||
| 75 | + enum PowerMode { Power_Normal = 0, Power_High, Power_Low }; | ||
| 76 | + | ||
| 77 | + PowerMode power = Power_Normal; | ||
| 78 | + | ||
| 79 | + enum PrecisionMode { Precision_Normal = 0, Precision_High, Precision_Low }; | ||
| 80 | + | ||
| 81 | + PrecisionMode precision = Precision_Normal; | ||
| 82 | + | ||
| 83 | + /** user defined context */ | ||
| 84 | + union { | ||
| 85 | + void* sharedContext = nullptr; | ||
| 86 | + size_t flags; // Valid for CPU Backend | ||
| 87 | + }; | ||
| 88 | +}; | ||
| 89 | +}; // namespace MNN | ||
| 90 | +#endif | ||
| 91 | +#endif /* MNNForwardType_h */ |
| 1 | +// | ||
| 2 | +// MNNSharedContext.h | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/10/11. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef MNNSharedContext_h | ||
| 10 | +#define MNNSharedContext_h | ||
| 11 | +#ifdef __cplusplus | ||
| 12 | +extern "C" { | ||
| 13 | +#endif | ||
| 14 | + | ||
| 15 | +#include <stdint.h> /*uint32_t*/ | ||
| 16 | + | ||
| 17 | +#ifndef VK_DEFINE_HANDLE | ||
| 18 | +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; | ||
| 19 | +VK_DEFINE_HANDLE(VkInstance) | ||
| 20 | +VK_DEFINE_HANDLE(VkPhysicalDevice) | ||
| 21 | +VK_DEFINE_HANDLE(VkDevice) | ||
| 22 | +VK_DEFINE_HANDLE(VkQueue) | ||
| 23 | +#endif | ||
| 24 | +struct MNNVulkanContext { | ||
| 25 | + VkInstance pInstance; | ||
| 26 | + VkPhysicalDevice pPhysicalDevice; | ||
| 27 | + VkDevice pDevice; | ||
| 28 | + VkQueue pQueue; | ||
| 29 | + uint32_t iQueueFamilyIndex; | ||
| 30 | +}; | ||
| 31 | +#ifdef __cplusplus | ||
| 32 | +} | ||
| 33 | +#endif | ||
| 34 | + | ||
| 35 | +#endif /* MNNSharedContext_h */ |
lite.ai.toolkit/include/MNN/Matrix.h
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2006 The Android Open Source Project | ||
| 3 | + * | ||
| 4 | + * Use of this source code is governed by a BSD-style license that can be | ||
| 5 | + * found in the LICENSE file. | ||
| 6 | + */ | ||
| 7 | + | ||
| 8 | +/* Generated by tools/bookmaker from include/core/Matrix.h and docs/SkMatrix_Reference.bmh | ||
| 9 | + on 2018-07-13 08:15:11. Additional documentation and examples can be found at: | ||
| 10 | + https://skia.org/user/api/SkMatrix_Reference | ||
| 11 | + | ||
| 12 | + You may edit either file directly. Structural changes to public interfaces require | ||
| 13 | + editing both files. After editing docs/SkMatrix_Reference.bmh, run: | ||
| 14 | + bookmaker -b docs -i include/core/Matrix.h -p | ||
| 15 | + to create an updated version of this file. | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +// | ||
| 20 | +// Modified by jiangxiaotang on 2018/09/19. | ||
| 21 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 22 | +// | ||
| 23 | + | ||
| 24 | +#ifndef SkMatrix_DEFINED | ||
| 25 | +#define SkMatrix_DEFINED | ||
| 26 | + | ||
| 27 | +#include <string.h> | ||
| 28 | +#include <cstdint> | ||
| 29 | +#include <MNN/Rect.h> | ||
| 30 | + | ||
| 31 | +namespace MNN { | ||
| 32 | +namespace CV { | ||
| 33 | + | ||
| 34 | +/** \class Matrix | ||
| 35 | + Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping | ||
| 36 | + Point and vectors with translation, scaling, skewing, rotation, and | ||
| 37 | + perspective. | ||
| 38 | + | ||
| 39 | + Matrix elements are in row major order. Matrix does not have a constructor, | ||
| 40 | + so it must be explicitly initialized. setIdentity() initializes Matrix | ||
| 41 | + so it has no effect. setTranslate(), setScale(), setSkew(), setRotate(), set9 and setAll() | ||
| 42 | + initializes all Matrix elements with the corresponding mapping. | ||
| 43 | + | ||
| 44 | + Matrix includes a hidden variable that classifies the type of matrix to | ||
| 45 | + improve performance. Matrix is not thread safe unless getType() is called first. | ||
| 46 | +*/ | ||
| 47 | + | ||
| 48 | +class MNN_PUBLIC Matrix { | ||
| 49 | +public: | ||
| 50 | + Matrix() { | ||
| 51 | + setIdentity(); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** Sets Matrix to scale by (sx, sy). Returned matrix is: | ||
| 55 | + | ||
| 56 | + | sx 0 0 | | ||
| 57 | + | 0 sy 0 | | ||
| 58 | + | 0 0 1 | | ||
| 59 | + | ||
| 60 | + @param sx horizontal scale factor | ||
| 61 | + @param sy vertical scale factor | ||
| 62 | + @return Matrix with scale | ||
| 63 | + */ | ||
| 64 | + static Matrix MakeScale(float sx, float sy) { | ||
| 65 | + Matrix m; | ||
| 66 | + m.setScale(sx, sy); | ||
| 67 | + return m; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + /** Sets Matrix to scale by (scale, scale). Returned matrix is: | ||
| 71 | + | ||
| 72 | + | scale 0 0 | | ||
| 73 | + | 0 scale 0 | | ||
| 74 | + | 0 0 1 | | ||
| 75 | + | ||
| 76 | + @param scale horizontal and vertical scale factor | ||
| 77 | + @return Matrix with scale | ||
| 78 | + */ | ||
| 79 | + static Matrix MakeScale(float scale) { | ||
| 80 | + Matrix m; | ||
| 81 | + m.setScale(scale, scale); | ||
| 82 | + return m; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** Sets Matrix to translate by (dx, dy). Returned matrix is: | ||
| 86 | + | ||
| 87 | + | 1 0 dx | | ||
| 88 | + | 0 1 dy | | ||
| 89 | + | 0 0 1 | | ||
| 90 | + | ||
| 91 | + @param dx horizontal translation | ||
| 92 | + @param dy vertical translation | ||
| 93 | + @return Matrix with translation | ||
| 94 | + */ | ||
| 95 | + static Matrix MakeTrans(float dx, float dy) { | ||
| 96 | + Matrix m; | ||
| 97 | + m.setTranslate(dx, dy); | ||
| 98 | + return m; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** Sets Matrix to: | ||
| 102 | + | ||
| 103 | + | scaleX skewX transX | | ||
| 104 | + | skewY scaleY transY | | ||
| 105 | + | pers0 pers1 pers2 | | ||
| 106 | + | ||
| 107 | + @param scaleX horizontal scale factor | ||
| 108 | + @param skewX horizontal skew factor | ||
| 109 | + @param transX horizontal translation | ||
| 110 | + @param skewY vertical skew factor | ||
| 111 | + @param scaleY vertical scale factor | ||
| 112 | + @param transY vertical translation | ||
| 113 | + @param pers0 input x-axis perspective factor | ||
| 114 | + @param pers1 input y-axis perspective factor | ||
| 115 | + @param pers2 perspective scale factor | ||
| 116 | + @return Matrix constructed from parameters | ||
| 117 | + */ | ||
| 118 | + static Matrix MakeAll(float scaleX, float skewX, float transX, float skewY, float scaleY, float transY, float pers0, | ||
| 119 | + float pers1, float pers2) { | ||
| 120 | + Matrix m; | ||
| 121 | + m.setAll(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2); | ||
| 122 | + return m; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** \enum Matrix::TypeMask | ||
| 126 | + Enum of bit fields for mask returned by getType(). | ||
| 127 | + Used to identify the complexity of Matrix, to optimize performance. | ||
| 128 | + */ | ||
| 129 | + enum TypeMask { | ||
| 130 | + kIdentity_Mask = 0, //!< identity Matrix; all bits clear | ||
| 131 | + kTranslate_Mask = 0x01, //!< translation Matrix | ||
| 132 | + kScale_Mask = 0x02, //!< scale Matrix | ||
| 133 | + kAffine_Mask = 0x04, //!< skew or rotate Matrix | ||
| 134 | + kPerspective_Mask = 0x08, //!< perspective Matrix | ||
| 135 | + }; | ||
| 136 | + | ||
| 137 | + /** Returns a bit field describing the transformations the matrix may | ||
| 138 | + perform. The bit field is computed conservatively, so it may include | ||
| 139 | + false positives. For example, when kPerspective_Mask is set, all | ||
| 140 | + other bits are set. | ||
| 141 | + | ||
| 142 | + @return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, | ||
| 143 | + kAffine_Mask, kPerspective_Mask | ||
| 144 | + */ | ||
| 145 | + TypeMask getType() const { | ||
| 146 | + if (fTypeMask & kUnknown_Mask) { | ||
| 147 | + fTypeMask = this->computeTypeMask(); | ||
| 148 | + } | ||
| 149 | + // only return the public masks | ||
| 150 | + return (TypeMask)(fTypeMask & 0xF); | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + /** Returns true if Matrix is identity. Identity matrix is: | ||
| 154 | + | ||
| 155 | + | 1 0 0 | | ||
| 156 | + | 0 1 0 | | ||
| 157 | + | 0 0 1 | | ||
| 158 | + | ||
| 159 | + @return true if Matrix has no effect | ||
| 160 | + */ | ||
| 161 | + bool isIdentity() const { | ||
| 162 | + return this->getType() == 0; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + /** Returns true if Matrix at most scales and translates. Matrix may be identity, | ||
| 166 | + contain only scale elements, only translate elements, or both. Matrix form is: | ||
| 167 | + | ||
| 168 | + | scale-x 0 translate-x | | ||
| 169 | + | 0 scale-y translate-y | | ||
| 170 | + | 0 0 1 | | ||
| 171 | + | ||
| 172 | + @return true if Matrix is identity; or scales, translates, or both | ||
| 173 | + */ | ||
| 174 | + bool isScaleTranslate() const { | ||
| 175 | + return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + /** Returns true if Matrix is identity, or translates. Matrix form is: | ||
| 179 | + | ||
| 180 | + | 1 0 translate-x | | ||
| 181 | + | 0 1 translate-y | | ||
| 182 | + | 0 0 1 | | ||
| 183 | + | ||
| 184 | + @return true if Matrix is identity, or translates | ||
| 185 | + */ | ||
| 186 | + bool isTranslate() const { | ||
| 187 | + return !(this->getType() & ~(kTranslate_Mask)); | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + /** Returns true Matrix maps Rect to another Rect. If true, Matrix is identity, | ||
| 191 | + or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all | ||
| 192 | + cases, Matrix may also have translation. Matrix form is either: | ||
| 193 | + | ||
| 194 | + | scale-x 0 translate-x | | ||
| 195 | + | 0 scale-y translate-y | | ||
| 196 | + | 0 0 1 | | ||
| 197 | + | ||
| 198 | + or | ||
| 199 | + | ||
| 200 | + | 0 rotate-x translate-x | | ||
| 201 | + | rotate-y 0 translate-y | | ||
| 202 | + | 0 0 1 | | ||
| 203 | + | ||
| 204 | + for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. | ||
| 205 | + | ||
| 206 | + Also called preservesAxisAlignment(); use the one that provides better inline | ||
| 207 | + documentation. | ||
| 208 | + | ||
| 209 | + @return true if Matrix maps one Rect into another | ||
| 210 | + */ | ||
| 211 | + bool rectStaysRect() const { | ||
| 212 | + if (fTypeMask & kUnknown_Mask) { | ||
| 213 | + fTypeMask = this->computeTypeMask(); | ||
| 214 | + } | ||
| 215 | + return (fTypeMask & kRectStaysRect_Mask) != 0; | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + /** Returns true Matrix maps Rect to another Rect. If true, Matrix is identity, | ||
| 219 | + or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all | ||
| 220 | + cases, Matrix may also have translation. Matrix form is either: | ||
| 221 | + | ||
| 222 | + | scale-x 0 translate-x | | ||
| 223 | + | 0 scale-y translate-y | | ||
| 224 | + | 0 0 1 | | ||
| 225 | + | ||
| 226 | + or | ||
| 227 | + | ||
| 228 | + | 0 rotate-x translate-x | | ||
| 229 | + | rotate-y 0 translate-y | | ||
| 230 | + | 0 0 1 | | ||
| 231 | + | ||
| 232 | + for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. | ||
| 233 | + | ||
| 234 | + Also called rectStaysRect(); use the one that provides better inline | ||
| 235 | + documentation. | ||
| 236 | + | ||
| 237 | + @return true if Matrix maps one Rect into another | ||
| 238 | + */ | ||
| 239 | + bool preservesAxisAlignment() const { | ||
| 240 | + return this->rectStaysRect(); | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + /** Matrix organizes its values in row order. These members correspond to | ||
| 244 | + each value in Matrix. | ||
| 245 | + */ | ||
| 246 | + static constexpr int kMScaleX = 0; //!< horizontal scale factor | ||
| 247 | + static constexpr int kMSkewX = 1; //!< horizontal skew factor | ||
| 248 | + static constexpr int kMTransX = 2; //!< horizontal translation | ||
| 249 | + static constexpr int kMSkewY = 3; //!< vertical skew factor | ||
| 250 | + static constexpr int kMScaleY = 4; //!< vertical scale factor | ||
| 251 | + static constexpr int kMTransY = 5; //!< vertical translation | ||
| 252 | + static constexpr int kMPersp0 = 6; //!< input x perspective factor | ||
| 253 | + static constexpr int kMPersp1 = 7; //!< input y perspective factor | ||
| 254 | + static constexpr int kMPersp2 = 8; //!< perspective bias | ||
| 255 | + | ||
| 256 | + /** Affine arrays are in column major order to match the matrix used by | ||
| 257 | + PDF and XPS. | ||
| 258 | + */ | ||
| 259 | + static constexpr int kAScaleX = 0; //!< horizontal scale factor | ||
| 260 | + static constexpr int kASkewY = 1; //!< vertical skew factor | ||
| 261 | + static constexpr int kASkewX = 2; //!< horizontal skew factor | ||
| 262 | + static constexpr int kAScaleY = 3; //!< vertical scale factor | ||
| 263 | + static constexpr int kATransX = 4; //!< horizontal translation | ||
| 264 | + static constexpr int kATransY = 5; //!< vertical translation | ||
| 265 | + | ||
| 266 | + /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is | ||
| 267 | + defined. | ||
| 268 | + | ||
| 269 | + @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, | ||
| 270 | + kMPersp0, kMPersp1, kMPersp2 | ||
| 271 | + @return value corresponding to index | ||
| 272 | + */ | ||
| 273 | + float operator[](int index) const { | ||
| 274 | + MNN_ASSERT((unsigned)index < 9); | ||
| 275 | + return fMat[index]; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is | ||
| 279 | + defined. | ||
| 280 | + | ||
| 281 | + @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, | ||
| 282 | + kMPersp0, kMPersp1, kMPersp2 | ||
| 283 | + @return value corresponding to index | ||
| 284 | + */ | ||
| 285 | + float get(int index) const { | ||
| 286 | + MNN_ASSERT((unsigned)index < 9); | ||
| 287 | + return fMat[index]; | ||
| 288 | + } | ||
| 289 | + | ||
| 290 | + /** Returns scale factor multiplied by x-axis input, contributing to x-axis output. | ||
| 291 | + With mapPoints(), scales Point along the x-axis. | ||
| 292 | + | ||
| 293 | + @return horizontal scale factor | ||
| 294 | + */ | ||
| 295 | + float getScaleX() const { | ||
| 296 | + return fMat[kMScaleX]; | ||
| 297 | + } | ||
| 298 | + | ||
| 299 | + /** Returns scale factor multiplied by y-axis input, contributing to y-axis output. | ||
| 300 | + With mapPoints(), scales Point along the y-axis. | ||
| 301 | + | ||
| 302 | + @return vertical scale factor | ||
| 303 | + */ | ||
| 304 | + float getScaleY() const { | ||
| 305 | + return fMat[kMScaleY]; | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + /** Returns scale factor multiplied by x-axis input, contributing to y-axis output. | ||
| 309 | + With mapPoints(), skews Point along the y-axis. | ||
| 310 | + Skewing both axes can rotate Point. | ||
| 311 | + | ||
| 312 | + @return vertical skew factor | ||
| 313 | + */ | ||
| 314 | + float getSkewY() const { | ||
| 315 | + return fMat[kMSkewY]; | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + /** Returns scale factor multiplied by y-axis input, contributing to x-axis output. | ||
| 319 | + With mapPoints(), skews Point along the x-axis. | ||
| 320 | + Skewing both axes can rotate Point. | ||
| 321 | + | ||
| 322 | + @return horizontal scale factor | ||
| 323 | + */ | ||
| 324 | + float getSkewX() const { | ||
| 325 | + return fMat[kMSkewX]; | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + /** Returns translation contributing to x-axis output. | ||
| 329 | + With mapPoints(), moves Point along the x-axis. | ||
| 330 | + | ||
| 331 | + @return horizontal translation factor | ||
| 332 | + */ | ||
| 333 | + float getTranslateX() const { | ||
| 334 | + return fMat[kMTransX]; | ||
| 335 | + } | ||
| 336 | + | ||
| 337 | + /** Returns translation contributing to y-axis output. | ||
| 338 | + With mapPoints(), moves Point along the y-axis. | ||
| 339 | + | ||
| 340 | + @return vertical translation factor | ||
| 341 | + */ | ||
| 342 | + float getTranslateY() const { | ||
| 343 | + return fMat[kMTransY]; | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + /** Returns factor scaling input x-axis relative to input y-axis. | ||
| 347 | + | ||
| 348 | + @return input x-axis perspective factor | ||
| 349 | + */ | ||
| 350 | + float getPerspX() const { | ||
| 351 | + return fMat[kMPersp0]; | ||
| 352 | + } | ||
| 353 | + | ||
| 354 | + /** Returns factor scaling input y-axis relative to input x-axis. | ||
| 355 | + | ||
| 356 | + @return input y-axis perspective factor | ||
| 357 | + */ | ||
| 358 | + float getPerspY() const { | ||
| 359 | + return fMat[kMPersp1]; | ||
| 360 | + } | ||
| 361 | + | ||
| 362 | + /** Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is | ||
| 363 | + defined. Clears internal cache anticipating that caller will change Matrix value. | ||
| 364 | + | ||
| 365 | + Next call to read Matrix state may recompute cache; subsequent writes to Matrix | ||
| 366 | + value must be followed by dirtyMatrixTypeCache(). | ||
| 367 | + | ||
| 368 | + @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, | ||
| 369 | + kMPersp0, kMPersp1, kMPersp2 | ||
| 370 | + @return writable value corresponding to index | ||
| 371 | + */ | ||
| 372 | + float& operator[](int index) { | ||
| 373 | + MNN_ASSERT((unsigned)index < 9); | ||
| 374 | + this->setTypeMask(kUnknown_Mask); | ||
| 375 | + return fMat[index]; | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + /** Sets Matrix value. Asserts if index is out of range and SK_DEBUG is | ||
| 379 | + defined. Safer than operator[]; internal cache is always maintained. | ||
| 380 | + | ||
| 381 | + @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, | ||
| 382 | + kMPersp0, kMPersp1, kMPersp2 | ||
| 383 | + @param value scalar to store in Matrix | ||
| 384 | + */ | ||
| 385 | + void set(int index, float value) { | ||
| 386 | + MNN_ASSERT((unsigned)index < 9); | ||
| 387 | + fMat[index] = value; | ||
| 388 | + this->setTypeMask(kUnknown_Mask); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + /** Sets horizontal scale factor. | ||
| 392 | + | ||
| 393 | + @param v horizontal scale factor to store | ||
| 394 | + */ | ||
| 395 | + void setScaleX(float v) { | ||
| 396 | + this->set(kMScaleX, v); | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + /** Sets vertical scale factor. | ||
| 400 | + | ||
| 401 | + @param v vertical scale factor to store | ||
| 402 | + */ | ||
| 403 | + void setScaleY(float v) { | ||
| 404 | + this->set(kMScaleY, v); | ||
| 405 | + } | ||
| 406 | + | ||
| 407 | + /** Sets vertical skew factor. | ||
| 408 | + | ||
| 409 | + @param v vertical skew factor to store | ||
| 410 | + */ | ||
| 411 | + void setSkewY(float v) { | ||
| 412 | + this->set(kMSkewY, v); | ||
| 413 | + } | ||
| 414 | + | ||
| 415 | + /** Sets horizontal skew factor. | ||
| 416 | + | ||
| 417 | + @param v horizontal skew factor to store | ||
| 418 | + */ | ||
| 419 | + void setSkewX(float v) { | ||
| 420 | + this->set(kMSkewX, v); | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + /** Sets horizontal translation. | ||
| 424 | + | ||
| 425 | + @param v horizontal translation to store | ||
| 426 | + */ | ||
| 427 | + void setTranslateX(float v) { | ||
| 428 | + this->set(kMTransX, v); | ||
| 429 | + } | ||
| 430 | + | ||
| 431 | + /** Sets vertical translation. | ||
| 432 | + | ||
| 433 | + @param v vertical translation to store | ||
| 434 | + */ | ||
| 435 | + void setTranslateY(float v) { | ||
| 436 | + this->set(kMTransY, v); | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + /** Sets input x-axis perspective factor, which causes mapXY() to vary input x-axis values | ||
| 440 | + inversely proportional to input y-axis values. | ||
| 441 | + | ||
| 442 | + @param v perspective factor | ||
| 443 | + */ | ||
| 444 | + void setPerspX(float v) { | ||
| 445 | + this->set(kMPersp0, v); | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + /** Sets input y-axis perspective factor, which causes mapXY() to vary input y-axis values | ||
| 449 | + inversely proportional to input x-axis values. | ||
| 450 | + | ||
| 451 | + @param v perspective factor | ||
| 452 | + */ | ||
| 453 | + void setPerspY(float v) { | ||
| 454 | + this->set(kMPersp1, v); | ||
| 455 | + } | ||
| 456 | + | ||
| 457 | + /** Sets all values from parameters. Sets matrix to: | ||
| 458 | + | ||
| 459 | + | scaleX skewX transX | | ||
| 460 | + | skewY scaleY transY | | ||
| 461 | + | persp0 persp1 persp2 | | ||
| 462 | + | ||
| 463 | + @param scaleX horizontal scale factor to store | ||
| 464 | + @param skewX horizontal skew factor to store | ||
| 465 | + @param transX horizontal translation to store | ||
| 466 | + @param skewY vertical skew factor to store | ||
| 467 | + @param scaleY vertical scale factor to store | ||
| 468 | + @param transY vertical translation to store | ||
| 469 | + @param persp0 input x-axis values perspective factor to store | ||
| 470 | + @param persp1 input y-axis values perspective factor to store | ||
| 471 | + @param persp2 perspective scale factor to store | ||
| 472 | + */ | ||
| 473 | + void setAll(float scaleX, float skewX, float transX, float skewY, float scaleY, float transY, float persp0, | ||
| 474 | + float persp1, float persp2) { | ||
| 475 | + fMat[kMScaleX] = scaleX; | ||
| 476 | + fMat[kMSkewX] = skewX; | ||
| 477 | + fMat[kMTransX] = transX; | ||
| 478 | + fMat[kMSkewY] = skewY; | ||
| 479 | + fMat[kMScaleY] = scaleY; | ||
| 480 | + fMat[kMTransY] = transY; | ||
| 481 | + fMat[kMPersp0] = persp0; | ||
| 482 | + fMat[kMPersp1] = persp1; | ||
| 483 | + fMat[kMPersp2] = persp2; | ||
| 484 | + this->setTypeMask(kUnknown_Mask); | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + /** Copies nine scalar values contained by Matrix into buffer, in member value | ||
| 488 | + ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, | ||
| 489 | + kMPersp0, kMPersp1, kMPersp2. | ||
| 490 | + | ||
| 491 | + @param buffer storage for nine scalar values | ||
| 492 | + */ | ||
| 493 | + void get9(float buffer[9]) const { | ||
| 494 | + memcpy(buffer, fMat, 9 * sizeof(float)); | ||
| 495 | + } | ||
| 496 | + | ||
| 497 | + /** Sets Matrix to nine scalar values in buffer, in member value ascending order: | ||
| 498 | + kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, | ||
| 499 | + kMPersp2. | ||
| 500 | + | ||
| 501 | + Sets matrix to: | ||
| 502 | + | ||
| 503 | + | buffer[0] buffer[1] buffer[2] | | ||
| 504 | + | buffer[3] buffer[4] buffer[5] | | ||
| 505 | + | buffer[6] buffer[7] buffer[8] | | ||
| 506 | + | ||
| 507 | + In the future, set9 followed by get9 may not return the same values. Since Matrix | ||
| 508 | + maps non-homogeneous coordinates, scaling all nine values produces an equivalent | ||
| 509 | + transformation, possibly improving precision. | ||
| 510 | + | ||
| 511 | + @param buffer nine scalar values | ||
| 512 | + */ | ||
| 513 | + void set9(const float buffer[9]); | ||
| 514 | + | ||
| 515 | + /** Sets Matrix to identity; which has no effect on mapped Point. Sets Matrix to: | ||
| 516 | + | ||
| 517 | + | 1 0 0 | | ||
| 518 | + | 0 1 0 | | ||
| 519 | + | 0 0 1 | | ||
| 520 | + | ||
| 521 | + Also called setIdentity(); use the one that provides better inline | ||
| 522 | + documentation. | ||
| 523 | + */ | ||
| 524 | + void reset(); | ||
| 525 | + | ||
| 526 | + /** Sets Matrix to identity; which has no effect on mapped Point. Sets Matrix to: | ||
| 527 | + | ||
| 528 | + | 1 0 0 | | ||
| 529 | + | 0 1 0 | | ||
| 530 | + | 0 0 1 | | ||
| 531 | + | ||
| 532 | + Also called reset(); use the one that provides better inline | ||
| 533 | + documentation. | ||
| 534 | + */ | ||
| 535 | + void setIdentity() { | ||
| 536 | + this->reset(); | ||
| 537 | + } | ||
| 538 | + | ||
| 539 | + /** Sets Matrix to translate by (dx, dy). | ||
| 540 | + | ||
| 541 | + @param dx horizontal translation | ||
| 542 | + @param dy vertical translation | ||
| 543 | + */ | ||
| 544 | + void setTranslate(float dx, float dy); | ||
| 545 | + | ||
| 546 | + /** Sets Matrix to scale by sx and sy, about a pivot point at (px, py). | ||
| 547 | + The pivot point is unchanged when mapped with Matrix. | ||
| 548 | + | ||
| 549 | + @param sx horizontal scale factor | ||
| 550 | + @param sy vertical scale factor | ||
| 551 | + @param px pivot x | ||
| 552 | + @param py pivot y | ||
| 553 | + */ | ||
| 554 | + void setScale(float sx, float sy, float px, float py); | ||
| 555 | + | ||
| 556 | + /** Sets Matrix to scale by sx and sy about at pivot point at (0, 0). | ||
| 557 | + | ||
| 558 | + @param sx horizontal scale factor | ||
| 559 | + @param sy vertical scale factor | ||
| 560 | + */ | ||
| 561 | + void setScale(float sx, float sy); | ||
| 562 | + | ||
| 563 | + /** Sets Matrix to rotate by degrees about a pivot point at (px, py). | ||
| 564 | + The pivot point is unchanged when mapped with Matrix. | ||
| 565 | + | ||
| 566 | + Positive degrees rotates clockwise. | ||
| 567 | + | ||
| 568 | + @param degrees angle of axes relative to upright axes | ||
| 569 | + @param px pivot x | ||
| 570 | + @param py pivot y | ||
| 571 | + */ | ||
| 572 | + void setRotate(float degrees, float px, float py); | ||
| 573 | + | ||
| 574 | + /** Sets Matrix to rotate by degrees about a pivot point at (0, 0). | ||
| 575 | + Positive degrees rotates clockwise. | ||
| 576 | + | ||
| 577 | + @param degrees angle of axes relative to upright axes | ||
| 578 | + */ | ||
| 579 | + void setRotate(float degrees); | ||
| 580 | + | ||
| 581 | + /** Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py). | ||
| 582 | + The pivot point is unchanged when mapped with Matrix. | ||
| 583 | + | ||
| 584 | + Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). | ||
| 585 | + Vector length specifies scale. | ||
| 586 | + | ||
| 587 | + @param sinValue rotation vector x-axis component | ||
| 588 | + @param cosValue rotation vector y-axis component | ||
| 589 | + @param px pivot x-axis | ||
| 590 | + @param py pivot y-axis | ||
| 591 | + */ | ||
| 592 | + void setSinCos(float sinValue, float cosValue, float px, float py); | ||
| 593 | + | ||
| 594 | + /** Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0). | ||
| 595 | + | ||
| 596 | + Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). | ||
| 597 | + Vector length specifies scale. | ||
| 598 | + | ||
| 599 | + @param sinValue rotation vector x-axis component | ||
| 600 | + @param cosValue rotation vector y-axis component | ||
| 601 | + */ | ||
| 602 | + void setSinCos(float sinValue, float cosValue); | ||
| 603 | + | ||
| 604 | + /** Sets Matrix to skew by kx and ky, about a pivot point at (px, py). | ||
| 605 | + The pivot point is unchanged when mapped with Matrix. | ||
| 606 | + | ||
| 607 | + @param kx horizontal skew factor | ||
| 608 | + @param ky vertical skew factor | ||
| 609 | + @param px pivot x | ||
| 610 | + @param py pivot y | ||
| 611 | + */ | ||
| 612 | + void setSkew(float kx, float ky, float px, float py); | ||
| 613 | + | ||
| 614 | + /** Sets Matrix to skew by kx and ky, about a pivot point at (0, 0). | ||
| 615 | + | ||
| 616 | + @param kx horizontal skew factor | ||
| 617 | + @param ky vertical skew factor | ||
| 618 | + */ | ||
| 619 | + void setSkew(float kx, float ky); | ||
| 620 | + | ||
| 621 | + /** Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this. | ||
| 622 | + | ||
| 623 | + Given: | ||
| 624 | + | ||
| 625 | + | A B C | | J K L | | ||
| 626 | + a = | D E F |, b = | M N O | | ||
| 627 | + | G H I | | P Q R | | ||
| 628 | + | ||
| 629 | + sets Matrix to: | ||
| 630 | + | ||
| 631 | + | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | | ||
| 632 | + a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | | ||
| 633 | + | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | | ||
| 634 | + | ||
| 635 | + @param a Matrix on left side of multiply expression | ||
| 636 | + @param b Matrix on right side of multiply expression | ||
| 637 | + */ | ||
| 638 | + void setConcat(const Matrix& a, const Matrix& b); | ||
| 639 | + | ||
| 640 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy). | ||
| 641 | + This can be thought of as moving the point to be mapped before applying Matrix. | ||
| 642 | + | ||
| 643 | + Given: | ||
| 644 | + | ||
| 645 | + | A B C | | 1 0 dx | | ||
| 646 | + Matrix = | D E F |, T(dx, dy) = | 0 1 dy | | ||
| 647 | + | G H I | | 0 0 1 | | ||
| 648 | + | ||
| 649 | + sets Matrix to: | ||
| 650 | + | ||
| 651 | + | A B C | | 1 0 dx | | A B A*dx+B*dy+C | | ||
| 652 | + Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F | | ||
| 653 | + | G H I | | 0 0 1 | | G H G*dx+H*dy+I | | ||
| 654 | + | ||
| 655 | + @param dx x-axis translation before applying Matrix | ||
| 656 | + @param dy y-axis translation before applying Matrix | ||
| 657 | + */ | ||
| 658 | + void preTranslate(float dx, float dy); | ||
| 659 | + | ||
| 660 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) | ||
| 661 | + about pivot point (px, py). | ||
| 662 | + This can be thought of as scaling about a pivot point before applying Matrix. | ||
| 663 | + | ||
| 664 | + Given: | ||
| 665 | + | ||
| 666 | + | A B C | | sx 0 dx | | ||
| 667 | + Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy | | ||
| 668 | + | G H I | | 0 0 1 | | ||
| 669 | + | ||
| 670 | + where | ||
| 671 | + | ||
| 672 | + dx = px - sx * px | ||
| 673 | + dy = py - sy * py | ||
| 674 | + | ||
| 675 | + sets Matrix to: | ||
| 676 | + | ||
| 677 | + | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C | | ||
| 678 | + Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F | | ||
| 679 | + | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I | | ||
| 680 | + | ||
| 681 | + @param sx horizontal scale factor | ||
| 682 | + @param sy vertical scale factor | ||
| 683 | + @param px pivot x | ||
| 684 | + @param py pivot y | ||
| 685 | + */ | ||
| 686 | + void preScale(float sx, float sy, float px, float py); | ||
| 687 | + | ||
| 688 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) | ||
| 689 | + about pivot point (0, 0). | ||
| 690 | + This can be thought of as scaling about the origin before applying Matrix. | ||
| 691 | + | ||
| 692 | + Given: | ||
| 693 | + | ||
| 694 | + | A B C | | sx 0 0 | | ||
| 695 | + Matrix = | D E F |, S(sx, sy) = | 0 sy 0 | | ||
| 696 | + | G H I | | 0 0 1 | | ||
| 697 | + | ||
| 698 | + sets Matrix to: | ||
| 699 | + | ||
| 700 | + | A B C | | sx 0 0 | | A*sx B*sy C | | ||
| 701 | + Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F | | ||
| 702 | + | G H I | | 0 0 1 | | G*sx H*sy I | | ||
| 703 | + | ||
| 704 | + @param sx horizontal scale factor | ||
| 705 | + @param sy vertical scale factor | ||
| 706 | + */ | ||
| 707 | + void preScale(float sx, float sy); | ||
| 708 | + | ||
| 709 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees | ||
| 710 | + about pivot point (px, py). | ||
| 711 | + This can be thought of as rotating about a pivot point before applying Matrix. | ||
| 712 | + | ||
| 713 | + Positive degrees rotates clockwise. | ||
| 714 | + | ||
| 715 | + Given: | ||
| 716 | + | ||
| 717 | + | A B C | | c -s dx | | ||
| 718 | + Matrix = | D E F |, R(degrees, px, py) = | s c dy | | ||
| 719 | + | G H I | | 0 0 1 | | ||
| 720 | + | ||
| 721 | + where | ||
| 722 | + | ||
| 723 | + c = cos(degrees) | ||
| 724 | + s = sin(degrees) | ||
| 725 | + dx = s * py + (1 - c) * px | ||
| 726 | + dy = -s * px + (1 - c) * py | ||
| 727 | + | ||
| 728 | + sets Matrix to: | ||
| 729 | + | ||
| 730 | + | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C | | ||
| 731 | + Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F | | ||
| 732 | + | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I | | ||
| 733 | + | ||
| 734 | + @param degrees angle of axes relative to upright axes | ||
| 735 | + @param px pivot x | ||
| 736 | + @param py pivot y | ||
| 737 | + */ | ||
| 738 | + void preRotate(float degrees, float px, float py); | ||
| 739 | + | ||
| 740 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees | ||
| 741 | + about pivot point (0, 0). | ||
| 742 | + This can be thought of as rotating about the origin before applying Matrix. | ||
| 743 | + | ||
| 744 | + Positive degrees rotates clockwise. | ||
| 745 | + | ||
| 746 | + Given: | ||
| 747 | + | ||
| 748 | + | A B C | | c -s 0 | | ||
| 749 | + Matrix = | D E F |, R(degrees, px, py) = | s c 0 | | ||
| 750 | + | G H I | | 0 0 1 | | ||
| 751 | + | ||
| 752 | + where | ||
| 753 | + | ||
| 754 | + c = cos(degrees) | ||
| 755 | + s = sin(degrees) | ||
| 756 | + | ||
| 757 | + sets Matrix to: | ||
| 758 | + | ||
| 759 | + | A B C | | c -s 0 | | Ac+Bs -As+Bc C | | ||
| 760 | + Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F | | ||
| 761 | + | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I | | ||
| 762 | + | ||
| 763 | + @param degrees angle of axes relative to upright axes | ||
| 764 | + */ | ||
| 765 | + void preRotate(float degrees); | ||
| 766 | + | ||
| 767 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) | ||
| 768 | + about pivot point (px, py). | ||
| 769 | + This can be thought of as skewing about a pivot point before applying Matrix. | ||
| 770 | + | ||
| 771 | + Given: | ||
| 772 | + | ||
| 773 | + | A B C | | 1 kx dx | | ||
| 774 | + Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy | | ||
| 775 | + | G H I | | 0 0 1 | | ||
| 776 | + | ||
| 777 | + where | ||
| 778 | + | ||
| 779 | + dx = -kx * py | ||
| 780 | + dy = -ky * px | ||
| 781 | + | ||
| 782 | + sets Matrix to: | ||
| 783 | + | ||
| 784 | + | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C | | ||
| 785 | + Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F | | ||
| 786 | + | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I | | ||
| 787 | + | ||
| 788 | + @param kx horizontal skew factor | ||
| 789 | + @param ky vertical skew factor | ||
| 790 | + @param px pivot x | ||
| 791 | + @param py pivot y | ||
| 792 | + */ | ||
| 793 | + void preSkew(float kx, float ky, float px, float py); | ||
| 794 | + | ||
| 795 | + /** Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) | ||
| 796 | + about pivot point (0, 0). | ||
| 797 | + This can be thought of as skewing about the origin before applying Matrix. | ||
| 798 | + | ||
| 799 | + Given: | ||
| 800 | + | ||
| 801 | + | A B C | | 1 kx 0 | | ||
| 802 | + Matrix = | D E F |, K(kx, ky) = | ky 1 0 | | ||
| 803 | + | G H I | | 0 0 1 | | ||
| 804 | + | ||
| 805 | + sets Matrix to: | ||
| 806 | + | ||
| 807 | + | A B C | | 1 kx 0 | | A+B*ky A*kx+B C | | ||
| 808 | + Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F | | ||
| 809 | + | G H I | | 0 0 1 | | G+H*ky G*kx+H I | | ||
| 810 | + | ||
| 811 | + @param kx horizontal skew factor | ||
| 812 | + @param ky vertical skew factor | ||
| 813 | + */ | ||
| 814 | + void preSkew(float kx, float ky); | ||
| 815 | + | ||
| 816 | + /** Sets Matrix to Matrix multiplied by Matrix other. | ||
| 817 | + This can be thought of mapping by other before applying Matrix. | ||
| 818 | + | ||
| 819 | + Given: | ||
| 820 | + | ||
| 821 | + | A B C | | J K L | | ||
| 822 | + Matrix = | D E F |, other = | M N O | | ||
| 823 | + | G H I | | P Q R | | ||
| 824 | + | ||
| 825 | + sets Matrix to: | ||
| 826 | + | ||
| 827 | + | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | | ||
| 828 | + Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | | ||
| 829 | + | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | | ||
| 830 | + | ||
| 831 | + @param other Matrix on right side of multiply expression | ||
| 832 | + */ | ||
| 833 | + void preConcat(const Matrix& other); | ||
| 834 | + | ||
| 835 | + /** Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix. | ||
| 836 | + This can be thought of as moving the point to be mapped after applying Matrix. | ||
| 837 | + | ||
| 838 | + Given: | ||
| 839 | + | ||
| 840 | + | J K L | | 1 0 dx | | ||
| 841 | + Matrix = | M N O |, T(dx, dy) = | 0 1 dy | | ||
| 842 | + | P Q R | | 0 0 1 | | ||
| 843 | + | ||
| 844 | + sets Matrix to: | ||
| 845 | + | ||
| 846 | + | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R | | ||
| 847 | + T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R | | ||
| 848 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 849 | + | ||
| 850 | + @param dx x-axis translation after applying Matrix | ||
| 851 | + @param dy y-axis translation after applying Matrix | ||
| 852 | + */ | ||
| 853 | + void postTranslate(float dx, float dy); | ||
| 854 | + | ||
| 855 | + /** Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point | ||
| 856 | + (px, py), multiplied by Matrix. | ||
| 857 | + This can be thought of as scaling about a pivot point after applying Matrix. | ||
| 858 | + | ||
| 859 | + Given: | ||
| 860 | + | ||
| 861 | + | J K L | | sx 0 dx | | ||
| 862 | + Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy | | ||
| 863 | + | P Q R | | 0 0 1 | | ||
| 864 | + | ||
| 865 | + where | ||
| 866 | + | ||
| 867 | + dx = px - sx * px | ||
| 868 | + dy = py - sy * py | ||
| 869 | + | ||
| 870 | + sets Matrix to: | ||
| 871 | + | ||
| 872 | + | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R | | ||
| 873 | + S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R | | ||
| 874 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 875 | + | ||
| 876 | + @param sx horizontal scale factor | ||
| 877 | + @param sy vertical scale factor | ||
| 878 | + @param px pivot x | ||
| 879 | + @param py pivot y | ||
| 880 | + */ | ||
| 881 | + void postScale(float sx, float sy, float px, float py); | ||
| 882 | + | ||
| 883 | + /** Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point | ||
| 884 | + (0, 0), multiplied by Matrix. | ||
| 885 | + This can be thought of as scaling about the origin after applying Matrix. | ||
| 886 | + | ||
| 887 | + Given: | ||
| 888 | + | ||
| 889 | + | J K L | | sx 0 0 | | ||
| 890 | + Matrix = | M N O |, S(sx, sy) = | 0 sy 0 | | ||
| 891 | + | P Q R | | 0 0 1 | | ||
| 892 | + | ||
| 893 | + sets Matrix to: | ||
| 894 | + | ||
| 895 | + | sx 0 0 | | J K L | | sx*J sx*K sx*L | | ||
| 896 | + S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | | ||
| 897 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 898 | + | ||
| 899 | + @param sx horizontal scale factor | ||
| 900 | + @param sy vertical scale factor | ||
| 901 | + */ | ||
| 902 | + void postScale(float sx, float sy); | ||
| 903 | + | ||
| 904 | + /** Sets Matrix to Matrix constructed from scaling by (1/divx, 1/divy) about pivot point (px, py), multiplied by | ||
| 905 | + Matrix. | ||
| 906 | + | ||
| 907 | + Returns false if either divx or divy is zero. | ||
| 908 | + | ||
| 909 | + Given: | ||
| 910 | + | ||
| 911 | + | J K L | | sx 0 0 | | ||
| 912 | + Matrix = | M N O |, I(divx, divy) = | 0 sy 0 | | ||
| 913 | + | P Q R | | 0 0 1 | | ||
| 914 | + | ||
| 915 | + where | ||
| 916 | + | ||
| 917 | + sx = 1 / divx | ||
| 918 | + sy = 1 / divy | ||
| 919 | + | ||
| 920 | + sets Matrix to: | ||
| 921 | + | ||
| 922 | + | sx 0 0 | | J K L | | sx*J sx*K sx*L | | ||
| 923 | + I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | | ||
| 924 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 925 | + | ||
| 926 | + @param divx integer divisor for inverse scale in x | ||
| 927 | + @param divy integer divisor for inverse scale in y | ||
| 928 | + @return true on successful scale | ||
| 929 | + */ | ||
| 930 | + bool postIDiv(int divx, int divy); | ||
| 931 | + | ||
| 932 | + /** Sets Matrix to Matrix constructed from rotating by degrees about pivot point | ||
| 933 | + (px, py), multiplied by Matrix. | ||
| 934 | + This can be thought of as rotating about a pivot point after applying Matrix. | ||
| 935 | + | ||
| 936 | + Positive degrees rotates clockwise. | ||
| 937 | + | ||
| 938 | + Given: | ||
| 939 | + | ||
| 940 | + | J K L | | c -s dx | | ||
| 941 | + Matrix = | M N O |, R(degrees, px, py) = | s c dy | | ||
| 942 | + | P Q R | | 0 0 1 | | ||
| 943 | + | ||
| 944 | + where | ||
| 945 | + | ||
| 946 | + c = cos(degrees) | ||
| 947 | + s = sin(degrees) | ||
| 948 | + dx = s * py + (1 - c) * px | ||
| 949 | + dy = -s * px + (1 - c) * py | ||
| 950 | + | ||
| 951 | + sets Matrix to: | ||
| 952 | + | ||
| 953 | + |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R| | ||
| 954 | + R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R| | ||
| 955 | + |0 0 1| |P Q R| | P Q R| | ||
| 956 | + | ||
| 957 | + @param degrees angle of axes relative to upright axes | ||
| 958 | + @param px pivot x | ||
| 959 | + @param py pivot y | ||
| 960 | + */ | ||
| 961 | + void postRotate(float degrees, float px, float py); | ||
| 962 | + | ||
| 963 | + /** Sets Matrix to Matrix constructed from rotating by degrees about pivot point | ||
| 964 | + (0, 0), multiplied by Matrix. | ||
| 965 | + This can be thought of as rotating about the origin after applying Matrix. | ||
| 966 | + | ||
| 967 | + Positive degrees rotates clockwise. | ||
| 968 | + | ||
| 969 | + Given: | ||
| 970 | + | ||
| 971 | + | J K L | | c -s 0 | | ||
| 972 | + Matrix = | M N O |, R(degrees, px, py) = | s c 0 | | ||
| 973 | + | P Q R | | 0 0 1 | | ||
| 974 | + | ||
| 975 | + where | ||
| 976 | + | ||
| 977 | + c = cos(degrees) | ||
| 978 | + s = sin(degrees) | ||
| 979 | + | ||
| 980 | + sets Matrix to: | ||
| 981 | + | ||
| 982 | + | c -s dx | | J K L | | cJ-sM cK-sN cL-sO | | ||
| 983 | + R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO | | ||
| 984 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 985 | + | ||
| 986 | + @param degrees angle of axes relative to upright axes | ||
| 987 | + */ | ||
| 988 | + void postRotate(float degrees); | ||
| 989 | + | ||
| 990 | + /** Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point | ||
| 991 | + (px, py), multiplied by Matrix. | ||
| 992 | + This can be thought of as skewing about a pivot point after applying Matrix. | ||
| 993 | + | ||
| 994 | + Given: | ||
| 995 | + | ||
| 996 | + | J K L | | 1 kx dx | | ||
| 997 | + Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy | | ||
| 998 | + | P Q R | | 0 0 1 | | ||
| 999 | + | ||
| 1000 | + where | ||
| 1001 | + | ||
| 1002 | + dx = -kx * py | ||
| 1003 | + dy = -ky * px | ||
| 1004 | + | ||
| 1005 | + sets Matrix to: | ||
| 1006 | + | ||
| 1007 | + | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R| | ||
| 1008 | + K(kx, ky, px, py) * Matrix = |ky 1 dy| |M N O| = |ky*J+M+dy*P ky*K+N+dy*Q ky*L+O+dy*R| | ||
| 1009 | + | 0 0 1| |P Q R| | P Q R| | ||
| 1010 | + | ||
| 1011 | + @param kx horizontal skew factor | ||
| 1012 | + @param ky vertical skew factor | ||
| 1013 | + @param px pivot x | ||
| 1014 | + @param py pivot y | ||
| 1015 | + */ | ||
| 1016 | + void postSkew(float kx, float ky, float px, float py); | ||
| 1017 | + | ||
| 1018 | + /** Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point | ||
| 1019 | + (0, 0), multiplied by Matrix. | ||
| 1020 | + This can be thought of as skewing about the origin after applying Matrix. | ||
| 1021 | + | ||
| 1022 | + Given: | ||
| 1023 | + | ||
| 1024 | + | J K L | | 1 kx 0 | | ||
| 1025 | + Matrix = | M N O |, K(kx, ky) = | ky 1 0 | | ||
| 1026 | + | P Q R | | 0 0 1 | | ||
| 1027 | + | ||
| 1028 | + sets Matrix to: | ||
| 1029 | + | ||
| 1030 | + | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O | | ||
| 1031 | + K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O | | ||
| 1032 | + | 0 0 1 | | P Q R | | P Q R | | ||
| 1033 | + | ||
| 1034 | + @param kx horizontal skew factor | ||
| 1035 | + @param ky vertical skew factor | ||
| 1036 | + */ | ||
| 1037 | + void postSkew(float kx, float ky); | ||
| 1038 | + | ||
| 1039 | + /** Sets Matrix to Matrix other multiplied by Matrix. | ||
| 1040 | + This can be thought of mapping by other after applying Matrix. | ||
| 1041 | + | ||
| 1042 | + Given: | ||
| 1043 | + | ||
| 1044 | + | J K L | | A B C | | ||
| 1045 | + Matrix = | M N O |, other = | D E F | | ||
| 1046 | + | P Q R | | G H I | | ||
| 1047 | + | ||
| 1048 | + sets Matrix to: | ||
| 1049 | + | ||
| 1050 | + | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | | ||
| 1051 | + other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | | ||
| 1052 | + | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | | ||
| 1053 | + | ||
| 1054 | + @param other Matrix on left side of multiply expression | ||
| 1055 | + */ | ||
| 1056 | + void postConcat(const Matrix& other); | ||
| 1057 | + | ||
| 1058 | + /** \enum Matrix::ScaleToFit | ||
| 1059 | + ScaleToFit describes how Matrix is constructed to map one Rect to another. | ||
| 1060 | + ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling, | ||
| 1061 | + or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies | ||
| 1062 | + how Matrix maps to the side or center of the destination Rect. | ||
| 1063 | + */ | ||
| 1064 | + enum ScaleToFit { | ||
| 1065 | + kFill_ScaleToFit, //!< scales in x and y to fill destination Rect | ||
| 1066 | + kStart_ScaleToFit, //!< scales and aligns to left and top | ||
| 1067 | + kCenter_ScaleToFit, //!< scales and aligns to center | ||
| 1068 | + kEnd_ScaleToFit, //!< scales and aligns to right and bottom | ||
| 1069 | + }; | ||
| 1070 | + | ||
| 1071 | + /** Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether | ||
| 1072 | + mapping completely fills dst or preserves the aspect ratio, and how to align | ||
| 1073 | + src within dst. Returns false if src is empty, and sets Matrix to identity. | ||
| 1074 | + Returns true if dst is empty, and sets Matrix to: | ||
| 1075 | + | ||
| 1076 | + | 0 0 0 | | ||
| 1077 | + | 0 0 0 | | ||
| 1078 | + | 0 0 1 | | ||
| 1079 | + | ||
| 1080 | + @param src Rect to map from | ||
| 1081 | + @param dst Rect to map to | ||
| 1082 | + @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, | ||
| 1083 | + kCenter_ScaleToFit, kEnd_ScaleToFit | ||
| 1084 | + @return true if Matrix can represent Rect mapping | ||
| 1085 | + */ | ||
| 1086 | + bool setRectToRect(const Rect& src, const Rect& dst, ScaleToFit stf); | ||
| 1087 | + | ||
| 1088 | + /** Returns Matrix set to scale and translate src Rect to dst Rect. stf selects | ||
| 1089 | + whether mapping completely fills dst or preserves the aspect ratio, and how to | ||
| 1090 | + align src within dst. Returns the identity Matrix if src is empty. If dst is | ||
| 1091 | + empty, returns Matrix set to: | ||
| 1092 | + | ||
| 1093 | + | 0 0 0 | | ||
| 1094 | + | 0 0 0 | | ||
| 1095 | + | 0 0 1 | | ||
| 1096 | + | ||
| 1097 | + @param src Rect to map from | ||
| 1098 | + @param dst Rect to map to | ||
| 1099 | + @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, | ||
| 1100 | + kCenter_ScaleToFit, kEnd_ScaleToFit | ||
| 1101 | + @return Matrix mapping src to dst | ||
| 1102 | + */ | ||
| 1103 | + static Matrix MakeRectToRect(const Rect& src, const Rect& dst, ScaleToFit stf) { | ||
| 1104 | + Matrix m; | ||
| 1105 | + m.setRectToRect(src, dst, stf); | ||
| 1106 | + return m; | ||
| 1107 | + } | ||
| 1108 | + | ||
| 1109 | + /** Sets Matrix to map src to dst. count must be zero or greater, and four or less. | ||
| 1110 | + | ||
| 1111 | + If count is zero, sets Matrix to identity and returns true. | ||
| 1112 | + If count is one, sets Matrix to translate and returns true. | ||
| 1113 | + If count is two or more, sets Matrix to map Point if possible; returns false | ||
| 1114 | + if Matrix cannot be constructed. If count is four, Matrix may include | ||
| 1115 | + perspective. | ||
| 1116 | + | ||
| 1117 | + @param src Point to map from | ||
| 1118 | + @param dst Point to map to | ||
| 1119 | + @param count number of Point in src and dst | ||
| 1120 | + @return true if Matrix was constructed successfully | ||
| 1121 | + */ | ||
| 1122 | + bool setPolyToPoly(const Point src[], const Point dst[], int count); | ||
| 1123 | + | ||
| 1124 | + /** Sets inverse to reciprocal matrix, returning true if Matrix can be inverted. | ||
| 1125 | + Geometrically, if Matrix maps from source to destination, inverse Matrix | ||
| 1126 | + maps from destination to source. If Matrix can not be inverted, inverse is | ||
| 1127 | + unchanged. | ||
| 1128 | + | ||
| 1129 | + @param inverse storage for inverted Matrix; may be nullptr | ||
| 1130 | + @return true if Matrix can be inverted | ||
| 1131 | + */ | ||
| 1132 | + bool invert(Matrix* inverse) const { | ||
| 1133 | + // Allow the trivial case to be inlined. | ||
| 1134 | + if (this->isIdentity()) { | ||
| 1135 | + if (inverse) { | ||
| 1136 | + inverse->reset(); | ||
| 1137 | + } | ||
| 1138 | + return true; | ||
| 1139 | + } | ||
| 1140 | + return this->invertNonIdentity(inverse); | ||
| 1141 | + } | ||
| 1142 | + | ||
| 1143 | + /** Fills affine with identity values in column major order. | ||
| 1144 | + Sets affine to: | ||
| 1145 | + | ||
| 1146 | + | 1 0 0 | | ||
| 1147 | + | 0 1 0 | | ||
| 1148 | + | ||
| 1149 | + Affine 3x2 matrices in column major order are used by OpenGL and XPS. | ||
| 1150 | + | ||
| 1151 | + @param affine storage for 3x2 affine matrix | ||
| 1152 | + */ | ||
| 1153 | + static void SetAffineIdentity(float affine[6]); | ||
| 1154 | + | ||
| 1155 | + /** Fills affine in column major order. Sets affine to: | ||
| 1156 | + | ||
| 1157 | + | scale-x skew-x translate-x | | ||
| 1158 | + | skew-y scale-y translate-y | | ||
| 1159 | + | ||
| 1160 | + If Matrix contains perspective, returns false and leaves affine unchanged. | ||
| 1161 | + | ||
| 1162 | + @param affine storage for 3x2 affine matrix; may be nullptr | ||
| 1163 | + @return true if Matrix does not contain perspective | ||
| 1164 | + */ | ||
| 1165 | + bool asAffine(float affine[6]) const; | ||
| 1166 | + | ||
| 1167 | + /** Sets Matrix to affine values, passed in column major order. Given affine, | ||
| 1168 | + column, then row, as: | ||
| 1169 | + | ||
| 1170 | + | scale-x skew-x translate-x | | ||
| 1171 | + | skew-y scale-y translate-y | | ||
| 1172 | + | ||
| 1173 | + Matrix is set, row, then column, to: | ||
| 1174 | + | ||
| 1175 | + | scale-x skew-x translate-x | | ||
| 1176 | + | skew-y scale-y translate-y | | ||
| 1177 | + | 0 0 1 | | ||
| 1178 | + | ||
| 1179 | + @param affine 3x2 affine matrix | ||
| 1180 | + */ | ||
| 1181 | + void setAffine(const float affine[6]); | ||
| 1182 | + | ||
| 1183 | + /** Maps src Point array of length count to dst Point array of equal or greater | ||
| 1184 | + length. Point are mapped by multiplying each Point by Matrix. Given: | ||
| 1185 | + | ||
| 1186 | + | A B C | | x | | ||
| 1187 | + Matrix = | D E F |, pt = | y | | ||
| 1188 | + | G H I | | 1 | | ||
| 1189 | + | ||
| 1190 | + where | ||
| 1191 | + | ||
| 1192 | + for (i = 0; i < count; ++i) { | ||
| 1193 | + x = src[i].fX | ||
| 1194 | + y = src[i].fY | ||
| 1195 | + } | ||
| 1196 | + | ||
| 1197 | + each dst Point is computed as: | ||
| 1198 | + | ||
| 1199 | + |A B C| |x| Ax+By+C Dx+Ey+F | ||
| 1200 | + Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- | ||
| 1201 | + |G H I| |1| Gx+Hy+I Gx+Hy+I | ||
| 1202 | + | ||
| 1203 | + src and dst may point to the same storage. | ||
| 1204 | + | ||
| 1205 | + @param dst storage for mapped Point | ||
| 1206 | + @param src Point to transform | ||
| 1207 | + @param count number of Point to transform | ||
| 1208 | + */ | ||
| 1209 | + void mapPoints(Point dst[], const Point src[], int count) const { | ||
| 1210 | + MNN_ASSERT((dst && src && count > 0) || 0 == count); | ||
| 1211 | + // no partial overlap | ||
| 1212 | + MNN_ASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); | ||
| 1213 | + this->getMapPtsProc()(*this, dst, src, count); | ||
| 1214 | + } | ||
| 1215 | + | ||
| 1216 | + /** Maps pts Point array of length count in place. Point are mapped by multiplying | ||
| 1217 | + each Point by Matrix. Given: | ||
| 1218 | + | ||
| 1219 | + | A B C | | x | | ||
| 1220 | + Matrix = | D E F |, pt = | y | | ||
| 1221 | + | G H I | | 1 | | ||
| 1222 | + | ||
| 1223 | + where | ||
| 1224 | + | ||
| 1225 | + for (i = 0; i < count; ++i) { | ||
| 1226 | + x = pts[i].fX | ||
| 1227 | + y = pts[i].fY | ||
| 1228 | + } | ||
| 1229 | + | ||
| 1230 | + each resulting pts Point is computed as: | ||
| 1231 | + | ||
| 1232 | + |A B C| |x| Ax+By+C Dx+Ey+F | ||
| 1233 | + Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- | ||
| 1234 | + |G H I| |1| Gx+Hy+I Gx+Hy+I | ||
| 1235 | + | ||
| 1236 | + @param pts storage for mapped Point | ||
| 1237 | + @param count number of Point to transform | ||
| 1238 | + */ | ||
| 1239 | + void mapPoints(Point pts[], int count) const { | ||
| 1240 | + this->mapPoints(pts, pts, count); | ||
| 1241 | + } | ||
| 1242 | + | ||
| 1243 | + /** Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given: | ||
| 1244 | + | ||
| 1245 | + | A B C | | x | | ||
| 1246 | + Matrix = | D E F |, pt = | y | | ||
| 1247 | + | G H I | | 1 | | ||
| 1248 | + | ||
| 1249 | + result is computed as: | ||
| 1250 | + | ||
| 1251 | + |A B C| |x| Ax+By+C Dx+Ey+F | ||
| 1252 | + Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- | ||
| 1253 | + |G H I| |1| Gx+Hy+I Gx+Hy+I | ||
| 1254 | + | ||
| 1255 | + @param x x-axis value of Point to map | ||
| 1256 | + @param y y-axis value of Point to map | ||
| 1257 | + @param result storage for mapped Point | ||
| 1258 | + */ | ||
| 1259 | + void mapXY(float x, float y, Point* result) const { | ||
| 1260 | + this->getMapXYProc()(*this, x, y, result); | ||
| 1261 | + } | ||
| 1262 | + | ||
| 1263 | + /** Returns Point (x, y) multiplied by Matrix. Given: | ||
| 1264 | + | ||
| 1265 | + | A B C | | x | | ||
| 1266 | + Matrix = | D E F |, pt = | y | | ||
| 1267 | + | G H I | | 1 | | ||
| 1268 | + | ||
| 1269 | + result is computed as: | ||
| 1270 | + | ||
| 1271 | + |A B C| |x| Ax+By+C Dx+Ey+F | ||
| 1272 | + Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- | ||
| 1273 | + |G H I| |1| Gx+Hy+I Gx+Hy+I | ||
| 1274 | + | ||
| 1275 | + @param x x-axis value of Point to map | ||
| 1276 | + @param y y-axis value of Point to map | ||
| 1277 | + @return mapped Point | ||
| 1278 | + */ | ||
| 1279 | + Point mapXY(float x, float y) const { | ||
| 1280 | + Point result; | ||
| 1281 | + this->getMapXYProc()(*this, x, y, &result); | ||
| 1282 | + return result; | ||
| 1283 | + } | ||
| 1284 | + | ||
| 1285 | + /** Sets dst to bounds of src corners mapped by Matrix. | ||
| 1286 | + Returns true if mapped corners are dst corners. | ||
| 1287 | + | ||
| 1288 | + Returned value is the same as calling rectStaysRect(). | ||
| 1289 | + | ||
| 1290 | + @param dst storage for bounds of mapped Point | ||
| 1291 | + @param src Rect to map | ||
| 1292 | + @return true if dst is equivalent to mapped src | ||
| 1293 | + */ | ||
| 1294 | + bool mapRect(Rect* dst, const Rect& src) const; | ||
| 1295 | + | ||
| 1296 | + /** Sets rect to bounds of rect corners mapped by Matrix. | ||
| 1297 | + Returns true if mapped corners are computed rect corners. | ||
| 1298 | + | ||
| 1299 | + Returned value is the same as calling rectStaysRect(). | ||
| 1300 | + | ||
| 1301 | + @param rect rectangle to map, and storage for bounds of mapped corners | ||
| 1302 | + @return true if result is equivalent to mapped src | ||
| 1303 | + */ | ||
| 1304 | + bool mapRect(Rect* rect) const { | ||
| 1305 | + return this->mapRect(rect, *rect); | ||
| 1306 | + } | ||
| 1307 | + | ||
| 1308 | + /** Returns bounds of src corners mapped by Matrix. | ||
| 1309 | + | ||
| 1310 | + @param src rectangle to map | ||
| 1311 | + @return mapped bounds | ||
| 1312 | + */ | ||
| 1313 | + Rect mapRect(const Rect& src) const { | ||
| 1314 | + Rect dst; | ||
| 1315 | + (void)this->mapRect(&dst, src); | ||
| 1316 | + return dst; | ||
| 1317 | + } | ||
| 1318 | + | ||
| 1319 | + /** Sets dst to bounds of src corners mapped by Matrix. If matrix contains | ||
| 1320 | + elements other than scale or translate: asserts if SK_DEBUG is defined; | ||
| 1321 | + otherwise, results are undefined. | ||
| 1322 | + | ||
| 1323 | + @param dst storage for bounds of mapped Point | ||
| 1324 | + @param src Rect to map | ||
| 1325 | + */ | ||
| 1326 | + void mapRectScaleTranslate(Rect* dst, const Rect& src) const; | ||
| 1327 | + | ||
| 1328 | + /** Returns true if Matrix equals m, using an efficient comparison. | ||
| 1329 | + | ||
| 1330 | + Returns false when the sign of zero values is the different; when one | ||
| 1331 | + matrix has positive zero value and the other has negative zero value. | ||
| 1332 | + | ||
| 1333 | + Returns true even when both Matrix contain NaN. | ||
| 1334 | + | ||
| 1335 | + NaN never equals any value, including itself. To improve performance, NaN values | ||
| 1336 | + are treated as bit patterns that are equal if their bit patterns are equal. | ||
| 1337 | + | ||
| 1338 | + @param m Matrix to compare | ||
| 1339 | + @return true if m and Matrix are represented by identical bit patterns | ||
| 1340 | + */ | ||
| 1341 | + bool cheapEqualTo(const Matrix& m) const { | ||
| 1342 | + return 0 == memcmp(fMat, m.fMat, sizeof(fMat)); | ||
| 1343 | + } | ||
| 1344 | + | ||
| 1345 | + /** Compares a and b; returns true if a and b are numerically equal. Returns true | ||
| 1346 | + even if sign of zero values are different. Returns false if either Matrix | ||
| 1347 | + contains NaN, even if the other Matrix also contains NaN. | ||
| 1348 | + | ||
| 1349 | + @param a Matrix to compare | ||
| 1350 | + @param b Matrix to compare | ||
| 1351 | + @return true if Matrix a and Matrix b are numerically equal | ||
| 1352 | + */ | ||
| 1353 | + friend MNN_PUBLIC bool operator==(const Matrix& a, const Matrix& b); | ||
| 1354 | + | ||
| 1355 | + /** Compares a and b; returns true if a and b are not numerically equal. Returns false | ||
| 1356 | + even if sign of zero values are different. Returns true if either Matrix | ||
| 1357 | + contains NaN, even if the other Matrix also contains NaN. | ||
| 1358 | + | ||
| 1359 | + @param a Matrix to compare | ||
| 1360 | + @param b Matrix to compare | ||
| 1361 | + @return true if Matrix a and Matrix b are numerically not equal | ||
| 1362 | + */ | ||
| 1363 | + friend MNN_PUBLIC bool operator!=(const Matrix& a, const Matrix& b) { | ||
| 1364 | + return !(a == b); | ||
| 1365 | + } | ||
| 1366 | + | ||
| 1367 | + /** Writes text representation of Matrix to standard output. Floating point values | ||
| 1368 | + are written with limited precision; it may not be possible to reconstruct | ||
| 1369 | + original Matrix from output. | ||
| 1370 | + */ | ||
| 1371 | + void dump() const; | ||
| 1372 | + | ||
| 1373 | + /** Returns the minimum scaling factor of Matrix by decomposing the scaling and | ||
| 1374 | + skewing elements. | ||
| 1375 | + Returns -1 if scale factor overflows or Matrix contains perspective. | ||
| 1376 | + | ||
| 1377 | + @return minimum scale factor | ||
| 1378 | + */ | ||
| 1379 | + float getMinScale() const; | ||
| 1380 | + | ||
| 1381 | + /** Returns the maximum scaling factor of Matrix by decomposing the scaling and | ||
| 1382 | + skewing elements. | ||
| 1383 | + Returns -1 if scale factor overflows or Matrix contains perspective. | ||
| 1384 | + | ||
| 1385 | + @return maximum scale factor | ||
| 1386 | + */ | ||
| 1387 | + float getMaxScale() const; | ||
| 1388 | + | ||
| 1389 | + /** Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the | ||
| 1390 | + maximum scaling factor. Scaling factors are computed by decomposing | ||
| 1391 | + the Matrix scaling and skewing elements. | ||
| 1392 | + | ||
| 1393 | + Returns true if scaleFactors are found; otherwise, returns false and sets | ||
| 1394 | + scaleFactors to undefined values. | ||
| 1395 | + | ||
| 1396 | + @param scaleFactors storage for minimum and maximum scale factors | ||
| 1397 | + @return true if scale factors were computed correctly | ||
| 1398 | + */ | ||
| 1399 | + bool getMinMaxScales(float scaleFactors[2]) const; | ||
| 1400 | + | ||
| 1401 | + /** Returns reference to const identity Matrix. Returned Matrix is set to: | ||
| 1402 | + | ||
| 1403 | + | 1 0 0 | | ||
| 1404 | + | 0 1 0 | | ||
| 1405 | + | 0 0 1 | | ||
| 1406 | + | ||
| 1407 | + @return const identity Matrix | ||
| 1408 | + */ | ||
| 1409 | + static const Matrix& I(); | ||
| 1410 | + | ||
| 1411 | + /** Returns reference to a const Matrix with invalid values. Returned Matrix is set | ||
| 1412 | + to: | ||
| 1413 | + | ||
| 1414 | + | SK_ScalarMax SK_ScalarMax SK_ScalarMax | | ||
| 1415 | + | SK_ScalarMax SK_ScalarMax SK_ScalarMax | | ||
| 1416 | + | SK_ScalarMax SK_ScalarMax SK_ScalarMax | | ||
| 1417 | + | ||
| 1418 | + @return const invalid Matrix | ||
| 1419 | + */ | ||
| 1420 | + static const Matrix& InvalidMatrix(); | ||
| 1421 | + | ||
| 1422 | + /** Returns Matrix a multiplied by Matrix b. | ||
| 1423 | + | ||
| 1424 | + Given: | ||
| 1425 | + | ||
| 1426 | + | A B C | | J K L | | ||
| 1427 | + a = | D E F |, b = | M N O | | ||
| 1428 | + | G H I | | P Q R | | ||
| 1429 | + | ||
| 1430 | + sets Matrix to: | ||
| 1431 | + | ||
| 1432 | + | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | | ||
| 1433 | + a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | | ||
| 1434 | + | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | | ||
| 1435 | + | ||
| 1436 | + @param a Matrix on left side of multiply expression | ||
| 1437 | + @param b Matrix on right side of multiply expression | ||
| 1438 | + @return Matrix computed from a times b | ||
| 1439 | + */ | ||
| 1440 | + static Matrix Concat(const Matrix& a, const Matrix& b) { | ||
| 1441 | + Matrix result; | ||
| 1442 | + result.setConcat(a, b); | ||
| 1443 | + return result; | ||
| 1444 | + } | ||
| 1445 | + | ||
| 1446 | + /** Sets internal cache to unknown state. Use to force update after repeated | ||
| 1447 | + modifications to Matrix element reference returned by operator[](int index). | ||
| 1448 | + */ | ||
| 1449 | + void dirtyMatrixTypeCache() { | ||
| 1450 | + this->setTypeMask(kUnknown_Mask); | ||
| 1451 | + } | ||
| 1452 | + | ||
| 1453 | + /** Initializes Matrix with scale and translate elements. | ||
| 1454 | + | ||
| 1455 | + | sx 0 tx | | ||
| 1456 | + | 0 sy ty | | ||
| 1457 | + | 0 0 1 | | ||
| 1458 | + | ||
| 1459 | + @param sx horizontal scale factor to store | ||
| 1460 | + @param sy vertical scale factor to store | ||
| 1461 | + @param tx horizontal translation to store | ||
| 1462 | + @param ty vertical translation to store | ||
| 1463 | + */ | ||
| 1464 | + void setScaleTranslate(float sx, float sy, float tx, float ty) { | ||
| 1465 | + fMat[kMScaleX] = sx; | ||
| 1466 | + fMat[kMSkewX] = 0; | ||
| 1467 | + fMat[kMTransX] = tx; | ||
| 1468 | + | ||
| 1469 | + fMat[kMSkewY] = 0; | ||
| 1470 | + fMat[kMScaleY] = sy; | ||
| 1471 | + fMat[kMTransY] = ty; | ||
| 1472 | + | ||
| 1473 | + fMat[kMPersp0] = 0; | ||
| 1474 | + fMat[kMPersp1] = 0; | ||
| 1475 | + fMat[kMPersp2] = 1; | ||
| 1476 | + | ||
| 1477 | + unsigned mask = 0; | ||
| 1478 | + if (sx != 1 || sy != 1) { | ||
| 1479 | + mask |= kScale_Mask; | ||
| 1480 | + } | ||
| 1481 | + if (tx || ty) { | ||
| 1482 | + mask |= kTranslate_Mask; | ||
| 1483 | + } | ||
| 1484 | + this->setTypeMask(mask | kRectStaysRect_Mask); | ||
| 1485 | + } | ||
| 1486 | + | ||
| 1487 | + /** Returns true if all elements of the matrix are finite. Returns false if any | ||
| 1488 | + element is infinity, or NaN. | ||
| 1489 | + | ||
| 1490 | + @return true if matrix has only finite elements | ||
| 1491 | + */ | ||
| 1492 | + | ||
| 1493 | +private: | ||
| 1494 | + /** Set if the matrix will map a rectangle to another rectangle. This | ||
| 1495 | + can be true if the matrix is scale-only, or rotates a multiple of | ||
| 1496 | + 90 degrees. | ||
| 1497 | + | ||
| 1498 | + This bit will be set on identity matrices | ||
| 1499 | + */ | ||
| 1500 | + static constexpr int kRectStaysRect_Mask = 0x10; | ||
| 1501 | + | ||
| 1502 | + /** Set if the perspective bit is valid even though the rest of | ||
| 1503 | + the matrix is Unknown. | ||
| 1504 | + */ | ||
| 1505 | + static constexpr int kOnlyPerspectiveValid_Mask = 0x40; | ||
| 1506 | + | ||
| 1507 | + static constexpr int kUnknown_Mask = 0x80; | ||
| 1508 | + | ||
| 1509 | + static constexpr int kORableMasks = kTranslate_Mask | kScale_Mask | kAffine_Mask | kPerspective_Mask; | ||
| 1510 | + | ||
| 1511 | + static constexpr int kAllMasks = | ||
| 1512 | + kTranslate_Mask | kScale_Mask | kAffine_Mask | kPerspective_Mask | kRectStaysRect_Mask; | ||
| 1513 | + | ||
| 1514 | + float fMat[9]; | ||
| 1515 | + mutable uint32_t fTypeMask; | ||
| 1516 | + | ||
| 1517 | + static void ComputeInv(float dst[9], const float src[9], double invDet, bool isPersp); | ||
| 1518 | + | ||
| 1519 | + uint8_t computeTypeMask() const; | ||
| 1520 | + uint8_t computePerspectiveTypeMask() const; | ||
| 1521 | + | ||
| 1522 | + void setTypeMask(int mask) { | ||
| 1523 | + // allow kUnknown or a valid mask | ||
| 1524 | + MNN_ASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask || | ||
| 1525 | + ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask) == | ||
| 1526 | + (kUnknown_Mask | kOnlyPerspectiveValid_Mask)); | ||
| 1527 | + fTypeMask = (uint8_t)(mask); | ||
| 1528 | + } | ||
| 1529 | + | ||
| 1530 | + void orTypeMask(int mask) { | ||
| 1531 | + MNN_ASSERT((mask & kORableMasks) == mask); | ||
| 1532 | + fTypeMask = (uint8_t)(fTypeMask | mask); | ||
| 1533 | + } | ||
| 1534 | + | ||
| 1535 | + void clearTypeMask(int mask) { | ||
| 1536 | + // only allow a valid mask | ||
| 1537 | + MNN_ASSERT((mask & kAllMasks) == mask); | ||
| 1538 | + fTypeMask = fTypeMask & ~mask; | ||
| 1539 | + } | ||
| 1540 | + | ||
| 1541 | + TypeMask getPerspectiveTypeMaskOnly() const { | ||
| 1542 | + if ((fTypeMask & kUnknown_Mask) && !(fTypeMask & kOnlyPerspectiveValid_Mask)) { | ||
| 1543 | + fTypeMask = this->computePerspectiveTypeMask(); | ||
| 1544 | + } | ||
| 1545 | + return (TypeMask)(fTypeMask & 0xF); | ||
| 1546 | + } | ||
| 1547 | + | ||
| 1548 | + /** Returns true if we already know that the matrix is identity; | ||
| 1549 | + false otherwise. | ||
| 1550 | + */ | ||
| 1551 | + bool isTriviallyIdentity() const { | ||
| 1552 | + if (fTypeMask & kUnknown_Mask) { | ||
| 1553 | + return false; | ||
| 1554 | + } | ||
| 1555 | + return ((fTypeMask & 0xF) == 0); | ||
| 1556 | + } | ||
| 1557 | + | ||
| 1558 | + inline void updateTranslateMask() { | ||
| 1559 | + if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) { | ||
| 1560 | + fTypeMask |= kTranslate_Mask; | ||
| 1561 | + } else { | ||
| 1562 | + fTypeMask &= ~kTranslate_Mask; | ||
| 1563 | + } | ||
| 1564 | + } | ||
| 1565 | + | ||
| 1566 | + typedef void (*MapXYProc)(const Matrix& mat, float x, float y, Point* result); | ||
| 1567 | + | ||
| 1568 | + static MapXYProc GetMapXYProc(TypeMask mask) { | ||
| 1569 | + MNN_ASSERT((mask & ~kAllMasks) == 0); | ||
| 1570 | + return gMapXYProcs[mask & kAllMasks]; | ||
| 1571 | + } | ||
| 1572 | + | ||
| 1573 | + MapXYProc getMapXYProc() const { | ||
| 1574 | + return GetMapXYProc(this->getType()); | ||
| 1575 | + } | ||
| 1576 | + | ||
| 1577 | + typedef void (*MapPtsProc)(const Matrix& mat, Point dst[], const Point src[], int count); | ||
| 1578 | + | ||
| 1579 | + static MapPtsProc GetMapPtsProc(TypeMask mask) { | ||
| 1580 | + MNN_ASSERT((mask & ~kAllMasks) == 0); | ||
| 1581 | + return gMapPtsProcs[mask & kAllMasks]; | ||
| 1582 | + } | ||
| 1583 | + | ||
| 1584 | + MapPtsProc getMapPtsProc() const { | ||
| 1585 | + return GetMapPtsProc(this->getType()); | ||
| 1586 | + } | ||
| 1587 | + | ||
| 1588 | + bool invertNonIdentity(Matrix* inverse) const; | ||
| 1589 | + | ||
| 1590 | + static void Identity_xy(const Matrix&, float, float, Point*); | ||
| 1591 | + static void Trans_xy(const Matrix&, float, float, Point*); | ||
| 1592 | + static void Scale_xy(const Matrix&, float, float, Point*); | ||
| 1593 | + static void ScaleTrans_xy(const Matrix&, float, float, Point*); | ||
| 1594 | + static void Rot_xy(const Matrix&, float, float, Point*); | ||
| 1595 | + static void RotTrans_xy(const Matrix&, float, float, Point*); | ||
| 1596 | + static void Persp_xy(const Matrix&, float, float, Point*); | ||
| 1597 | + | ||
| 1598 | + static const MapXYProc gMapXYProcs[]; | ||
| 1599 | + | ||
| 1600 | + static void Identity_pts(const Matrix&, Point[], const Point[], int); | ||
| 1601 | + static void Trans_pts(const Matrix&, Point dst[], const Point[], int); | ||
| 1602 | + static void Scale_pts(const Matrix&, Point dst[], const Point[], int); | ||
| 1603 | + static void ScaleTrans_pts(const Matrix&, Point dst[], const Point[], int count); | ||
| 1604 | + static void Persp_pts(const Matrix&, Point dst[], const Point[], int); | ||
| 1605 | + | ||
| 1606 | + static void Affine_vpts(const Matrix&, Point dst[], const Point[], int); | ||
| 1607 | + | ||
| 1608 | + static const MapPtsProc gMapPtsProcs[]; | ||
| 1609 | + static bool Poly2Proc(const Point srcPt[], Matrix* dst); | ||
| 1610 | + static bool Poly3Proc(const Point srcPt[], Matrix* dst); | ||
| 1611 | + static bool Poly4Proc(const Point srcPt[], Matrix* dst); | ||
| 1612 | +}; | ||
| 1613 | +} // namespace CV | ||
| 1614 | +} // namespace MNN | ||
| 1615 | +#endif |
lite.ai.toolkit/include/MNN/Rect.h
0 → 100644
| 1 | +// | ||
| 2 | +// Rect.h | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Modified by jiangxiaotang on 2018/09/19. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +/* | ||
| 10 | + * Copyright 2006 The Android Open Source Project | ||
| 11 | + * | ||
| 12 | + * Use of this source code is governed by a BSD-style license that can be | ||
| 13 | + * found in the LICENSE file. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +/* Generated by tools/bookmaker from include/core/Rect.h and docs/SkRect_Reference.bmh | ||
| 17 | + on 2018-07-13 08:15:11. Additional documentation and examples can be found at: | ||
| 18 | + https://skia.org/user/api/SkRect_Reference | ||
| 19 | + | ||
| 20 | + You may edit either file directly. Structural changes to public interfaces require | ||
| 21 | + editing both files. After editing docs/SkRect_Reference.bmh, run: | ||
| 22 | + bookmaker -b docs -i include/core/Rect.h -p | ||
| 23 | + to create an updated version of this file. | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +#ifndef SkRect_DEFINED | ||
| 27 | +#define SkRect_DEFINED | ||
| 28 | + | ||
| 29 | +#include <math.h> | ||
| 30 | +#include <algorithm> | ||
| 31 | +#include <utility> | ||
| 32 | +#include <MNN/MNNDefine.h> | ||
| 33 | + | ||
| 34 | +namespace MNN { | ||
| 35 | +namespace CV { | ||
| 36 | + | ||
| 37 | +struct Point { | ||
| 38 | + float fX; | ||
| 39 | + float fY; | ||
| 40 | + | ||
| 41 | + void set(float x, float y) { | ||
| 42 | + fX = x; | ||
| 43 | + fY = y; | ||
| 44 | + } | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +/** \struct Rect | ||
| 48 | + Rect holds four float coordinates describing the upper and | ||
| 49 | + lower bounds of a rectangle. Rect may be created from outer bounds or | ||
| 50 | + from position, width, and height. Rect describes an area; if its right | ||
| 51 | + is less than or equal to its left, or if its bottom is less than or equal to | ||
| 52 | + its top, it is considered empty. | ||
| 53 | +*/ | ||
| 54 | +struct MNN_PUBLIC Rect { | ||
| 55 | + float fLeft; //!< smaller x-axis bounds | ||
| 56 | + float fTop; //!< smaller y-axis bounds | ||
| 57 | + float fRight; //!< larger x-axis bounds | ||
| 58 | + float fBottom; //!< larger y-axis bounds | ||
| 59 | + | ||
| 60 | + /** Returns constructed Rect set to (0, 0, 0, 0). | ||
| 61 | + Many other rectangles are empty; if left is equal to or greater than right, | ||
| 62 | + or if top is equal to or greater than bottom. Setting all members to zero | ||
| 63 | + is a convenience, but does not designate a special empty rectangle. | ||
| 64 | + | ||
| 65 | + @return bounds (0, 0, 0, 0) | ||
| 66 | + */ | ||
| 67 | + static constexpr Rect MakeEmpty() { | ||
| 68 | + return Rect{0, 0, 0, 0}; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | +#ifdef SK_SUPPORT_LEGACY_RECTMAKELARGEST | ||
| 72 | + /** Deprecated. | ||
| 73 | + */ | ||
| 74 | + static Rect MakeLargest() { | ||
| 75 | + return {SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax}; | ||
| 76 | + } | ||
| 77 | +#endif | ||
| 78 | + | ||
| 79 | + /** Returns constructed Rect set to float values (0, 0, w, h). Does not | ||
| 80 | + validate input; w or h may be negative. | ||
| 81 | + | ||
| 82 | + Passing integer values may generate a compiler warning since Rect cannot | ||
| 83 | + represent 32-bit integers exactly. Use SkIRect for an exact integer rectangle. | ||
| 84 | + | ||
| 85 | + @param w float width of constructed Rect | ||
| 86 | + @param h float height of constructed Rect | ||
| 87 | + @return bounds (0, 0, w, h) | ||
| 88 | + */ | ||
| 89 | + static constexpr Rect MakeWH(float w, float h) { | ||
| 90 | + return Rect{0, 0, w, h}; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** Returns constructed Rect set to integer values (0, 0, w, h). Does not validate | ||
| 94 | + input; w or h may be negative. | ||
| 95 | + | ||
| 96 | + Use to avoid a compiler warning that input may lose precision when stored. | ||
| 97 | + Use SkIRect for an exact integer rectangle. | ||
| 98 | + | ||
| 99 | + @param w integer width of constructed Rect | ||
| 100 | + @param h integer height of constructed Rect | ||
| 101 | + @return bounds (0, 0, w, h) | ||
| 102 | + */ | ||
| 103 | + static Rect MakeIWH(int w, int h) { | ||
| 104 | + Rect r; | ||
| 105 | + r.set(0, 0, (float)(w), (float)(h)); | ||
| 106 | + return r; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + /** Returns constructed Rect set to (l, t, r, b). Does not sort input; Rect may | ||
| 110 | + result in fLeft greater than fRight, or fTop greater than fBottom. | ||
| 111 | + | ||
| 112 | + @param l float stored in fLeft | ||
| 113 | + @param t float stored in fTop | ||
| 114 | + @param r float stored in fRight | ||
| 115 | + @param b float stored in fBottom | ||
| 116 | + @return bounds (l, t, r, b) | ||
| 117 | + */ | ||
| 118 | + static constexpr Rect MakeLTRB(float l, float t, float r, float b) { | ||
| 119 | + return Rect{l, t, r, b}; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /** Returns constructed Rect set to (x, y, x + w, y + h). Does not validate input; | ||
| 123 | + w or h may be negative. | ||
| 124 | + | ||
| 125 | + @param x stored in fLeft | ||
| 126 | + @param y stored in fTop | ||
| 127 | + @param w added to x and stored in fRight | ||
| 128 | + @param h added to y and stored in fBottom | ||
| 129 | + @return bounds at (x, y) with width w and height h | ||
| 130 | + */ | ||
| 131 | + static constexpr Rect MakeXYWH(float x, float y, float w, float h) { | ||
| 132 | + return Rect{x, y, x + w, y + h}; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + /** Returns true if fLeft is equal to or greater than fRight, or if fTop is equal | ||
| 136 | + to or greater than fBottom. Call sort() to reverse rectangles with negative | ||
| 137 | + width() or height(). | ||
| 138 | + | ||
| 139 | + @return true if width() or height() are zero or negative | ||
| 140 | + */ | ||
| 141 | + bool isEmpty() const { | ||
| 142 | + // We write it as the NOT of a non-empty rect, so we will return true if any values | ||
| 143 | + // are NaN. | ||
| 144 | + return !(fLeft < fRight && fTop < fBottom); | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + /** Returns true if fLeft is equal to or less than fRight, or if fTop is equal | ||
| 148 | + to or less than fBottom. Call sort() to reverse rectangles with negative | ||
| 149 | + width() or height(). | ||
| 150 | + | ||
| 151 | + @return true if width() or height() are zero or positive | ||
| 152 | + */ | ||
| 153 | + bool isSorted() const { | ||
| 154 | + return fLeft <= fRight && fTop <= fBottom; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + /** Returns left edge of Rect, if sorted. Call isSorted() to see if Rect is valid. | ||
| 158 | + Call sort() to reverse fLeft and fRight if needed. | ||
| 159 | + | ||
| 160 | + @return fLeft | ||
| 161 | + */ | ||
| 162 | + float x() const { | ||
| 163 | + return fLeft; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + /** Returns top edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid, | ||
| 167 | + and sort() to reverse fTop and fBottom if needed. | ||
| 168 | + | ||
| 169 | + @return fTop | ||
| 170 | + */ | ||
| 171 | + float y() const { | ||
| 172 | + return fTop; | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + /** Returns left edge of Rect, if sorted. Call isSorted() to see if Rect is valid. | ||
| 176 | + Call sort() to reverse fLeft and fRight if needed. | ||
| 177 | + | ||
| 178 | + @return fLeft | ||
| 179 | + */ | ||
| 180 | + float left() const { | ||
| 181 | + return fLeft; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /** Returns top edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid, | ||
| 185 | + and sort() to reverse fTop and fBottom if needed. | ||
| 186 | + | ||
| 187 | + @return fTop | ||
| 188 | + */ | ||
| 189 | + float top() const { | ||
| 190 | + return fTop; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** Returns right edge of Rect, if sorted. Call isSorted() to see if Rect is valid. | ||
| 194 | + Call sort() to reverse fLeft and fRight if needed. | ||
| 195 | + | ||
| 196 | + @return fRight | ||
| 197 | + */ | ||
| 198 | + float right() const { | ||
| 199 | + return fRight; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + /** Returns bottom edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid, | ||
| 203 | + and sort() to reverse fTop and fBottom if needed. | ||
| 204 | + | ||
| 205 | + @return fBottom | ||
| 206 | + */ | ||
| 207 | + float bottom() const { | ||
| 208 | + return fBottom; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + /** Returns span on the x-axis. This does not check if Rect is sorted, or if | ||
| 212 | + result fits in 32-bit float; result may be negative or infinity. | ||
| 213 | + | ||
| 214 | + @return fRight minus fLeft | ||
| 215 | + */ | ||
| 216 | + float width() const { | ||
| 217 | + return fRight - fLeft; | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + /** Returns span on the y-axis. This does not check if Rect is sorted, or if | ||
| 221 | + result fits in 32-bit float; result may be negative or infinity. | ||
| 222 | + | ||
| 223 | + @return fBottom minus fTop | ||
| 224 | + */ | ||
| 225 | + float height() const { | ||
| 226 | + return fBottom - fTop; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + /** Returns average of left edge and right edge. Result does not change if Rect | ||
| 230 | + is sorted. Result may overflow to infinity if Rect is far from the origin. | ||
| 231 | + | ||
| 232 | + @return midpoint in x | ||
| 233 | + */ | ||
| 234 | + float centerX() const { | ||
| 235 | + // don't use floatHalf(fLeft + fBottom) as that might overflow before the 0.5 | ||
| 236 | + return 0.5f * (fLeft) + 0.5f * (fRight); | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + /** Returns average of top edge and bottom edge. Result does not change if Rect | ||
| 240 | + is sorted. | ||
| 241 | + | ||
| 242 | + @return midpoint in y | ||
| 243 | + */ | ||
| 244 | + float centerY() const { | ||
| 245 | + // don't use floatHalf(fTop + fBottom) as that might overflow before the 0.5 | ||
| 246 | + return 0.5f * (fTop) + 0.5f * (fBottom); | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + /** Sets Rect to (0, 0, 0, 0). | ||
| 250 | + | ||
| 251 | + Many other rectangles are empty; if left is equal to or greater than right, | ||
| 252 | + or if top is equal to or greater than bottom. Setting all members to zero | ||
| 253 | + is a convenience, but does not designate a special empty rectangle. | ||
| 254 | + */ | ||
| 255 | + void setEmpty() { | ||
| 256 | + *this = MakeEmpty(); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + /** Sets Rect to (left, top, right, bottom). | ||
| 260 | + left and right are not sorted; left is not necessarily less than right. | ||
| 261 | + top and bottom are not sorted; top is not necessarily less than bottom. | ||
| 262 | + | ||
| 263 | + @param left stored in fLeft | ||
| 264 | + @param top stored in fTop | ||
| 265 | + @param right stored in fRight | ||
| 266 | + @param bottom stored in fBottom | ||
| 267 | + */ | ||
| 268 | + void set(float left, float top, float right, float bottom) { | ||
| 269 | + fLeft = left; | ||
| 270 | + fTop = top; | ||
| 271 | + fRight = right; | ||
| 272 | + fBottom = bottom; | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + /** Sets Rect to (left, top, right, bottom). | ||
| 276 | + left and right are not sorted; left is not necessarily less than right. | ||
| 277 | + top and bottom are not sorted; top is not necessarily less than bottom. | ||
| 278 | + | ||
| 279 | + @param left stored in fLeft | ||
| 280 | + @param top stored in fTop | ||
| 281 | + @param right stored in fRight | ||
| 282 | + @param bottom stored in fBottom | ||
| 283 | + */ | ||
| 284 | + void setLTRB(float left, float top, float right, float bottom) { | ||
| 285 | + this->set(left, top, right, bottom); | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + /** Sets Rect to (left, top, right, bottom). | ||
| 289 | + All parameters are promoted from integer to scalar. | ||
| 290 | + left and right are not sorted; left is not necessarily less than right. | ||
| 291 | + top and bottom are not sorted; top is not necessarily less than bottom. | ||
| 292 | + | ||
| 293 | + @param left promoted to float and stored in fLeft | ||
| 294 | + @param top promoted to float and stored in fTop | ||
| 295 | + @param right promoted to float and stored in fRight | ||
| 296 | + @param bottom promoted to float and stored in fBottom | ||
| 297 | + */ | ||
| 298 | + void iset(int left, int top, int right, int bottom) { | ||
| 299 | + fLeft = (float)(left); | ||
| 300 | + fTop = (float)(top); | ||
| 301 | + fRight = (float)(right); | ||
| 302 | + fBottom = (float)(bottom); | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + /** Sets Rect to (0, 0, width, height). | ||
| 306 | + width and height may be zero or negative. width and height are promoted from | ||
| 307 | + integer to float, large values may lose precision. | ||
| 308 | + | ||
| 309 | + @param width promoted to float and stored in fRight | ||
| 310 | + @param height promoted to float and stored in fBottom | ||
| 311 | + */ | ||
| 312 | + void isetWH(int width, int height) { | ||
| 313 | + fLeft = fTop = 0; | ||
| 314 | + fRight = (float)(width); | ||
| 315 | + fBottom = (float)(height); | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + /** Sets Rect to (x, y, x + width, y + height). Does not validate input; | ||
| 319 | + width or height may be negative. | ||
| 320 | + | ||
| 321 | + @param x stored in fLeft | ||
| 322 | + @param y stored in fTop | ||
| 323 | + @param width added to x and stored in fRight | ||
| 324 | + @param height added to y and stored in fBottom | ||
| 325 | + */ | ||
| 326 | + void setXYWH(float x, float y, float width, float height) { | ||
| 327 | + fLeft = x; | ||
| 328 | + fTop = y; | ||
| 329 | + fRight = x + width; | ||
| 330 | + fBottom = y + height; | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + /** Sets Rect to (0, 0, width, height). Does not validate input; | ||
| 334 | + width or height may be negative. | ||
| 335 | + | ||
| 336 | + @param width stored in fRight | ||
| 337 | + @param height stored in fBottom | ||
| 338 | + */ | ||
| 339 | + void setWH(float width, float height) { | ||
| 340 | + fLeft = 0; | ||
| 341 | + fTop = 0; | ||
| 342 | + fRight = width; | ||
| 343 | + fBottom = height; | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + /** Returns Rect offset by (dx, dy). | ||
| 347 | + | ||
| 348 | + If dx is negative, Rect returned is moved to the left. | ||
| 349 | + If dx is positive, Rect returned is moved to the right. | ||
| 350 | + If dy is negative, Rect returned is moved upward. | ||
| 351 | + If dy is positive, Rect returned is moved downward. | ||
| 352 | + | ||
| 353 | + @param dx added to fLeft and fRight | ||
| 354 | + @param dy added to fTop and fBottom | ||
| 355 | + @return Rect offset on axes, with original width and height | ||
| 356 | + */ | ||
| 357 | + Rect makeOffset(float dx, float dy) const { | ||
| 358 | + return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + /** Returns Rect, inset by (dx, dy). | ||
| 362 | + | ||
| 363 | + If dx is negative, Rect returned is wider. | ||
| 364 | + If dx is positive, Rect returned is narrower. | ||
| 365 | + If dy is negative, Rect returned is taller. | ||
| 366 | + If dy is positive, Rect returned is shorter. | ||
| 367 | + | ||
| 368 | + @param dx added to fLeft and subtracted from fRight | ||
| 369 | + @param dy added to fTop and subtracted from fBottom | ||
| 370 | + @return Rect inset symmetrically left and right, top and bottom | ||
| 371 | + */ | ||
| 372 | + Rect makeInset(float dx, float dy) const { | ||
| 373 | + return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + /** Returns Rect, outset by (dx, dy). | ||
| 377 | + | ||
| 378 | + If dx is negative, Rect returned is narrower. | ||
| 379 | + If dx is positive, Rect returned is wider. | ||
| 380 | + If dy is negative, Rect returned is shorter. | ||
| 381 | + If dy is positive, Rect returned is taller. | ||
| 382 | + | ||
| 383 | + @param dx subtracted to fLeft and added from fRight | ||
| 384 | + @param dy subtracted to fTop and added from fBottom | ||
| 385 | + @return Rect outset symmetrically left and right, top and bottom | ||
| 386 | + */ | ||
| 387 | + Rect makeOutset(float dx, float dy) const { | ||
| 388 | + return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + /** Offsets Rect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom. | ||
| 392 | + | ||
| 393 | + If dx is negative, moves Rect to the left. | ||
| 394 | + If dx is positive, moves Rect to the right. | ||
| 395 | + If dy is negative, moves Rect upward. | ||
| 396 | + If dy is positive, moves Rect downward. | ||
| 397 | + | ||
| 398 | + @param dx offset added to fLeft and fRight | ||
| 399 | + @param dy offset added to fTop and fBottom | ||
| 400 | + */ | ||
| 401 | + void offset(float dx, float dy) { | ||
| 402 | + fLeft += dx; | ||
| 403 | + fTop += dy; | ||
| 404 | + fRight += dx; | ||
| 405 | + fBottom += dy; | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + /** Offsets Rect so that fLeft equals newX, and fTop equals newY. width and height | ||
| 409 | + are unchanged. | ||
| 410 | + | ||
| 411 | + @param newX stored in fLeft, preserving width() | ||
| 412 | + @param newY stored in fTop, preserving height() | ||
| 413 | + */ | ||
| 414 | + void offsetTo(float newX, float newY) { | ||
| 415 | + fRight += newX - fLeft; | ||
| 416 | + fBottom += newY - fTop; | ||
| 417 | + fLeft = newX; | ||
| 418 | + fTop = newY; | ||
| 419 | + } | ||
| 420 | + | ||
| 421 | + /** Insets Rect by (dx, dy). | ||
| 422 | + | ||
| 423 | + If dx is positive, makes Rect narrower. | ||
| 424 | + If dx is negative, makes Rect wider. | ||
| 425 | + If dy is positive, makes Rect shorter. | ||
| 426 | + If dy is negative, makes Rect taller. | ||
| 427 | + | ||
| 428 | + @param dx added to fLeft and subtracted from fRight | ||
| 429 | + @param dy added to fTop and subtracted from fBottom | ||
| 430 | + */ | ||
| 431 | + void inset(float dx, float dy) { | ||
| 432 | + fLeft += dx; | ||
| 433 | + fTop += dy; | ||
| 434 | + fRight -= dx; | ||
| 435 | + fBottom -= dy; | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + /** Outsets Rect by (dx, dy). | ||
| 439 | + | ||
| 440 | + If dx is positive, makes Rect wider. | ||
| 441 | + If dx is negative, makes Rect narrower. | ||
| 442 | + If dy is positive, makes Rect taller. | ||
| 443 | + If dy is negative, makes Rect shorter. | ||
| 444 | + | ||
| 445 | + @param dx subtracted to fLeft and added from fRight | ||
| 446 | + @param dy subtracted to fTop and added from fBottom | ||
| 447 | + */ | ||
| 448 | + void outset(float dx, float dy) { | ||
| 449 | + this->inset(-dx, -dy); | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | +private: | ||
| 453 | + static bool Intersects(float al, float at, float ar, float ab, float bl, float bt, float br, float bb) { | ||
| 454 | + float L = std::max(al, bl); | ||
| 455 | + float R = std::min(ar, br); | ||
| 456 | + float T = std::max(at, bt); | ||
| 457 | + float B = std::min(ab, bb); | ||
| 458 | + return L < R && T < B; | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | +public: | ||
| 462 | + /** Constructs Rect to intersect from (left, top, right, bottom). Does not sort | ||
| 463 | + construction. | ||
| 464 | + | ||
| 465 | + Returns true if Rect intersects construction. | ||
| 466 | + Returns false if either construction or Rect is empty, or do not intersect. | ||
| 467 | + | ||
| 468 | + @param left x-axis minimum of constructed Rect | ||
| 469 | + @param top y-axis minimum of constructed Rect | ||
| 470 | + @param right x-axis maximum of constructed Rect | ||
| 471 | + @param bottom y-axis maximum of constructed Rect | ||
| 472 | + @return true if construction and Rect have area in common | ||
| 473 | + */ | ||
| 474 | + bool intersects(float left, float top, float right, float bottom) const { | ||
| 475 | + return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom); | ||
| 476 | + } | ||
| 477 | + | ||
| 478 | + /** Returns true if Rect intersects r. | ||
| 479 | + Returns false if either r or Rect is empty, or do not intersect. | ||
| 480 | + | ||
| 481 | + @param r Rect to intersect | ||
| 482 | + @return true if r and Rect have area in common | ||
| 483 | + */ | ||
| 484 | + bool intersects(const Rect& r) const { | ||
| 485 | + return Intersects(fLeft, fTop, fRight, fBottom, r.fLeft, r.fTop, r.fRight, r.fBottom); | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + /** Returns true if a intersects b. | ||
| 489 | + Returns false if either a or b is empty, or do not intersect. | ||
| 490 | + | ||
| 491 | + @param a Rect to intersect | ||
| 492 | + @param b Rect to intersect | ||
| 493 | + @return true if a and b have area in common | ||
| 494 | + */ | ||
| 495 | + static bool Intersects(const Rect& a, const Rect& b) { | ||
| 496 | + return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, b.fLeft, b.fTop, b.fRight, b.fBottom); | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + /** Sets Rect to the union of itself and r. | ||
| 500 | + | ||
| 501 | + Asserts if r is empty and SK_DEBUG is defined. | ||
| 502 | + If Rect is empty, sets Rect to r. | ||
| 503 | + | ||
| 504 | + May produce incorrect results if r is empty. | ||
| 505 | + | ||
| 506 | + @param r expansion Rect | ||
| 507 | + */ | ||
| 508 | + void joinNonEmptyArg(const Rect& r) { | ||
| 509 | + MNN_ASSERT(!r.isEmpty()); | ||
| 510 | + // if we are empty, just assign | ||
| 511 | + if (fLeft >= fRight || fTop >= fBottom) { | ||
| 512 | + *this = r; | ||
| 513 | + } else { | ||
| 514 | + this->joinPossiblyEmptyRect(r); | ||
| 515 | + } | ||
| 516 | + } | ||
| 517 | + | ||
| 518 | + /** Sets Rect to the union of itself and the construction. | ||
| 519 | + | ||
| 520 | + May produce incorrect results if Rect or r is empty. | ||
| 521 | + | ||
| 522 | + @param r expansion Rect | ||
| 523 | + */ | ||
| 524 | + void joinPossiblyEmptyRect(const Rect& r) { | ||
| 525 | + fLeft = std::min(fLeft, r.left()); | ||
| 526 | + fTop = std::min(fTop, r.top()); | ||
| 527 | + fRight = std::max(fRight, r.right()); | ||
| 528 | + fBottom = std::max(fBottom, r.bottom()); | ||
| 529 | + } | ||
| 530 | + | ||
| 531 | + /** Returns true if: fLeft <= x < fRight && fTop <= y < fBottom. | ||
| 532 | + Returns false if Rect is empty. | ||
| 533 | + | ||
| 534 | + @param x test Point x-coordinate | ||
| 535 | + @param y test Point y-coordinate | ||
| 536 | + @return true if (x, y) is inside Rect | ||
| 537 | + */ | ||
| 538 | + bool contains(float x, float y) const { | ||
| 539 | + return x >= fLeft && x < fRight && y >= fTop && y < fBottom; | ||
| 540 | + } | ||
| 541 | + | ||
| 542 | + /** Swaps fLeft and fRight if fLeft is greater than fRight; and swaps | ||
| 543 | + fTop and fBottom if fTop is greater than fBottom. Result may be empty; | ||
| 544 | + and width() and height() will be zero or positive. | ||
| 545 | + */ | ||
| 546 | + void sort() { | ||
| 547 | + using std::swap; | ||
| 548 | + if (fLeft > fRight) { | ||
| 549 | + swap(fLeft, fRight); | ||
| 550 | + } | ||
| 551 | + | ||
| 552 | + if (fTop > fBottom) { | ||
| 553 | + swap(fTop, fBottom); | ||
| 554 | + } | ||
| 555 | + } | ||
| 556 | + | ||
| 557 | + /** Returns Rect with fLeft and fRight swapped if fLeft is greater than fRight; and | ||
| 558 | + with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty; | ||
| 559 | + and width() and height() will be zero or positive. | ||
| 560 | + | ||
| 561 | + @return sorted Rect | ||
| 562 | + */ | ||
| 563 | + Rect makeSorted() const { | ||
| 564 | + return MakeLTRB(std::min(fLeft, fRight), std::min(fTop, fBottom), std::max(fLeft, fRight), | ||
| 565 | + std::max(fTop, fBottom)); | ||
| 566 | + } | ||
| 567 | + | ||
| 568 | + /** Returns pointer to first scalar in Rect, to treat it as an array with four | ||
| 569 | + entries. | ||
| 570 | + | ||
| 571 | + @return pointer to fLeft | ||
| 572 | + */ | ||
| 573 | + const float* asScalars() const { | ||
| 574 | + return &fLeft; | ||
| 575 | + } | ||
| 576 | +}; | ||
| 577 | + | ||
| 578 | +} // namespace CV | ||
| 579 | +} // namespace MNN | ||
| 580 | +#endif |
lite.ai.toolkit/include/MNN/Tensor.hpp
0 → 100644
| 1 | +// | ||
| 2 | +// Tensor.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2018/08/14. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef Tensor_hpp | ||
| 10 | +#define Tensor_hpp | ||
| 11 | + | ||
| 12 | +#include <vector> | ||
| 13 | +#include <MNN/HalideRuntime.h> | ||
| 14 | +#include <MNN/MNNDefine.h> | ||
| 15 | +#define MNN_MAX_TENSOR_DIM 6 | ||
| 16 | + | ||
| 17 | +namespace MNN { | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * data container. | ||
| 21 | + * data for host tensor is saved in `host` field. its memory is allocated malloc directly. | ||
| 22 | + * data for device tensor is saved in `deviceId` field. its memory is allocated by session's backend. | ||
| 23 | + * usually, device tensors are created by engine (like net, session). | ||
| 24 | + * meanwhile, host tensors could be created by engine or user. | ||
| 25 | + */ | ||
| 26 | +class MNN_PUBLIC Tensor { | ||
| 27 | +public: | ||
| 28 | + struct InsideDescribe; | ||
| 29 | + | ||
| 30 | + /** dimension type used to create tensor */ | ||
| 31 | + enum DimensionType { | ||
| 32 | + /** for tensorflow net type. uses NHWC as data format. */ | ||
| 33 | + TENSORFLOW, | ||
| 34 | + /** for caffe net type. uses NCHW as data format. */ | ||
| 35 | + CAFFE, | ||
| 36 | + /** for caffe net type. uses NC4HW4 as data format. */ | ||
| 37 | + CAFFE_C4 | ||
| 38 | + }; | ||
| 39 | + | ||
| 40 | + /** handle type */ | ||
| 41 | + enum HandleDataType { | ||
| 42 | + /** default handle type */ | ||
| 43 | + HANDLE_NONE = 0, | ||
| 44 | + /** string handle type */ | ||
| 45 | + HANDLE_STRING = 1 | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + /** Tensor map type : Read or Write*/ | ||
| 49 | + enum MapType { | ||
| 50 | + /** map Tensor for writing data*/ | ||
| 51 | + MAP_TENSOR_WRITE = 0, | ||
| 52 | + MAP_TENSOR_READ = 1 | ||
| 53 | + }; | ||
| 54 | + | ||
| 55 | +public: | ||
| 56 | + /** | ||
| 57 | + * @brief create a tensor with dimension size and type without acquire memory for data. | ||
| 58 | + * @param dimSize dimension size. | ||
| 59 | + * @param type dimension type. | ||
| 60 | + */ | ||
| 61 | + Tensor(int dimSize = 4, DimensionType type = CAFFE); | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * @brief create a tensor with same shape as given tensor. | ||
| 65 | + * @param tensor shape provider. | ||
| 66 | + * @param type dimension type. | ||
| 67 | + * @param allocMemory acquire memory for data or not. | ||
| 68 | + * @warning tensor data won't be copied. | ||
| 69 | + */ | ||
| 70 | + Tensor(const Tensor* tensor, DimensionType type = CAFFE, bool allocMemory = true); | ||
| 71 | + | ||
| 72 | + /** deinitializer */ | ||
| 73 | + ~Tensor(); | ||
| 74 | + | ||
| 75 | +private: | ||
| 76 | + // remove all assignment operator | ||
| 77 | + Tensor(const Tensor& tensor) = delete; | ||
| 78 | + Tensor(const Tensor&& tensor) = delete; | ||
| 79 | + Tensor& operator=(const Tensor&) = delete; | ||
| 80 | + Tensor& operator=(const Tensor&&) = delete; | ||
| 81 | + | ||
| 82 | +public: | ||
| 83 | + /** | ||
| 84 | + * @brief create tensor with shape, data type and dimension type. | ||
| 85 | + * @param shape tensor shape. | ||
| 86 | + * @param type data type. | ||
| 87 | + * @param dimType dimension type. | ||
| 88 | + * @return created tensor. | ||
| 89 | + * @warning memory for data won't be acquired. call backend's onAcquireBuffer to get memory ready. | ||
| 90 | + */ | ||
| 91 | + static Tensor* createDevice(const std::vector<int>& shape, halide_type_t type, DimensionType dimType = TENSORFLOW); | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + * @brief create tensor with shape and dimension type. data type is represented by `T`. | ||
| 95 | + * @param shape tensor shape. | ||
| 96 | + * @param dimType dimension type. | ||
| 97 | + * @return created tensor. | ||
| 98 | + * @warning memory for data won't be acquired. call backend's onAcquireBuffer to get memory ready. | ||
| 99 | + */ | ||
| 100 | + template <typename T> | ||
| 101 | + static Tensor* createDevice(const std::vector<int>& shape, DimensionType dimType = TENSORFLOW) { | ||
| 102 | + return createDevice(shape, halide_type_of<T>(), dimType); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * @brief create tensor with shape, data type, data and dimension type. | ||
| 107 | + * @param shape tensor shape. | ||
| 108 | + * @param type data type. | ||
| 109 | + * @param data data to save. | ||
| 110 | + * @param dimType dimension type. | ||
| 111 | + * @return created tensor. | ||
| 112 | + */ | ||
| 113 | + static Tensor* create(const std::vector<int>& shape, halide_type_t type, void* data = NULL, | ||
| 114 | + DimensionType dimType = TENSORFLOW); | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * @brief create tensor with shape, data and dimension type. data type is represented by `T`. | ||
| 118 | + * @param shape tensor shape. | ||
| 119 | + * @param data data to save. | ||
| 120 | + * @param dimType dimension type. | ||
| 121 | + * @return created tensor. | ||
| 122 | + */ | ||
| 123 | + template <typename T> | ||
| 124 | + static Tensor* create(const std::vector<int>& shape, void* data = NULL, DimensionType dimType = TENSORFLOW) { | ||
| 125 | + return create(shape, halide_type_of<T>(), data, dimType); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | +public: | ||
| 129 | + /** | ||
| 130 | + * @brief for DEVICE tensor, copy data from given host tensor. | ||
| 131 | + * @param hostTensor host tensor, the data provider. | ||
| 132 | + * @return true for DEVICE tensor, and false for HOST tensor. | ||
| 133 | + */ | ||
| 134 | + bool copyFromHostTensor(const Tensor* hostTensor); | ||
| 135 | + | ||
| 136 | + /** | ||
| 137 | + * @brief for DEVICE tensor, copy data to given host tensor. | ||
| 138 | + * @param hostTensor host tensor, the data consumer. | ||
| 139 | + * @return true for DEVICE tensor, and false for HOST tensor. | ||
| 140 | + */ | ||
| 141 | + bool copyToHostTensor(Tensor* hostTensor) const; | ||
| 142 | + | ||
| 143 | + /** | ||
| 144 | + * @brief create HOST tensor from DEVICE tensor, with or without data copying. | ||
| 145 | + * @param deviceTensor given device tensor. | ||
| 146 | + * @param copyData copy data or not. | ||
| 147 | + * @return created host tensor. | ||
| 148 | + */ | ||
| 149 | + static Tensor* createHostTensorFromDevice(const Tensor* deviceTensor, bool copyData = true); | ||
| 150 | + | ||
| 151 | +public: | ||
| 152 | + const halide_buffer_t& buffer() const { | ||
| 153 | + return mBuffer; | ||
| 154 | + } | ||
| 155 | + halide_buffer_t& buffer() { | ||
| 156 | + return mBuffer; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + /** | ||
| 160 | + * @brief get dimension type. | ||
| 161 | + * @return dimension type. | ||
| 162 | + */ | ||
| 163 | + DimensionType getDimensionType() const; | ||
| 164 | + | ||
| 165 | + /** | ||
| 166 | + * @brief handle data type. used when data type code is halide_type_handle. | ||
| 167 | + * @return handle data type. | ||
| 168 | + */ | ||
| 169 | + HandleDataType getHandleDataType() const; | ||
| 170 | + | ||
| 171 | + /** | ||
| 172 | + * @brief set data type. | ||
| 173 | + * @param type data type defined in 'Type_generated.h'. | ||
| 174 | + */ | ||
| 175 | + void setType(int type); | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * @brief get data type. | ||
| 179 | + * @return data type. | ||
| 180 | + */ | ||
| 181 | + inline halide_type_t getType() const { | ||
| 182 | + return mBuffer.type; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + /** | ||
| 186 | + * @brief visit host memory, data type is represented by `T`. | ||
| 187 | + * @return data point in `T` type. | ||
| 188 | + */ | ||
| 189 | + template <typename T> | ||
| 190 | + T* host() const { | ||
| 191 | + return (T*)mBuffer.host; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + /** | ||
| 195 | + * @brief visit device memory. | ||
| 196 | + * @return device data ID. what the ID means varies between backends. | ||
| 197 | + */ | ||
| 198 | + uint64_t deviceId() const { | ||
| 199 | + return mBuffer.device; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | +public: | ||
| 203 | + int dimensions() const { | ||
| 204 | + return mBuffer.dimensions; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + /** | ||
| 208 | + * @brief get all dimensions' extent. | ||
| 209 | + * @return dimensions' extent. | ||
| 210 | + */ | ||
| 211 | + std::vector<int> shape() const; | ||
| 212 | + | ||
| 213 | + /** | ||
| 214 | + * @brief calculate number of bytes needed to store data taking reordering flag into account. | ||
| 215 | + * @return bytes needed to store data | ||
| 216 | + */ | ||
| 217 | + int size() const; | ||
| 218 | + | ||
| 219 | + /** | ||
| 220 | + * @brief calculate number of elements needed to store data taking reordering flag into account. | ||
| 221 | + * @return elements needed to store data | ||
| 222 | + */ | ||
| 223 | + inline int elementSize() const { | ||
| 224 | + return size() / mBuffer.type.bytes(); | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | +public: | ||
| 228 | + inline int width() const { | ||
| 229 | + if (getDimensionType() == TENSORFLOW) { | ||
| 230 | + return mBuffer.dim[2].extent; | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + return mBuffer.dim[3].extent; | ||
| 234 | + } | ||
| 235 | + inline int height() const { | ||
| 236 | + if (getDimensionType() == TENSORFLOW) { | ||
| 237 | + return mBuffer.dim[1].extent; | ||
| 238 | + } | ||
| 239 | + return mBuffer.dim[2].extent; | ||
| 240 | + } | ||
| 241 | + inline int channel() const { | ||
| 242 | + if (getDimensionType() == TENSORFLOW) { | ||
| 243 | + return mBuffer.dim[3].extent; | ||
| 244 | + } | ||
| 245 | + return mBuffer.dim[1].extent; | ||
| 246 | + } | ||
| 247 | + inline int batch() const { | ||
| 248 | + return mBuffer.dim[0].extent; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + // visit dimension's extent & stride | ||
| 252 | + inline int stride(int index) const { | ||
| 253 | + return mBuffer.dim[index].stride; | ||
| 254 | + } | ||
| 255 | + inline int length(int index) const { | ||
| 256 | + return mBuffer.dim[index].extent; | ||
| 257 | + } | ||
| 258 | + inline void setStride(int index, int stride) { | ||
| 259 | + mBuffer.dim[index].stride = stride; | ||
| 260 | + } | ||
| 261 | + inline void setLength(int index, int length) { | ||
| 262 | + mBuffer.dim[index].extent = length; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | +public: | ||
| 266 | + /** | ||
| 267 | + * @brief print tensor data. for DEBUG use only. | ||
| 268 | + */ | ||
| 269 | + void print() const; | ||
| 270 | + | ||
| 271 | + /** | ||
| 272 | + *@brief print tensor shape | ||
| 273 | + */ | ||
| 274 | + void printShape() const; | ||
| 275 | + | ||
| 276 | +public: | ||
| 277 | + /** | ||
| 278 | + * @brief map/umap GPU Tensor, to get host ptr | ||
| 279 | + */ | ||
| 280 | + void* map(MapType mtype, DimensionType dtype); | ||
| 281 | + void unmap(MapType mtype, DimensionType dtype, void* mapPtr); | ||
| 282 | + | ||
| 283 | +private: | ||
| 284 | + halide_buffer_t mBuffer; | ||
| 285 | + struct InsideDescribe* mDescribe; | ||
| 286 | + | ||
| 287 | +private: | ||
| 288 | + friend class TensorUtils; | ||
| 289 | +}; | ||
| 290 | +} // namespace MNN | ||
| 291 | + | ||
| 292 | +#endif /* Tensor_hpp */ |
| 1 | +// | ||
| 2 | +// Executor.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2019/07/25. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | +#ifndef Executor_hpp | ||
| 9 | +#define Executor_hpp | ||
| 10 | +#include <MNN/ErrorCode.hpp> | ||
| 11 | +#include <MNN/expr/Expr.hpp> | ||
| 12 | +#include <MNN/Tensor.hpp> | ||
| 13 | +#include <MNN/Interpreter.hpp> | ||
| 14 | +#include <vector> | ||
| 15 | +#include <mutex> | ||
| 16 | +#include <set> | ||
| 17 | +#include <MNN/MNNForwardType.h> | ||
| 18 | +namespace MNN { | ||
| 19 | +class Backend; | ||
| 20 | +class Execution; | ||
| 21 | +class Runtime; | ||
| 22 | +struct Op; | ||
| 23 | +namespace Express { | ||
| 24 | +class MNN_PUBLIC Executor { | ||
| 25 | +public: | ||
| 26 | + class ComputeCache; | ||
| 27 | + struct Unit; | ||
| 28 | + static void setShapeDirty(ComputeCache* cache); | ||
| 29 | + static void setContentDirty(ComputeCache* cache); | ||
| 30 | + static Tensor* getOutput(ComputeCache* cache, int offset); | ||
| 31 | + static void* mapOutput(ComputeCache* cache, int offset, Tensor* dest); | ||
| 32 | + struct Requirement { | ||
| 33 | + std::vector<bool> contentNeedContent; | ||
| 34 | + std::vector<bool> shapeNeedContent; | ||
| 35 | + }; | ||
| 36 | + ~Executor(); | ||
| 37 | + Requirement getRequirement(Expr* expr) const; | ||
| 38 | + ErrorCode computeInfo(Expr* expr); | ||
| 39 | + void makeCache(const std::vector<EXPRP>& expr, bool forceCPU = false); | ||
| 40 | + ErrorCode runCache(std::shared_ptr<ComputeCache> cache); | ||
| 41 | + void setGlobalExecutorConfig(MNNForwardType type, const BackendConfig& config, int numberThread); | ||
| 42 | + enum GCFlag { | ||
| 43 | + FULL, | ||
| 44 | + PART | ||
| 45 | + }; | ||
| 46 | + void gc(GCFlag flag = FULL); | ||
| 47 | + static std::shared_ptr<Executor> getGlobalExecutor(); | ||
| 48 | + | ||
| 49 | + static std::shared_ptr<Executor> newExecutor(MNNForwardType type, | ||
| 50 | + const BackendConfig& config, | ||
| 51 | + int numberThread); | ||
| 52 | + void resetProfile(); | ||
| 53 | + void dumpProfile(); | ||
| 54 | + void addOpCostTime(int op, float costTime); | ||
| 55 | + void addOpCostTime(const std::string& type, float costTime); | ||
| 56 | + void addOpFlops(const std::string& type, float flops); | ||
| 57 | + class Profiler; | ||
| 58 | + static RuntimeInfo getRuntime(); | ||
| 59 | + | ||
| 60 | + struct Cache; | ||
| 61 | + class RuntimeManager { | ||
| 62 | + public: | ||
| 63 | + RuntimeManager(std::vector<ScheduleConfig> &configs); | ||
| 64 | + ~RuntimeManager() {}; | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * @param configs: schedule configs. | ||
| 68 | + * @param cacheName: full path for cache file. Note: should choose location for reading and writing. | ||
| 69 | + */ | ||
| 70 | + static RuntimeManager* createRuntimeManager(std::vector<ScheduleConfig> &configs); | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * @brief set cache file. when file not exist -- create it, when file exist -- load it. | ||
| 74 | + * When should use : When choose GPU backend or use AUTO backend. | ||
| 75 | + * Calling Position: calling after createRuntimeManager. | ||
| 76 | + */ | ||
| 77 | + void setCache(std::string cacheName); | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * @brief update cache file | ||
| 81 | + * When should use : Together with setCache API. calling for first inference and when input shape is changed. | ||
| 82 | + * Calling Position : calling after inference done. | ||
| 83 | + */ | ||
| 84 | + void updateCache(); | ||
| 85 | + std::vector<bool> isBackendSupport(const std::vector<MNNForwardType> type); | ||
| 86 | + RuntimeInfo getRuntimeInfo() { | ||
| 87 | + return mRuntime; | ||
| 88 | + } | ||
| 89 | + private: | ||
| 90 | + RuntimeInfo mRuntime; | ||
| 91 | + std::shared_ptr<Runtime> mInfo; | ||
| 92 | + std::shared_ptr<Cache> mCache; | ||
| 93 | + | ||
| 94 | + }; | ||
| 95 | + | ||
| 96 | + | ||
| 97 | +private: | ||
| 98 | + void _makeCache(const std::vector<EXPRP>& outputs, bool forceCPU); | ||
| 99 | + void _create(const std::vector<EXPRP>& outputs, std::set<std::shared_ptr<Executor::ComputeCache>>&& inputCaches, std::set<std::shared_ptr<Expr::Inside>>&& inputNode, bool forceCPU); | ||
| 100 | + | ||
| 101 | + void _visit(EXPRP expr, std::set<std::shared_ptr<Executor::ComputeCache>>& inputCaches, std::set<std::shared_ptr<Expr::Inside>>& inputNode); | ||
| 102 | + | ||
| 103 | + Executor(std::shared_ptr<Runtime> backend, MNNForwardType type); | ||
| 104 | + std::pair<std::shared_ptr<Runtime>, MNNForwardType> mRuntime; | ||
| 105 | + std::pair<std::shared_ptr<Runtime>, MNNForwardType> mBackupRuntime; | ||
| 106 | + std::mutex mMutex; | ||
| 107 | + std::shared_ptr<Profiler> mProfiler; | ||
| 108 | +}; | ||
| 109 | +} // namespace Express | ||
| 110 | +} // namespace MNN | ||
| 111 | +#endif |
| 1 | +// | ||
| 2 | +// ExecutorScope.hpp | ||
| 3 | +// MNN | ||
| 4 | +// | ||
| 5 | +// Created by MNN on 2020/10/26. | ||
| 6 | +// Copyright © 2018, Alibaba Group Holding Limited | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef MNN_EXPR_EXECUTOR_SCOPE_HPP_ | ||
| 10 | +#define MNN_EXPR_EXECUTOR_SCOPE_HPP_ | ||
| 11 | + | ||
| 12 | +#include <MNN/expr/Executor.hpp> | ||
| 13 | + | ||
| 14 | +namespace MNN { | ||
| 15 | +namespace Express { | ||
| 16 | + | ||
| 17 | +struct MNN_PUBLIC ExecutorScope final { | ||
| 18 | +public: | ||
| 19 | + ExecutorScope() = delete; | ||
| 20 | + explicit ExecutorScope(const ExecutorScope&) = delete; | ||
| 21 | + explicit ExecutorScope(const std::shared_ptr<Executor>& current); | ||
| 22 | + | ||
| 23 | + explicit ExecutorScope(const std::string& scope_name, | ||
| 24 | + const std::shared_ptr<Executor>& current); | ||
| 25 | + | ||
| 26 | + virtual ~ExecutorScope(); | ||
| 27 | + | ||
| 28 | + static const std::shared_ptr<Executor> Current(); | ||
| 29 | +}; | ||
| 30 | + | ||
| 31 | +} // namespace MNN | ||
| 32 | +} // namespace Express | ||
| 33 | +#endif // MNN_EXPR_EXECUTOR_SCOPE_HPP_ |
-
请 注册 或 登录 后发表评论