From e0351dd01ea370bc5c0f8e46ae5a4f5d9232bc4c Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:56:32 +0900 Subject: [PATCH 1/1] Initialize Tizen 2.3 --- CMakeLists.txt | 80 ++ LICENSE.APLv2 | 202 +++++ LICENSE.Flora | 206 +++++ NOTICE | 8 + inc/FUixVision.h | 64 ++ inc/FUixVisionFaceBuffer.h | 119 +++ inc/FUixVisionFaceComponentsPosition.h | 207 +++++ inc/FUixVisionFaceDetector.h | 422 ++++++++++ inc/FUixVisionFaceRecognitionInfo.h | 137 ++++ inc/FUixVisionFaceRecognizer.h | 556 +++++++++++++ inc/FUixVisionFaceTypes.h | 198 +++++ osp-face.manifest | 5 + osp-face.pc.in | 14 + packaging/osp-face.spec | 89 ++ src/FUixVisionFaceBuffer.cpp | 74 ++ src/FUixVisionFaceComponentsPosition.cpp | 188 +++++ src/FUixVisionFaceDetector.cpp | 393 +++++++++ src/FUixVisionFaceRecognitionInfo.cpp | 91 +++ src/FUixVisionFaceRecognizer.cpp | 623 ++++++++++++++ src/FUixVision_FaceDetectorImpl.cpp | 761 ++++++++++++++++++ src/FUixVision_FaceDetectorImpl.h | 290 +++++++ src/FUixVision_FaceRecognizerImpl.cpp | 1295 ++++++++++++++++++++++++++++++ src/FUixVision_FaceRecognizerImpl.h | 363 +++++++++ src/FUixVision_FaceUtil.cpp | 144 ++++ src/FUixVision_FaceUtil.h | 119 +++ src/caBasicDef.h | 233 ++++++ src/caBasicDef_ENUM.h | 198 +++++ src/caFaceAPP_interface.h | 75 ++ 28 files changed, 7154 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 LICENSE.Flora create mode 100644 NOTICE create mode 100755 inc/FUixVision.h create mode 100755 inc/FUixVisionFaceBuffer.h create mode 100755 inc/FUixVisionFaceComponentsPosition.h create mode 100755 inc/FUixVisionFaceDetector.h create mode 100755 inc/FUixVisionFaceRecognitionInfo.h create mode 100755 inc/FUixVisionFaceRecognizer.h create mode 100755 inc/FUixVisionFaceTypes.h create mode 100644 osp-face.manifest create mode 100755 osp-face.pc.in create mode 100644 packaging/osp-face.spec create mode 100644 src/FUixVisionFaceBuffer.cpp create mode 100644 src/FUixVisionFaceComponentsPosition.cpp create mode 100644 src/FUixVisionFaceDetector.cpp create mode 100644 src/FUixVisionFaceRecognitionInfo.cpp create mode 100644 src/FUixVisionFaceRecognizer.cpp create mode 100644 src/FUixVision_FaceDetectorImpl.cpp create mode 100644 src/FUixVision_FaceDetectorImpl.h create mode 100644 src/FUixVision_FaceRecognizerImpl.cpp create mode 100644 src/FUixVision_FaceRecognizerImpl.h create mode 100644 src/FUixVision_FaceUtil.cpp create mode 100644 src/FUixVision_FaceUtil.h create mode 100644 src/caBasicDef.h create mode 100644 src/caBasicDef_ENUM.h create mode 100644 src/caFaceAPP_interface.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2d10650 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,80 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET (this_target osp-face) + +SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output) + +INCLUDE_DIRECTORIES( + inc + src + /usr/include/osp + /usr/include/uix + /usr/include/osp/base + ) + +SET (${this_target}_SOURCE_FILES + src/FUixVisionFaceBuffer.cpp + src/FUixVisionFaceComponentsPosition.cpp + src/FUixVisionFaceDetector.cpp + src/FUixVision_FaceDetectorImpl.cpp + src/FUixVisionFaceRecognitionInfo.cpp + src/FUixVisionFaceRecognizer.cpp + src/FUixVision_FaceRecognizerImpl.cpp + src/FUixVision_FaceUtil.cpp + ) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" ) + +## SET C COMPILER FLAGS +SET(CMAKE_C_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") + +## SET CPP COMPILER FLAGS +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") + +## Create Library +ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES}) + +## SET DEPENDENCY FLAGS +ADD_DEPENDENCIES(${this_target} osp-appfw) +ADD_DEPENDENCIES(${this_target} osp-uifw) +ADD_DEPENDENCIES(${this_target} face-engine) + +## SET LINKER FLAGS +SET(CMAKE_SHARED_LINKER_FLAGS -Wl,--no-undefined) + +TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib/osp -losp-appfw" ) +TARGET_LINK_LIBRARIES(${this_target} "-losp-uifw" ) +TARGET_LINK_LIBRARIES(${this_target} "-lface-engine-plugin" ) + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + +ADD_CUSTOM_COMMAND(TARGET ${this_target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIBRARY_OUTPUT_PATH}/debug/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${FULLVER} + COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${FULLVER} ${LIBRARY_OUTPUT_PATH}/debug/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${MAJORVER} + COMMAND ${CMAKE_STRIP} --strip-unneeded ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} + COMMENT "strip ${this_target}" + ) + +INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION lib/osp + FILES_MATCHING PATTERN "*.so*" + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) +INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/debug/ DESTINATION lib/osp/debug + FILES_MATCHING PATTERN "*.so*" + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/inc/ DESTINATION include/osp FILES_MATCHING PATTERN "*.h") + +# pkgconfig file +CONFIGURE_FILE(${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION lib/pkgconfig) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.Flora b/LICENSE.Flora new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/LICENSE.Flora @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of +this definition, "control" means (i) the power, direct or indirect, +to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of +such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice +that is included in or attached to the work (an example is provided +in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, +or merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor +for inclusion in the Work by the copyright owner or by an individual or +Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Licensor or +its representatives, including but not limited to communication on +electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding +communication that is conspicuously marked or otherwise designated +in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work +solely as incorporated into a Tizen Certified Platform, where such +license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work solely +as incorporated into a Tizen Certified Platform to which such +Contribution(s) was submitted. If You institute patent litigation +against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that +Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. You must retain, in the Source form of any Derivative Works that + You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, + if and wherever such third-party notices normally appear. + The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum + to the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. You may add Your own + copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or + distribution of Your modifications, or for any such Derivative Works + as a whole, provided Your use, reproduction, and distribution of + the Work otherwise complies with the conditions stated in this License + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Flora License to your work + +To apply the Flora License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..25ad660 --- /dev/null +++ b/NOTICE @@ -0,0 +1,8 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. + +Several source codes may have its original copyright owner and/or +be licensed under other than Apache License, Version 2, say, Flora License, Version 1.1 +Please, see copyright and license comments section in the header of each file, +and the LICENSE.Flora file for Flora License, Version 1.1 terms and conditions. \ No newline at end of file diff --git a/inc/FUixVision.h b/inc/FUixVision.h new file mode 100755 index 0000000..1089dc9 --- /dev/null +++ b/inc/FUixVision.h @@ -0,0 +1,64 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision.h + * @brief This is the header file for the %Vision namespace. + * + * This header file contains the declarations and descriptions of the %Vision namespace. + */ + +#ifndef _FUIX_VISION_H_ +#define _FUIX_VISION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @namespace Tizen::Uix::Vision + * @brief This namespace contains classes for vision and its related functions. + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face, @b osp-vision @n + * + * The %Vision namespace provides the ability to automatically detect and trace natural objects including faces, images, and QR Codes in a still image or a video stream. @n + * For more information on the %Vision namespace features, see Face Detector and Recognizer and + * Image recognizer and feature manager and QR code recognizer and generator. + * + * The following diagram illustrates the relationships between the classes belonging to the %Vision namespace. + * @image html uix_vision_namespace_classdiagram.png + + */ + +namespace Tizen { namespace Uix { namespace Vision +{ + +} } } // Tizen::Uix::Vision + +#endif // _FUIX_VISION_H_ diff --git a/inc/FUixVisionFaceBuffer.h b/inc/FUixVisionFaceBuffer.h new file mode 100755 index 0000000..e9e641b --- /dev/null +++ b/inc/FUixVisionFaceBuffer.h @@ -0,0 +1,119 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +/** + * @file FUixVisionFaceBuffer.h + * @brief This is the header file for the %FaceBuffer class. + * + * This header file contains the declarations of the %FaceBuffer class. + */ + +#ifndef _FUIX_VISION_FACE_BUFFER_H_ +#define _FUIX_VISION_FACE_BUFFER_H_ + +#include +#include + +namespace Tizen { namespace Base +{ +class ByteBuffer; +} } + +namespace Tizen { namespace Uix { namespace Vision +{ + +/** + * @class FaceBuffer + * @brief This class encapsulates the information processed by the %FaceDetector and %FaceRecognizer classes. + * + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face @n + * + * The %FaceBuffer class encapsulates the information processed by the FaceDetector and FaceRecognizer classes. + * It contains the proper data format that can be used in the face related methods. The user can get the face buffer from the FaceDetector::PreprocessDataN() method. @n + * For more information on the %FaceBuffer class features, see Face Detector and Recognizer. + * + */ + +class _OSP_EXPORT_ FaceBuffer + : public Tizen::Base::Object +{ + +public: + /** + * This is the destructor for this class. @n + * The resources are deallocated by this method. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~FaceBuffer(void); + +// Operation + + /** + * Gets the width and the height of the face data. + * + * @since 2.0 + * + * @return The dimensions of the face data + */ + Tizen::Graphics::Dimension GetDimension(void) const; + + + /** + * Gets the buffer that contains the face data. + * + * @since 2.0 + * + * @return A pointer to the Tizen::Base::ByteBuffer instance that contains the face data + */ + const Tizen::Base::ByteBuffer* GetBuffer(void) const; + +private: + /** + * This is the default constructor for this class. + * This default constructor is intentionally declared as private so that only the platform can create an instance. + */ + FaceBuffer(void); + /** + * This constructor is intentionally declared as private so that only the platform can create an instance. + */ + FaceBuffer(const Tizen::Base::ByteBuffer& buffer, const Tizen::Graphics::Dimension& dim); + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceBuffer(const FaceBuffer& value); + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceBuffer& operator =(const FaceBuffer& value); + +private: + Tizen::Base::ByteBuffer* __pBuffer; + Tizen::Graphics::Dimension __resolution; + + friend class FaceDetector; + +}; // FaceBuffer + +} } } // Tizen::Uix::Vision + +#endif // _FUIX_VISION_FACE_BUFFER_H_ diff --git a/inc/FUixVisionFaceComponentsPosition.h b/inc/FUixVisionFaceComponentsPosition.h new file mode 100755 index 0000000..98bb887 --- /dev/null +++ b/inc/FUixVisionFaceComponentsPosition.h @@ -0,0 +1,207 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +/** + * @file FUixVisionFaceComponentsPosition.h + * @brief This is the header file for the %FaceComponentsPosition class. + * + * This header file contains the declarations of the %FaceComponentsPosition class. + */ + +#ifndef _FUIX_VISION_FACE_COMPONENTS_POSITION_H_ +#define _FUIX_VISION_FACE_COMPONENTS_POSITION_H_ + +#include +#include +#include +#include + +namespace Tizen { namespace Uix { namespace Vision +{ + +/** + * @class FaceComponentsPosition + * @brief This class encapsulates the extracted face component's information that is processed by the %FaceDetector class. + * + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face @n + * + * The %FaceComponentsPosition class encapsulates the extracted face component's information that is processed by the FaceDetector class. + * + * This class provides the following functionalities: + * - Getting/Setting the position of the face. + * - Getting/Setting the position of the eyes. + * - Getting/Setting the position of the mouth. + * + * For more information on the %FaceComponentsPosition class features, see Face Detector and Recognizer. + */ + +class _OSP_EXPORT_ FaceComponentsPosition + : public Tizen::Base::Object +{ +public: + /** + * This is the default constructor for this class. @n + * The value of all the attributes is set to @c -1 when this instance is initialized. + * + * @since 2.0 + */ + FaceComponentsPosition(void); + + /** + * Initializes this instance of %FaceComponentsPosition with the specified parameter. + * + * @since 2.0 + * + * @param[in] faceRect The face position that is obtained using the FaceDetector::DetectFacesN() method + */ + FaceComponentsPosition(const Tizen::Graphics::Rectangle& faceRect); + + /** + * Initializes this instance of %FaceComponentsPosition with the specified parameters. + * + * @since 2.0 + * + * @param[in] faceRect The face position that is obtained using the FaceDetector::DetectFacesN() method + * @param[in] leftEyePos The left eye position that is obtained using the FaceDetector::ExtractFaceComponentsN() method + * @param[in] rightEyePos The right eye position that is obtained using the FaceDetector::ExtractFaceComponentsN() method + */ + FaceComponentsPosition(const Tizen::Graphics::Rectangle& faceRect, const Tizen::Graphics::Point& leftEyePos, const Tizen::Graphics::Point& rightEyePos); + + /** + * This is the destructor for this class. @n + * The resources are deallocated by this method. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~FaceComponentsPosition(void); + + + /** + * Gets the position of the face. @n + * The value of all the attributes is set to @c -1, if their value is not set to @c -1 during the initialization. + * + * @since 2.0 + * + * @return The position of the face + */ + Tizen::Graphics::Rectangle GetFacePosition(void) const; + + /** + * Gets the position of the eyes. @n + * The value of @c leftEyePos and @c rightEyePos is set to @c -1, if they are not set to @c -1 during the initialization. + * + * @since 2.0 + * + * @param[out] leftEyePos The left eye position + * @param[out] rightEyePos The right eye position + */ + void GetEyePosition(Tizen::Graphics::Point& leftEyePos, Tizen::Graphics::Point& rightEyePos) const; + + /** + * Gets the position of the mouth. @n + * The value of all the attributes is set to @c -1, if their value is not set to @c -1 during the initialization. + * + * @since 2.0 + * + * @return The position of the mouth + */ + Tizen::Graphics::Rectangle GetMouthPosition(void) const; + + /** + * Sets the position of the face. + * + * @since 2.0 + * + * @return An error code + * @param[in] faceRect The face position that is obtained using the FaceDetector::DetectFacesN() method @n + * The values of the x and y positions of the @c faceRect parameter must be greater than or equal to @c 0 @n + * The values of the width and the height of the @c faceRect parameter must be greater than @c 0. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG The specified input parameter is invalid. + * @see FaceDetector::ExtractFaceComponentsN() + */ + result SetFacePosition(const Tizen::Graphics::Rectangle& faceRect); + + /** + * Sets the position of the eyes. + * + * @since 2.0 + * + * @return An error code + * @param[in] leftEyePos The left eye position @n + * This position is obtained using the FaceDetector::ExtractFaceComponentsN() method. + * @param[in] rightEyePos The right eye position @n + * This position is obtained using the FaceDetector::ExtractFaceComponentsN() method @n + * The right eye position must be greater than or equal to @c 0, and must be greater than @c leftEyePos. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + */ + result SetEyePosition(const Tizen::Graphics::Point& leftEyePos, const Tizen::Graphics::Point& rightEyePos); + + /** + * Sets the position of the mouth. + * + * @since 2.0 + * + * @return An error code + * @param[in] mouthRect The position of the mouth that is obtained using the FaceDetector::ExtractFaceComponentsN() method + * @exception E_SUCCESS Either of the following conditions has occurred: + * - The method is successful. + * - The values of the x and y positions of the @c mouthRect parameter must be greater than or equal to @c 0. + * - The values of the width and the height of the @c mouthRect parameter must be greater than @c 0. + * @exception E_INVALID_ARG The specified input parameter is invalid. + */ + result SetMouthPosition(const Tizen::Graphics::Rectangle& mouthRect); + + /** + * This is the copy constructor for this class. @n + * Initializes this instance of %FaceComponentsPosition with the specified parameter. @n + * Copying of objects using this copy constructor is allowed. + * + * @since 2.0 + * + * @param[in] rhs An instance of %FaceComponentsPosition to copy + */ + FaceComponentsPosition(const FaceComponentsPosition& rhs); + + /** + * Assigns the value of the specified %FaceComponentsPosition object to the current instance. @n + * Copying of objects using this copy assignment operator is allowed. + * + * @since 2.0 + * + * @param[in] rhs An instance of %FaceComponentsPosition to copy + */ + FaceComponentsPosition& operator =(const FaceComponentsPosition& rhs); + +// Member variable +private: + Tizen::Graphics::Rectangle __faceRect; + Tizen::Graphics::Point __eyeRight; + Tizen::Graphics::Point __eyeLeft; + Tizen::Graphics::Rectangle __mouthRect; + +}; // FaceComponentsPosition + +} } } // Tizen::Uix::Vision + +#endif diff --git a/inc/FUixVisionFaceDetector.h b/inc/FUixVisionFaceDetector.h new file mode 100755 index 0000000..7d31633 --- /dev/null +++ b/inc/FUixVisionFaceDetector.h @@ -0,0 +1,422 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +/** + * @file FUixVisionFaceDetector.h + * @brief This is the header file for the %FaceDetector class. + * + * This header file contains the declarations of the %FaceDetector class. + */ + +#ifndef _FUIX_VISION_FACE_DETECTOR_H_ +#define _FUIX_VISION_FACE_DETECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace Tizen { namespace Base +{ +class ByteBuffer; +} } + +namespace Tizen { namespace Base { namespace Collection +{ +class IList; +template< class Type > class IListT; +} } } + +namespace Tizen { namespace Graphics +{ +class Bitmap; +class Dimension; +class Rectangle; +} } + +namespace Tizen { namespace Uix { namespace Vision +{ +class _FaceDetectorImpl; + +/** + * @class FaceDetector + * @brief This class is used to trace faces in an image or a video. + * + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face @n + * + * The %FaceDetector class provides the ability to automatically detect and trace faces in a still image or a video stream. @n + * For more information on the %FaceDetector class features, see Face Detector and Recognizer. + * + * The following example demonstrates how to use the %FaceDetector class. + * + * @code + * #include + * #include + * #include + * #include + * #include + * + * using namespace Tizen::Base; + * using namespace Tizen::Media; + * using namespace Tizen::Graphics; + * using namespace Tizen::Io; + * using namespace Tizen::Uix::Vision; + * + * result + * MyClass::TestFaceDetect(void) + * { + * ByteBuffer* pByteBuffer = null; + * int width = 0, height = 0; + * result r = E_SUCCESS; + * + * Image* pImage = new Image(); + * r = pImage->Construct(); + * + * String path(L"test.bmp"); + * + * pByteBuffer = pImage->DecodeToBufferN(path, BITMAP_PIXEL_FORMAT_RGB565,width,height ); + * + * //Deletes the image object + * delete pImage; + * + * if (pByteBuffer) + * { + * //Detects faces + * FaceDetector faceDetect; + * r = faceDetect.Construct(); + * const Tizen::Base::Collection::IList* pFaceDetectList = faceDetect.DetectFacesFromStillImageN(*pByteBuffer, Dimension(width,height), BITMAP_PIXEL_FORMAT_RGB565); + * + * if(pFaceDetectList == null) + * { + * delete pByteBuffer; + * return GetLastResult(); + * } + * + * for(int i=0; i < pFaceDetectList->GetCount(); i++) + * { + * Tizen::Graphics::Rectangle* pRect = (Tizen::Graphics::Rectangle*)pFaceDetectList->GetAt(i); + * } + * + * delete pFaceDetectList; + * } + * + * return r; + * } + * @endcode + */ +class _OSP_EXPORT_ FaceDetector + : public Tizen::Base::Object +{ + +// Lifecycle +public: + /** + * This is the default constructor for this class. @n + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 2.0 + */ + FaceDetector(void); + + /** + * This is the destructor for this class. @n + * The resources are deallocated by this method. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~FaceDetector(void); + + +// Operation + + /** + * Initializes this instance of %FaceDetector. + * + * @since 2.0 + * + * @feature %http://tizen.org/feature/vision.face_recognition + * @return An error code + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The target device does not support the face detection feature. @b Since: @b 2.1 + * For more information, see Application Filtering. + * @remarks Before calling this method, check whether the feature is supported by Tizen::System::SystemInfo::GetValue(const Tizen::Base::String&, bool&). + */ + result Construct(void); + + /** + * Gets the range and the default value of the specified configuration property. + * + * @since 2.0 + * + * @return An error code + * @param[in] configProperty The property to query + * @param[out] min The minimum value of the property + * @param[out] max The maximum value of the property + * @param[out] steppingDelta The step size for the property @n + * The step size is the smallest increment by which the property can be changed. + * @param[out] defaultVal The default value of the property + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + */ + result GetRange(FaceDetectorConfigProperty configProperty, long& min, long& max, long& steppingDelta, long& defaultVal) const; + + /** + * Sets the value of the specified property. + * + * @since 2.0 + * + * @return An error code + * @param[in] configProperty The property to query + * @param[in] value The new value of the property + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + * @exception E_OUT_OF_RANGE The specified @c value is out of the valid range. + * @see GetRange() + */ + result SetProperty(FaceDetectorConfigProperty configProperty, long value); + + /** + * Gets the current setting for the specified configuration property. + * + * @since 2.0 + * + * @return The value of the property, @n + * else @c -1 if an exception occurs + * @param[in] configProperty The property to query + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + long GetProperty(FaceDetectorConfigProperty configProperty) const; + + /** + * Gets the list of supported pixel formats. + * + * @since 2.0 + * + * @return The list of supported pixel formats that are used in the DetectFacesFromVideoStreamN() method @n + * The format is in the form of a string. + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* GetSupportedFormatListN(void) const; + + /** + * Detects faces in a video. + * + * @since 2.0 + * + * @return The list of detected face positions, @n + * else @c null if an exception occurs @n + * Each list item has a pointer of Tizen::Graphics::Rectangle value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the video data is not clear @n + * This is the result of a normal operation. + * + * @param[in] byteBuffer The buffer that contains the video data + * @param[in] dim The width and the height of the video data @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The format of the video data @n + * It must be one of the pixel formats extracted from the GetSupportedFormatListN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IList* DetectFacesFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::PixelFormat format); + + /** + * @if OSPDEPREC + * Detects faces from a still image. + * @brief [Deprecated] + * @deprecated This method is deprecated as it may return an improper result. + * Instead of using this method, use the DetectFacesFromStillImageN(Tizen::Base::ByteBuffer &, Tizen::Graphics::Dimension &, Tizen::Graphics::BitmapPixelFormat) method. + * To optimize the memory usage and processing time, the bitmap, scales down an image by decreasing its resolution in some models, + * that in turn decreases the accuracy of the face library. Therefore, the usage of this method using Tizen::Base::ByteBuffer is encouraged. + * @since 2.0 + * + * @return The list of detected face positions, @n + * else @c null if an exception occurs @n + * Each list item has a pointer of Tizen::Graphics::Rectangle value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the image is not clear @n + * This is the result of a normal operation. + * + * @param[in] bitmap The bitmap file that contains the input image data + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks + * - The specific error code can be accessed using the GetLastResult() method. + * - BitmapPixelFormat::BITMAP_PIXEL_FORMAT_R8G8B8A8 is not applicable for this method. + * @endif + */ + Tizen::Base::Collection::IList* DetectFacesFromStillImageN(const Tizen::Graphics::Bitmap& bitmap); + + /** + * Detects faces in a still image. + * + * @since 2.0 + * + * @return The list of detected face positions, @n + * else @c null if an exception occurs @n + * Each list item has a pointer of Tizen::Graphics::Rectangle value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the image is not clear @n + * This is the result of a normal operation. + * + * @param[in] byteBuffer The buffer that contains the input image data + * @param[in] dim The width and the height of the input image @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The color format @n + * @c BITMAP_PIXEL_FORMAT_R8G8B8A8 is not applicable for this method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IList* DetectFacesFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat format); + + + /** + * Converts the input data to a proper data format that can be used in the face related methods. + * + * @since 2.0 + * + * @return The preprocessed data, @n + * else @c null if an exception occurs + * @param[in] byteBuffer The buffer that contains the input data + * @param[in] dim The width and the height of the input data @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The format of the input data @n + * It must be one of the pixel formats extracted from the GetSupportedFormatListN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + FaceBuffer* PreprocessDataN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::PixelFormat format); + + /** + * Detects faces in the preprocessed data. + * + * @since 2.0 + * + * @return The list of detected face positions, @n + * else @c null if an exception occurs + * Each list item has a pointer of Tizen::Graphics::Rectangle value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the input data is not clear @n + * This is the result of a normal operation. + * + * @param[in] preprocessedFaceBuffer The preprocessed data @n + * The @c preprocessedFaceBuffer must be obtained from the PreprocessDataN() method. + * @param[in] option The working option of the detecting faces + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The specified mode is not supported. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + * @see FaceDetectorConfigProperty() + */ + Tizen::Base::Collection::IList* DetectFacesN(const FaceBuffer& preprocessedFaceBuffer, FaceDetectionOption option = FACE_DETECTION_OPTION_FAST); + + /** + * Extracts the facial component's information. + * + * @since 2.0 + * + * @return The facial component's information, @n + * else @c null if an exception occurs + * @param[in] preprocessedFaceBuffer The preprocessed data @n + * The @c preprocessedFaceBuffer must be obtained from the PreprocessDataN() method. + * @param[in] faceRect The position of the face detected by the DetectFacesN() method @n + * The values of the x and y positions of the @c faceRect parameter must be greater than or equal to @c 0 @n + * The values of the width and the height of the @c faceRect parameter must be greater than @c 0 @n + * The position of @c faceRect must be within @c preprocessedFaceBuffer. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_SYSTEM A system error has occurred. + * @exception E_OPERATION_FAILED The method has failed to extract the facial information, but no error has been reported. @n + * This happens when the detected faces are too small, or the input data is not clear. @n + * This is the result of a normal operation. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + FaceComponentsPosition* ExtractFaceComponentsN(const FaceBuffer& preprocessedFaceBuffer, const Tizen::Graphics::Rectangle& faceRect); + + + /** + * Gets the position difference of the face. @n + * The %GetFaceMovement() method is used for tracking a face in a sequential video data. + * + * @since 2.0 + * + * @return An error code + * @param[in] prevData The buffer that contains the previous video data + * @param[in] curData The buffer that contains the current video data @n + * The size of @c prevData and @c curData must be the same @n + * The @c prevData and @c curData must be obtained from the PreprocessDataN() method. + * @param[in] prevFaceRect The region of the face inside @c prevData @n + * The values of the x and y positions of the @c prevFaceRect parameter must be greater than or equal to @c 0 @n + * The values of the width and the height of the @c prevFaceRect parameter must be greater than @c 0 @n + * The specified @c prevFaceRect must be within @c prevData. + * @param[out] xDiff The x offset that is moved from the previous to the current video data + * @param[out] yDiff The y offset that is moved from the previous to the current video data + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OPERATION_FAILED The method has failed to obtain the position difference of the specified region, but no error has been reported. @n + * In this case, @c xDiff and @c yDiff are returned with the value @c 0. @n + * This happens when the detected faces are too small, or any two video data are different even though they contain the same face. @n + * This is the result of a normal operation. + * @remarks The specific error code can be accessed using the GetLastResult() method. + * @see DetectFacesN() + */ + result GetFaceMovement(const FaceBuffer& prevData, const FaceBuffer& curData, const Tizen::Graphics::Rectangle& prevFaceRect, int& xDiff, int& yDiff); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceDetector(const FaceDetector& value); + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceDetector& operator =(const FaceDetector& value); + friend class _FaceDetectorImpl; + +//Member variables +private: + _FaceDetectorImpl* __pFaceDetectorImpl; + +}; // FaceDetector + +} } } // Tizen::Uix::Vision + +#endif // _FUIX_VISION_FACE_DETECTOR_H_ diff --git a/inc/FUixVisionFaceRecognitionInfo.h b/inc/FUixVisionFaceRecognitionInfo.h new file mode 100755 index 0000000..b6ea804 --- /dev/null +++ b/inc/FUixVisionFaceRecognitionInfo.h @@ -0,0 +1,137 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +/** + * @file FUixVisionFaceRecognitionInfo.h + * @brief This is the header file for the %FaceRecognitionInfo class. + * + * This header file contains the declarations of the %FaceRecognitionInfo class. + */ + +#ifndef _FUIX_VISION_FACE_RECOGNITION_INFO_H_ +#define _FUIX_VISION_FACE_RECOGNITION_INFO_H_ + +#include +#include +#include + +namespace Tizen { namespace Base +{ +class ByteBuffer; +} } + +namespace Tizen { namespace Uix { namespace Vision +{ +class _FaceRecognizerImpl; + +/** + * @class FaceRecognitionInfo + * @brief This class encapsulates the information class of a recognized face using the %FaceRecognizer class. + * + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face @n + * + * The %FaceRecognitionInfo class encapsulates the information of a face recognized using the FaceRecognizer class by: + * - Getting the position of the recognized face. + * - Getting the facial features of the recognized face. + * + * For more information on the %FaceRecognitionInfo class features, see Face Detector and Recognizer. + */ + +class _OSP_EXPORT_ FaceRecognitionInfo + : public Tizen::Base::Object +{ +public: + /** + * This is the default constructor for this class. @n + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 2.0 + */ + FaceRecognitionInfo(void); + + /** + * This is the destructor for this class. @n + * The resources are deallocated by this method. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~FaceRecognitionInfo(void); + +// Operation + /** + * Initializes this instance of %FaceRecognitionInfo with the specified parameter. + * + * @since 2.0 + * + * @return An error code + * @param[in] faceFeatures The facial features obtained from the extract methods in the FaceRecognizer class + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @see FaceRecognizer::ExtractFaceInfoFromVideoStreamN() + * @see FaceRecognizer::ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer&, const Tizen::Graphics::Dimension&, Tizen::Graphics::BitmapPixelFormat) + */ + result Construct(const Tizen::Base::ByteBuffer& faceFeatures); + + /** + * Gets the position of the recognized face. + * + * @since 2.0 + * + * @return The position of the recognized face + */ + Tizen::Graphics::Rectangle GetFacePosition(void) const; + + + /** + * Gets the facial features of the recognized face. + * + * @since 2.0 + * + * @return The facial features of the recognized face + */ + const Tizen::Base::ByteBuffer* GetFaceFeatures(void) const; + + +private: + /* + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceRecognitionInfo(const FaceRecognitionInfo& value); + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceRecognitionInfo& operator =(const FaceRecognitionInfo& value); + + void SetFacePosition(int x, int y, int width, int height); + +private: + Tizen::Graphics::Rectangle __faceRect; + Tizen::Base::ByteBuffer* __pfaceFeatures; + + friend class _FaceRecognizerImpl; + +}; // FaceRecognitionInfo + +} } } // Tizen::Uix::Vision + +#endif diff --git a/inc/FUixVisionFaceRecognizer.h b/inc/FUixVisionFaceRecognizer.h new file mode 100755 index 0000000..cc1a5f6 --- /dev/null +++ b/inc/FUixVisionFaceRecognizer.h @@ -0,0 +1,556 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +/** + * @file FUixVisionFaceRecognizer.h + * @brief This is the header file for the %FaceRecognizer class. + * + * This header file contains the declarations of the %FaceRecognizer class. + */ + +#ifndef _FUIX_VISION_FACE_RECOGNIZER_H_ +#define _FUIX_VISION_FACE_RECOGNIZER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Tizen { namespace Base +{ +class ByteBuffer; +} } + +namespace Tizen { namespace Base { namespace Collection +{ +class IList; +template< class Type > class IListT; +template< class KeyType, class ValueType > class IMapT; +} } } + +namespace Tizen { namespace Graphics +{ +class Bitmap; +class Dimension; +class Rectangle; +} } + +namespace Tizen { namespace Uix { namespace Vision +{ +class _FaceRecognizerImpl; + +/** + * @class FaceRecognizer + * @brief This class provides methods to recognize a face in an image or a video. + * + * @since 2.0 + * + * @remarks @b Header @b %file: @b \#include @b @n + * @b Library: @b osp-face @n + * + * The %FaceRecognizer class provides the ability to automatically recognize faces in still images or video streams. @n + * For more information on the %FaceRecognizer class features, see Face Detector and Recognizer. + * + * The following example demonstrates how to use the %FaceRecognizer class. + * + * @code + * #include + * #include + * #include + * #include + * #include + * + * using namespace Tizen::Base; + * using namespace Tizen::Media; + * using namespace Tizen::Graphics; + * using namespace Tizen::Io; + * using namespace Tizen::Uix::Vision; + * + * result + * MyClass::TestFaceRecognize(void) + * { + * ByteBuffer* pByteBuffer1 = null, * pByteBuffer2 = null; + * int width1 = 0, height1 = 0, width2 = 0, height2 = 0; + * result r; + * + * Image * pImage = new Image(); + * r = pImage->Construct(); + * + * String path1(L"test1.bmp"); + * String path2(L"test2.bmp"); + * + * pByteBuffer1 = pImage->DecodeToBufferN(path1, BITMAP_PIXEL_FORMAT_RGB565,width1,height1 ); + * pByteBuffer2 = pImage->DecodeToBufferN(path2, BITMAP_PIXEL_FORMAT_RGB565,width2,height2 ); + * + * //Deletes the image object + * delete pImage; + * + * if (pByteBuffer1 && pByteBuffer2) + * { + * FaceRecognizer faceRecog; + * r = faceRecog.Construct(); + * const Tizen::Base::Collection::IList* pFaceDetectList1 = faceRecog.ExtractFaceInfoFromStillImageN(*pByteBuffer1, Dimension(width1,height1), BITMAP_PIXEL_FORMAT_RGB565); + * const Tizen::Base::Collection::IList* pFaceDetectList2 = faceRecog.ExtractFaceInfoFromStillImageN(*pByteBuffer2, Dimension(width2,height2), BITMAP_PIXEL_FORMAT_RGB565); + * + * if(pFaceDetectList1 == null || pFaceDetectList2 == null) + * { + * delete pByteBuffer1; + * delete pByteBuffer2; + * return GetLastResult(); + * } + * + * FaceRecognitionInfo* pFInfo1 = null, *pFInfo2 = null; + * for(int i=0; i < pFaceDetectList1->GetCount(); i++) + * { + * pFInfo1 = (Tizen::Uix::FaceRecognitionInfo*)pFaceDetectList1->GetAt(i); + * for(int j=0; j < pFaceDetectList2->GetCount(); j++) + * { + * pFInfo2 = (Tizen::Uix::FaceRecognitionInfo*)pFaceDetectList2->GetAt(j); + * if(faceRecog.IsMatching(*pFInfo1, *pFInfo2)) + * { + * Tizen::Graphics::Rectangle rect1 = (Tizen::Graphics::Rectangle)pFInfo1->GetFacePosition(); + * } + * } + * } + * + * delete pByteBuffer1; + * delete pByteBuffer2; + * } + * return r; + * } + * @endcode + */ +class _OSP_EXPORT_ FaceRecognizer + : public Tizen::Base::Object +{ + +// Lifecycle +public: + /** + * This is the default constructor for this class. @n + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 2.0 + */ + FaceRecognizer(void); + + /** + * This is the destructor for this class. @n + * The resources are deallocated by this method. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~FaceRecognizer(void); + + +// Operation + + /** + * Initializes an instance of %FaceRecognizer. + * + * @since 2.0 + * + * @feature %http://tizen.org/feature/vision.face_recognition + * @return An error code + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The target device does not support the face detection feature. @b Since: @b 2.1 + * For more information, see Application Filtering. + * @remarks Before calling this method, check whether the feature is supported by Tizen::System::SystemInfo::GetValue(const Tizen::Base::String&, bool&). + */ + result Construct(void); + + /** + * Gets the range and the default value of the specified configuration property. + * + * @since 2.0 + * + * @return An error code + * @param[in] configProperty The property to query + * @param[out] min The minimum value of the property + * @param[out] max The maximum value of the property + * @param[out] steppingDelta The step size of the property @n + * The step size is the smallest increment by which the property can be changed. + * @param[out] defaultVal The default value of the property + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + */ + result GetRange(FaceRecognizerConfigProperty configProperty, long& min, long& max, long& steppingDelta, long& defaultVal) const; + + /** + * Sets the value of the specified property. + * + * @since 2.0 + * + * @return An error code + * @param[in] configProperty The property to query + * @param[in] value The new value of the property + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + * @exception E_OUT_OF_RANGE The specified @c value is out of the valid range. + * @see GetRange() + */ + result SetProperty(FaceRecognizerConfigProperty configProperty, long value); + + /** + * Gets the current setting of the specified configuration property. + * + * @since 2.0 + * + * @return The value of the property, @n + * else @c -1 if an exception occurs + * @param[in] configProperty The property to query + * @exception E_SUCCESS The method is successful. + * @exception E_UNSUPPORTED_OPERATION The device does not support the specified configuration property. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + long GetProperty(FaceRecognizerConfigProperty configProperty) const; + + /** + * Gets the list of supported pixel formats. + * + * @since 2.0 + * + * @return The list of supported pixel formats that are used in the ExtractFaceInfoFromVideoStreamN() method @n + * The format is in the form of a string. + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* GetSupportedFormatListN(void) const; + + /** + * Extracts the facial template that represents the face, from the video. + * + * @since 2.0 + * + * @return The list of FaceRecognitionInfo instances that contain the extracted facial features, @n + * else @c null if an exception occurs @n + * Each list item has a pointer to the %FaceRecognitionInfo value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the video data is not clear @n + * This is the result of a normal operation. + * + * @param[in] byteBuffer A pointer to the buffer that contains the video data + * @param[in] dim The width and the height of the video data @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The format of the video data @n + * It must be one of the pixel formats extracted from the GetSupportedFormatListN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG Either of the following conditions has occurred: + * - A specified input parameter is invalid. + * - The specified @c format is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IList* ExtractFaceInfoFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::PixelFormat format); + + /** + * @if OSPDEPREC + * Extracts the facial template that represents the face, from the still image. + * + * @brief [Deprecated] + * @deprecated This method is deprecated as it may return an improper result. + * Instead of using this method, use ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat format). + * To optimize the memory usage and processing time, the bitmap, scales down an image + * by decreasing its resolution in some models, that in turn decreases the accuracy of the face library. + * Therefore, the usage of this method using Tizen::Base::ByteBuffer is encouraged. + * @since 2.0 + * + * @return The list of FaceRecognitionInfo instances that contain the extracted facial features, @n + * else @c null if an exception occurs @n + * Each list item has a pointer to the %FaceRecognitionInfo value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when they are too small, or the image is not clear @n + * This is the result of a normal operation. + * @param[in] bitmap The bitmap file that contains the input image data + * @exception E_SUCCESS The method is successful. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks + * - The specific error code can be accessed using the GetLastResult() method. + * - BitmapPixelFormat::BITMAP_PIXEL_FORMAT_R8G8B8A8 is not applicable for this method. + * @endif + */ + Tizen::Base::Collection::IList* ExtractFaceInfoFromStillImageN(const Tizen::Graphics::Bitmap& bitmap); + + /** + * Extracts the facial template that represents the face, from the still image. + * + * @since 2.0 + * + * @return The list of FaceRecognitionInfo instances that contain the extracted facial features, @n + * else @c null if an exception occurs @n + * Each list item has a pointer to the %FaceRecognitionInfo value @n + * An empty list is returned, if no faces are detected and there is no error @n + * Faces are not detected when the faces are too small, or the image is not clear @n + * This is the result of a normal operation. + * @param[in] byteBuffer The buffer that contains the input image data + * @param[in] dim The width and the height of the input image @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The color format @n + * @c BITMAP_PIXEL_FORMAT_R8G8B8A8 is not applicable for this method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_FAILURE A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IList* ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat format); + + /** + * Checks if the two specified faces match. + * + * @since 2.0 + * + * @return @c true if the two faces match, @n + * else @c false + * @param[in] face1 The face information of the first face + * @param[in] face2 The face information of the second face + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG Either of the following conditions has occurred: + * - A specified input parameter is invalid. + * - The specified FaceRecognitionInfo is not constructed. + * @exception E_FAILURE A system error has occurred. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + bool IsMatching(const FaceRecognitionInfo& face1, const FaceRecognitionInfo& face2); + + /** + * Gets the similarity between the two specified faces. + * + * @since 2.0 + * + * @return The degree of similarity in percentage @n + * else @c -1 if an exception occurs @n + * This value ranges from @c 0 to @c 100, where @c 100 means the faces are the same, and @c 0 means there is no similarity between the two faces. + * + * @param[in] face1 The face information of the first face + * @param[in] face2 The face information of the second face + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG Either of the following conditions has occurred: + * - A specified input parameter is invalid. + * - The specified FaceRecognitionInfo is not constructed. + * @exception E_FAILURE A system error has occurred. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + int MeasureSimilarity(const FaceRecognitionInfo& face1, const FaceRecognitionInfo& face2); + + /** + * Extracts the facial template that represents the face. + * + * @since 2.0 + * + * @return The facial features of the recognized face, @n + * else @c null if an exception occurs + * @param[in] preprocessedFaceBuffer The preprocessed data + * @param[in] faceComponentPos The facial information that is obtained from the FaceDetector::ExtractFaceComponentsN() method @n + * The specified facial information must contain the eye position @n + * The position of the eyes must be greater than or equal to @c 0 @n + * The position of the eyes must be within @c preprocessedFaceBuffer @n + * If there are wrong values in the specified facial information, the result cannot be guaranteed even if it returns @c E_SUCCESS @n + * Therefore, the value of the facial information should not be changed after it is obtained from the %FaceDetector::ExtractFaceComponentsN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @exception E_OPERATION_FAILED The method has failed to extract the facial information, but no error has been reported. @n + * This happens when the detected faces are too small, or the input data is not clear. @n + * This is the result of a normal operation. + * @remarks The specific error code can be accessed using the GetLastResult() method. + * @see FaceDetector::PreprocessDataN() + * @see FaceDetector::ExtractFaceComponentsN() + */ + Tizen::Base::ByteBuffer* ExtractFeatureN(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos); + + /** + * Gets the eye status. + * + * @since 2.0 + * + * @return The eye status, @n + * else @c EYE_STATE_NONE if an exception occurs + * @param[in] preprocessedFaceBuffer The preprocessed data + * @param[in] faceComponentPos The facial information that is obtained from the FaceDetector::ExtractFaceComponentsN() method @n + * The specified facial information must contain the eye position @n + * The position of the eyes must be greater than or equal to @c 0 @n + * The position of the eyes must be within @c preprocessedFaceBuffer @n + * If there are wrong values in the specified facial information, the result cannot be guaranteed even if it returns @c E_SUCCESS @n + * Therefore, the value of the facial information should not be changed after it is obtained from the %FaceDetector::ExtractFaceComponentsN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @exception E_OPERATION_FAILED The method has failed to detect the eye state, but no error has been reported. @n + * This happens when the detected faces are too small, or the input data is not clear. @n + * This is the result of a normal operation. + * @remarks The specific error code can be accessed using the GetLastResult() method. + * @see FaceDetector::PreprocessDataN() + */ + EyeState GetEyeState(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos); + + /** + * Recognizes the facial expression. + * + * @since 2.0 + * + * @return The facial expression, @n + * else @c FACIAL_EXPRESSION_NONE if an exception occurs + * @param[in] preprocessedFaceBuffer The preprocessed data + * @param[in] faceComponentPos The facial information that is obtained from the FaceDetector::ExtractFaceComponentsN() method @n + * The specified facial information must contain the eye position @n + * The position of the eyes must be greater than or equal to @c 0 @n + * The position of the eyes must be within @c preprocessedFaceBuffer @n + * If there are wrong values in the specified facial information, the result cannot be guaranteed even if it returns @c E_SUCCESS @n + * Therefore, the value of the facial information should not be changed after it is obtained from the %FaceDetector::ExtractFaceComponentsN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @exception E_OPERATION_FAILED The method has failed to extract the facial expression, but no error has been reported. @n + * This happens when the detected faces are too small, or the input data is not clear. @n + * This is the result of a normal operation. + * @remarks The specific error code can be accessed using the GetLastResult() method. + * @see FaceDetector::PreprocessDataN() + */ + FacialExpression RecognizeExpression(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos); + + /** + * Detects the eye states from the video. + * + * @since 2.0 + * + * @return The list of eye states, @n + * else @c null if an exception occurs @n + * Each list item has an eyeState value @n + * An empty list is returned, if no eye states are detected and there is no error @n + * Eye states are not detected when the faces are too small, or the video data is not clear @n + * This is the result of a normal operation. + * @param[in] byteBuffer The buffer that contains the video data + * @param[in] dim The width and the height of the video data @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The format of the video data @n + * It must be one of the pixel formats extracted from the GetSupportedFormatListN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* DetectBlinksFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::PixelFormat format); + + + /** + * Detects the eye states from the still image. + * + * @since 2.0 + * + * @return The list of eye states, @n + * else @c null if an exception occurs @n + * Each list item has an eyeState value @n + * An empty list is returned, if no eye states are detected and there is no error @n + * Eye states are not detected when the faces are too small, or the image is not clear @n + * This is the result of a normal operation. + * @param[in] byteBuffer The buffer that contains the input image data + * @param[in] dim The width and the height of the input image @n + * Both the width and height must be greater than @c 0. + * @param[in] format The color format defined by Tizen::Graphics::BitmapPixelFormat + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* DetectBlinksFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat format); + + /** + * Recognizes the facial expressions from a video. + * + * @since 2.0 + * + * @return The list of facial expressions, @n + * else @c null if an exception occurs @n + * Each list item has a facial expression value @n + * An empty list is returned, if no facial expressions are recognized and there is no error @n + * Facial expressions are not recognized when the faces are too small, or the video data is not clear @n + * This is the result of a normal operation. + * @param[in] byteBuffer The buffer that contains the video data + * @param[in] dim The width and the height of the video data @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The format of the video data @n + * It must be one of the pixel formats extracted from the GetSupportedFormatListN() method. + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* RecognizeExpressionsFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::PixelFormat format); + + + /** + * Recognizes the facial expressions from the still image. + * + * @since 2.0 + * + * @return The list of facial expressions, @n + * else @c null if an exception occurs @n + * Each list item has a facial expression value @n + * An empty list is returned, if no facial expressions are recognized and there is no error @n + * Facial expressions are not recognized when the faces are too small, or the image is not clear @n + * This is the result of a normal operation. + * @param[in] byteBuffer The buffer that contains the input image data + * @param[in] dim The width and the height of the input image @n + * Both the width and the height must be greater than @c 0. + * @param[in] format The color format defined by Tizen::Graphics::BitmapPixelFormat + * @exception E_SUCCESS The method is successful. + * @exception E_INVALID_ARG A specified input parameter is invalid. + * @exception E_OUT_OF_MEMORY The memory is insufficient. + * @exception E_SYSTEM A system error has occurred. + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* RecognizeExpressionsFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat format); + + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceRecognizer(const FaceRecognizer& value); + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + FaceRecognizer& operator =(const FaceRecognizer& value); + friend class _FaceRecognizerImpl; + +private: + _FaceRecognizerImpl* __pFaceRecognizerImpl; + +}; // FaceRecognizer + +} } } // Tizen::Uix::Vision + +#endif diff --git a/inc/FUixVisionFaceTypes.h b/inc/FUixVisionFaceTypes.h new file mode 100755 index 0000000..1ab9380 --- /dev/null +++ b/inc/FUixVisionFaceTypes.h @@ -0,0 +1,198 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVisionFaceTypes.h + * @brief This is the header file for the declarations of the %Vision namespace. + * + * This header file contains the declarations of the Vision namespace. + */ + +#ifndef _FUIX_VISION_FACE_TYPES_H_ +#define _FUIX_VISION_FACE_TYPES_H_ + +namespace Tizen { namespace Uix { namespace Vision +{ + +/** + * @enum FaceDetectorConfigProperty + * + * Defines the configuration properties of a FaceDetector. + * + * @since 2.0 + * + * @see FaceDetector::GetRange() + * @see FaceDetector::GetProperty() + */ +enum FaceDetectorConfigProperty +{ + /** + * The maximum number of faces to detect from a video stream. @n + * This is used when the FaceDetector::DetectFacesFromVideoStreamN() method is called. + */ + FACEDETECTOR_MAXNUMBER_VIDEO, + + /** + * The maximum number of faces to detect from a still image. @n + * This is used when the FaceDetector::DetectFacesFromStillImageN(const Tizen::Base::ByteBuffer&, const Tizen::Graphics::Dimension&, Tizen::Graphics::BitmapPixelFormat) method is called. + */ + FACEDETECTOR_MAXNUMBER_IMAGE, + + /** + * The minimum ratio of the detectable faces relative to the size of a video stream. @n + * This value ranges from @c 1 to @c 3, where @c 1 has the longest execution time and @c 3 + * has the shortest execution time. The value @c 1 detects small faces. + * Therefore, for an application using a camera or a video file, the value @c 3 is an appropriate option. + * The value @c 3 is used when the FaceDetector::DetectFacesFromVideoStreamN() method is called, unless it has been changed previously + * using the FaceDetector::SetProperty() method. @n + * + * This is used when the %FaceDetector::DetectFacesFromVideoStreamN() method is called. + */ + FACEDETECTOR_SCALE_VIDEO, + + /** + * The minimum ratio of the detectable faces relative to the size of a still image. @n + * This value ranges from @c 1 to @c 3, where @c 1 has the longest execution time and @c 3 has + * the shortest execution time. The value @c 1 detects small faces. + * Therefore, for an application handling images, the value @c 1 is an appropriate option. + * The value @c 1 is used when the FaceDetector::DetectFacesFromStillImageN(const Tizen::Base::ByteBuffer&, const Tizen::Graphics::Dimension&, Tizen::Graphics::BitmapPixelFormat) is called, unless it has been changed + * previously using the FaceDetector::SetProperty() method. @n + * + * This is used when %FaceDetector::DetectFacesFromStillImageN(const %Tizen::Base::ByteBuffer&, const %Tizen::Graphics::Dimension&, %Tizen::Graphics::BitmapPixelFormat) method is called. + */ + FACEDETECTOR_SCALE_IMAGE, + + /** + * The maximum number of faces to detect. @n + * The value @c 1 is used when the FaceDetector::DetectFacesN() method is called, unless it has been changed previously + * using the FaceDetector::SetProperty() method. @n + * This is used when the %FaceDetector::DetectFacesN() method is called. + */ + FACEDETECTOR_MAXNUMBER_FACES, + + /** + * The minimum ratio of the detectable faces relative to an input data. @n + * This value ranges from @c 1 to @c 3, where @c 1 has the longest execution time and @c 3 + * has the shortest execution time. The value @c 1 detects small faces. + * The value @c 3 is used when the FaceDetector::DetectFacesN() method is called, unless it has been changed previously using + * the FaceDetector::SetProperty() method. @n + * + * This is used when the %FaceDetector::DetectFacesN() method is called. + */ + FACEDETECTOR_SCALE_FACTOR, +}; + +/** + * @enum FaceRecognizerConfigProperty + * + * Defines the configuration properties of a FaceRecognizer. + * + * @since 2.0 + * + * @see FaceRecognizer::GetRange() + * @see FaceRecognizer::GetProperty() + */ +enum FaceRecognizerConfigProperty +{ + /** + * The maximum number of faces to extract face information, from a video stream. @n + * This is used when the FaceRecognizer::ExtractFaceInfoFromVideoStreamN() method is called. + */ + FACERECOGNIZER_MAXNUMBER_VIDEO, + + /** + * The maximum number of faces to extract face information, from a still image. @n + * This is used when the FaceRecognizer::ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer&, const Tizen::Graphics::Dimension&, Tizen::Graphics::BitmapPixelFormat) method is called. + */ + FACERECOGNIZER_MAXNUMBER_IMAGE, + + /** + * The minimum ratio of the detectable faces relative to the size of a video stream. @n + * This value ranges from @c 1 to @c 3, where @c 1 has the longest execution time and @c 3 has + * the shortest execution time. The value @c 1 detects small faces. + * Therefore, for an application using a camera or a video file, the value @c 3 is an appropriate option. + * The value @c 3 is used when the FaceRecognizer::ExtractFaceInfoFromVideoStreamN() method is called, unless it has been changed + * previously using the FaceDetector::SetProperty() method. @n + * + * This is used when the %FaceRecognizer::ExtractFaceInfoFromVideoStreamN() method is called. + */ + FACERECOGNIZER_SCALE_VIDEO, + + /** + * The minimum ratio of the detectable faces relative to the size of a still image. @n + * This value ranges from @c 1 to @c 3, where @c 1 has the longest execution time and @c 3 has + * the shortest execution time. The value @c 1 detects small faces. + * Therefore, for an application handling images, the value @c 1 is an appropriate option. + * The value @c 1 is used when the FaceRecognizer::ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer&, const Tizen::Graphics::Dimension&, Tizen::Graphics::BitmapPixelFormat) method is called, unless it has been changed + * previously using the FaceDetector::SetProperty() method. @n + * + * This is used when the %FaceRecognizer::ExtractFaceInfoFromStillImageN(const %Tizen::Base::ByteBuffer&, const %Tizen::Graphics::Dimension&, %Tizen::Graphics::BitmapPixelFormat) method is called. + */ + FACERECOGNIZER_SCALE_IMAGE, +}; + +/** + * @enum FaceDetectionOption + * + * Defines the face detection options. + * + * @since 2.0 + * + * @see FaceDetector::DetectFacesN() + */ +enum FaceDetectionOption +{ + FACE_DETECTION_OPTION_FAST, /**< The option to detect faces as fast as possible even if the accuracy is low */ + FACE_DETECTION_OPTION_ROBUST, /**< The option to detect faces as accurate as possible even if it takes more time */ +}; + +/** + * @enum EyeState + * + * Defines the eye states. + * + * @since 2.0 + * + * @see FaceRecognizer::GetEyeState() + */ +enum EyeState +{ + EYE_STATE_NONE, /**< No eye state, when the eye detection fails */ + EYE_STATE_BOTH_OPEN, /**< The state when both eyes are open */ + EYE_STATE_BOTH_CLOSED, /**< The state when both eyes are closed */ +}; + +/** + * @enum FacialExpression + * + * Defines the facial expressions. + * + * @since 2.0 + * + * @see FaceRecognizer::RecognizeExpression() + */ +enum FacialExpression +{ + FACIAL_EXPRESSION_NONE, /**< No facial expression, when the face recognition fails */ + FACIAL_EXPRESSION_NEUTRAL, /**< The neutral facial expression */ + FACIAL_EXPRESSION_ANGRY, /**< The angry facial expression */ + FACIAL_EXPRESSION_HAPPY, /**< The happy facial expression */ + FACIAL_EXPRESSION_SURPRISED, /**< The surprised facial expression */ +}; + +} } } // Tizen::Uix::Vision +#endif diff --git a/osp-face.manifest b/osp-face.manifest new file mode 100644 index 0000000..ae3e6f7 --- /dev/null +++ b/osp-face.manifest @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/osp-face.pc.in b/osp-face.pc.in new file mode 100755 index 0000000..eb6c3b7 --- /dev/null +++ b/osp-face.pc.in @@ -0,0 +1,14 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib/osp +includedir=/usr/include/osp + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} + diff --git a/packaging/osp-face.spec b/packaging/osp-face.spec new file mode 100644 index 0000000..2a90eaf --- /dev/null +++ b/packaging/osp-face.spec @@ -0,0 +1,89 @@ +%define debug_package %{nil} +%define __strip /bin/true + +Name: osp-face +Summary: osp face library +Version: 1.2.2.0 +Release: 2 +Group: System/Libraries +License: Apache-2.0, flora-1.1 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(face-engine) +BuildRequires: pkgconfig(osp-appfw) +BuildRequires: osp-appfw-internal-devel +BuildRequires: pkgconfig(osp-uifw) +BuildRequires: osp-uifw-internal-devel + +# runtime requires +Requires: face-engine +Requires: osp-appfw +Requires: osp-uifw + +%description +osp face library + +%package devel +Summary: osp face library (Development) +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description devel +osp face library (DEV) + +%package debug +Summary: osp face library (Development) +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description debug +osp face library (DEV) + +%prep +%setup -q + +%build +%if 0%{?tizen_build_binary_release_type_eng} +CXXFLAGS="$CXXFLAGS -D_SECURE_LOG" +%endif +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%ifarch %{ix86} +%if 0%{?simulator} +CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ -D_OSP_EMUL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ " cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif +%else +%if 0%{?tizen_build_binary_release_type_eng} +CXXFLAGS="-O2 -g -pipe -Wall -fno-exceptions -Wformat -Wformat-security -Wl,--as-needed -fmessage-length=0 -march=armv7-a -mtune=cortex-a8 -mlittle-endian -mfpu=neon -mfloat-abi=softfp -D__SOFTFP__ -mthumb -Wa,-mimplicit-it=thumb -funwind-tables -D_OSP_DEBUG_ -D_SECURE_LOG -D_OSP_ARMEL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CXXFLAGS="-O2 -g -pipe -Wall -fno-exceptions -Wformat -Wformat-security -Wl,--as-needed -fmessage-length=0 -march=armv7-a -mtune=cortex-a8 -mlittle-endian -mfpu=neon -mfloat-abi=softfp -D__SOFTFP__ -mthumb -Wa,-mimplicit-it=thumb -funwind-tables -D_OSP_DEBUG_ -D_OSP_ARMEL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif +%endif + +# Call make instruction with smp support +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{name}-%{version}/LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} +cat %{_builddir}/%{name}-%{version}/LICENSE.Flora >> %{buildroot}/usr/share/license/%{name} +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest osp-face.manifest +/usr/share/license/%{name} +%{_libdir}/osp/*.so* + +%files devel +%{_includedir}/osp/*.h +%{_libdir}/pkgconfig/osp-face.pc + +%files debug +%{_libdir}/osp/debug/*.so* diff --git a/src/FUixVisionFaceBuffer.cpp b/src/FUixVisionFaceBuffer.cpp new file mode 100644 index 0000000..3b17763 --- /dev/null +++ b/src/FUixVisionFaceBuffer.cpp @@ -0,0 +1,74 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/** + * @file FUixVisionFaceBuffer.cpp + * @brief This is the implementation file for the %FaceBuffer class. + * + * This files contains implementation of the %FaceBuffer class. + */ + +// Includes +#include +#include +#include +#include +#include +#include + +namespace Tizen { namespace Uix { namespace Vision +{ + +FaceBuffer::FaceBuffer(void) + : __pBuffer(null) + , __resolution(0, 0) +{ + +} + +FaceBuffer::~FaceBuffer(void) +{ + if (__pBuffer != null) + { + delete __pBuffer; + __pBuffer = null; + } +} + +FaceBuffer::FaceBuffer(const Tizen::Base::ByteBuffer& buffer, const Tizen::Graphics::Dimension& resolution) +{ + __pBuffer = new (std::nothrow) Tizen::Base::ByteBuffer; + SysTryReturn(NID_UIX, __pBuffer != null, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + __pBuffer->Construct(buffer); + + __resolution.width = resolution.width; + __resolution.height = resolution.height; +} + +Tizen::Graphics::Dimension +FaceBuffer::GetDimension(void) const +{ + return __resolution; +} + +const Tizen::Base::ByteBuffer* +FaceBuffer::GetBuffer(void) const +{ + return __pBuffer; +} + +} } } //Tizen::Uix::Vision \ No newline at end of file diff --git a/src/FUixVisionFaceComponentsPosition.cpp b/src/FUixVisionFaceComponentsPosition.cpp new file mode 100644 index 0000000..f594a83 --- /dev/null +++ b/src/FUixVisionFaceComponentsPosition.cpp @@ -0,0 +1,188 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVisionFaceComponentsPosition.cpp + * @brief This is the implementation file for the %FaceComponentsPosition class. + * + * This files contains implementation of the %FaceComponentsPosition class. + */ + +// Includes +#include +#include +#include +#include +#include + +namespace Tizen { namespace Uix { namespace Vision +{ + +FaceComponentsPosition::FaceComponentsPosition(void) + : __faceRect(-1, -1, -1, -1) + , __eyeRight(-1, -1) + , __eyeLeft(-1, -1) + , __mouthRect(-1, -1, -1, -1) +{ + +} + +FaceComponentsPosition::~FaceComponentsPosition(void) +{ + +} + +FaceComponentsPosition::FaceComponentsPosition(const Tizen::Graphics::Rectangle& faceRect) + : __eyeRight(-1, -1) + , __eyeLeft(-1, -1) + , __mouthRect(-1, -1, -1, -1) +{ + __faceRect.x = faceRect.x; + __faceRect.y = faceRect.y; + __faceRect.width = faceRect.width; + __faceRect.height = faceRect.height; +} + +FaceComponentsPosition::FaceComponentsPosition(const Tizen::Graphics::Rectangle& faceRect, const Tizen::Graphics::Point& eyeLeft, const Tizen::Graphics::Point& eyeRight) + : __mouthRect(-1, -1, -1, -1) +{ + __faceRect.x = faceRect.x; + __faceRect.y = faceRect.y; + __faceRect.width = faceRect.width; + __faceRect.height = faceRect.height; + + __eyeRight.x = eyeRight.x; + __eyeRight.y = eyeRight.y; + __eyeLeft.x = eyeLeft.x; + __eyeLeft.y = eyeLeft.y; +} + +Tizen::Graphics::Rectangle +FaceComponentsPosition::GetFacePosition(void) const +{ + return __faceRect; +} + +void +FaceComponentsPosition::GetEyePosition(Tizen::Graphics::Point& eyeLeft, Tizen::Graphics::Point& eyeRight) const +{ + eyeRight.x = __eyeRight.x; + eyeRight.y = __eyeRight.y; + eyeLeft.x = __eyeLeft.x; + eyeLeft.y = __eyeLeft.y; +} + +Tizen::Graphics::Rectangle +FaceComponentsPosition::GetMouthPosition(void) const +{ + return __mouthRect; +} + +result +FaceComponentsPosition::SetEyePosition(const Tizen::Graphics::Point& eyeLeft, const Tizen::Graphics::Point& eyeRight) +{ + SysTryReturn(NID_UIX, eyeLeft.x > 0 && eyeLeft.y > 0 && eyeRight.x > 0 && eyeRight.y > 0, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The position of eyes should be greater or equal 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryReturn(NID_UIX, eyeRight.x > eyeLeft.x, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The position of eyeRight should be greater than the position of eyeLeft.", GetErrorMessage(E_INVALID_ARG)); + + __eyeRight.x = eyeRight.x; + __eyeRight.y = eyeRight.y; + __eyeLeft.x = eyeLeft.x; + __eyeLeft.y = eyeLeft.y; + + return E_SUCCESS; +} + +result +FaceComponentsPosition::SetMouthPosition(const Tizen::Graphics::Rectangle& mouthRect) +{ + SysTryReturn(NID_UIX, mouthRect.x >= 0 && mouthRect.y >= 0, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The x and y of the mouthRect should be greater or equal 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryReturn(NID_UIX, mouthRect.width > 0 && mouthRect.height > 0, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width and height of the mouthRect should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + __mouthRect.x = mouthRect.x; + __mouthRect.y = mouthRect.y; + __mouthRect.width = mouthRect.width; + __mouthRect.height = mouthRect.height; + + return E_SUCCESS; +} + +result +FaceComponentsPosition::SetFacePosition(const Tizen::Graphics::Rectangle& faceRect) +{ + SysTryReturn(NID_UIX, faceRect.x >= 0 && faceRect.y >= 0, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The x and y of the faceRect should be greater or equal 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryReturn(NID_UIX, faceRect.width > 0 && faceRect.height > 0, E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width and height of the mouthRect should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + __faceRect.x = faceRect.x; + __faceRect.y = faceRect.y; + __faceRect.width = faceRect.width; + __faceRect.height = faceRect.height; + + return E_SUCCESS; +} + +FaceComponentsPosition::FaceComponentsPosition(const FaceComponentsPosition& rhs) +{ + __eyeLeft.x = rhs.__eyeLeft.x; + __eyeLeft.y = rhs.__eyeLeft.y; + + __eyeRight.x = rhs.__eyeRight.x; + __eyeRight.y = rhs.__eyeRight.y; + + __faceRect.x = rhs.__faceRect.x; + __faceRect.y = rhs.__faceRect.y; + __faceRect.width = rhs.__faceRect.width; + __faceRect.height = rhs.__faceRect.height; + + __mouthRect.x = rhs.__mouthRect.x; + __mouthRect.y = rhs.__mouthRect.y; + __mouthRect.width = rhs.__mouthRect.width; + __mouthRect.height = rhs.__mouthRect.height; +} + +FaceComponentsPosition& +FaceComponentsPosition::operator =(const FaceComponentsPosition& rhs) +{ + if (&rhs == this) + { + return *this; + } + this->__eyeLeft.x = rhs.__eyeLeft.x; + this->__eyeLeft.y = rhs.__eyeLeft.y; + + this->__eyeRight.x = rhs.__eyeRight.x; + this->__eyeRight.y = rhs.__eyeRight.y; + + this->__faceRect.x = rhs.__faceRect.x; + this->__faceRect.y = rhs.__faceRect.y; + this->__faceRect.width = rhs.__faceRect.width; + this->__faceRect.height = rhs.__faceRect.height; + + this->__mouthRect.x = rhs.__mouthRect.x; + this->__mouthRect.y = rhs.__mouthRect.y; + this->__mouthRect.width = rhs.__mouthRect.width; + this->__mouthRect.height = rhs.__mouthRect.height; + + return *this; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVisionFaceDetector.cpp b/src/FUixVisionFaceDetector.cpp new file mode 100644 index 0000000..26a8049 --- /dev/null +++ b/src/FUixVisionFaceDetector.cpp @@ -0,0 +1,393 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVisionFaceDetector.cpp + * @brief This is the implementation file for the %FaceDetector class. + * + * This files contains implementation of the %FaceDetector class. + */ + +// Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FUixVision_FaceDetectorImpl.h" + +namespace Tizen { namespace Uix { namespace Vision +{ + +FaceDetector::FaceDetector(void) + : __pFaceDetectorImpl(null) +{ + +} + +FaceDetector::~FaceDetector(void) +{ + if (__pFaceDetectorImpl != null) + { + delete __pFaceDetectorImpl; + __pFaceDetectorImpl = null; + } +} + +result +FaceDetector::Construct(void) +{ + SysAssertf(__pFaceDetectorImpl == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class."); + + result r = E_SUCCESS; + + std::unique_ptr< _FaceDetectorImpl > pFaceDetectorImpl(new (std::nothrow) _FaceDetectorImpl()); + SysTryReturn(NID_UIX, pFaceDetectorImpl != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pFaceDetectorImpl->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + + __pFaceDetectorImpl = pFaceDetectorImpl.release(); + + return r; +} + +result +FaceDetector::GetRange(FaceDetectorConfigProperty configProperty, long& min, long& max, long& steppingDelta, + long& defaultVal) const +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + SysTryReturn(NID_UIX, configProperty >= FACEDETECTOR_MAXNUMBER_VIDEO && configProperty <= FACEDETECTOR_SCALE_FACTOR, + E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, + "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + + return __pFaceDetectorImpl->GetRange(configProperty, min, max, steppingDelta, defaultVal); +} + +long +FaceDetector::GetProperty(FaceDetectorConfigProperty configProperty) const +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + SysTryCatch(NID_UIX, configProperty >= FACEDETECTOR_MAXNUMBER_VIDEO && configProperty <= FACEDETECTOR_SCALE_FACTOR, + r = E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, + "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + + return __pFaceDetectorImpl->GetProperty(configProperty); + +CATCH: + SetLastResult(r); + return (long) -1; +} + +result +FaceDetector::SetProperty(FaceDetectorConfigProperty configProperty, long value) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + SysTryReturn(NID_UIX, configProperty >= FACEDETECTOR_MAXNUMBER_VIDEO && configProperty <= FACEDETECTOR_SCALE_FACTOR, + E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, + "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + + return __pFaceDetectorImpl->SetProperty(configProperty, value); +} + +Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* +FaceDetector::GetSupportedFormatListN(void) const +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + return __pFaceDetectorImpl->GetSupportedFormatListN(); +} + +Tizen::Base::Collection::IList* +FaceDetector::DetectFacesFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* pList = null; + + SysTryCatch(NID_UIX, 0 <= resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 <= resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + pList = GetSupportedFormatListN(); + + SysTryCatch(NID_UIX, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult())); + + if (pList->Contains(format) == false) + { + SysTryCatch(NID_UIX, false, r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format is invalid.", GetErrorMessage(E_INVALID_ARG)); + } + + pList->RemoveAll(); + delete pList; + pList = null; + + // Below check routine includes the Pixelformat. Therefore it is checked after verifying format is valid. + if (format == Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR) + { + bytePerPixel = 1.5f; + } + else if (format == Tizen::Graphics::PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + byteBuffer.GetLimit() == (int) (resolution.width * resolution.height * bytePerPixel), r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c byteBuffer does not have the size specified by the @c width, @c height, and @c format.", GetErrorMessage(E_INVALID_ARG)); + + return __pFaceDetectorImpl->DetectFacesFromBufferN(byteBuffer, resolution, format); + +CATCH: + if (pList != null) + { + pList->RemoveAll(); + delete pList; + pList = null; + } + + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IList* +FaceDetector::DetectFacesFromStillImageN(const Tizen::Graphics::Bitmap& bitmap) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + return __pFaceDetectorImpl->DetectFacesFromBitmapN(bitmap); +} + +Tizen::Base::Collection::IList* +FaceDetector::DetectFacesFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, format > Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN && format < Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX, r = + E_INVALID_ARG, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(E_INVALID_ARG)); + + return __pFaceDetectorImpl->DetectFacesFromBitmapN(byteBuffer, resolution, format); + +CATCH: + SetLastResult(r); + return null; +} + +/*** since 2.0 ***/ +FaceBuffer* +FaceDetector::PreprocessDataN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& dim, + Tizen::Graphics::PixelFormat format) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + float bytePerPixel = 0.0f; + std::unique_ptr< FaceBuffer > pProcessedData; + + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* pFormatList = null; + Tizen::Base::ByteBuffer* pGrayBuf = null; + + SysTryCatch(NID_UIX, 0 < dim.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < dim.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + pFormatList = GetSupportedFormatListN(); + SysTryCatch(NID_UIX, pFormatList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult())); + SysTryCatch(NID_UIX, pFormatList->Contains( + format) == true, r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format is invalid.", GetErrorMessage(E_INVALID_ARG)); + + pFormatList->RemoveAll(); + + delete pFormatList; + pFormatList = null; + + if (format == Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR) + { + bytePerPixel = 1.5f; + } + else if (format == Tizen::Graphics::PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + (int) (dim.width * dim.height * bytePerPixel) == byteBuffer.GetLimit(), r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c byteBuffer does not have the size specified by the @c width, @c height, and @c format.", GetErrorMessage(E_INVALID_ARG)); + + pGrayBuf = __pFaceDetectorImpl->ConvertToGrayN(byteBuffer, dim, format); + + pProcessedData = std::unique_ptr(new (std::nothrow) FaceBuffer(*pGrayBuf, dim)); + SysTryCatch(NID_UIX, pProcessedData.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + delete pGrayBuf; + pGrayBuf = null; + + return pProcessedData.release(); + +CATCH: + delete pFormatList; + pFormatList = null; + + delete pGrayBuf; + pGrayBuf = null; + + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IList* +FaceDetector::DetectFacesN(const FaceBuffer& preprocessedData, FaceDetectionOption mode) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + switch (mode) + { + case FACE_DETECTION_OPTION_FAST: + // fall through + case FACE_DETECTION_OPTION_ROBUST: + break; + + default: + SysTryCatch(NID_UIX, false, r = E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, "[%s] The specified mode is not supported.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + break; + } + + return __pFaceDetectorImpl->DetectFacesN(*(preprocessedData.GetBuffer()), preprocessedData.GetDimension(), mode); + +CATCH: + SetLastResult(r); + return null; +} + +FaceComponentsPosition* +FaceDetector::ExtractFaceComponentsN(const FaceBuffer& preprocessedFaceBuffer, const Tizen::Graphics::Rectangle& faceRect) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + Tizen::Graphics::Dimension resolution; + Tizen::Graphics::Point eyeRight; + Tizen::Graphics::Point eyeLeft; + Tizen::Graphics::Rectangle mouthRect; + + std::unique_ptr< FaceComponentsPosition > pGeoInfo(new (std::nothrow) FaceComponentsPosition()); + SysTryReturn(NID_UIX, pGeoInfo != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + resolution = preprocessedFaceBuffer.GetDimension(); + SysTryReturn(NID_UIX, + faceRect.x >= 0 && faceRect.y >= 0 && faceRect.width > 0 && faceRect.height > 0 && + faceRect.x + faceRect.width < resolution.width && faceRect.y + faceRect.height < resolution.height, + null, E_INVALID_ARG, + "[%s] The specified @c faceRect is not within the @c FaceComponentsPosition.", GetErrorMessage(E_INVALID_ARG)); + + r = pGeoInfo->SetFacePosition(faceRect); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + resolution = preprocessedFaceBuffer.GetDimension(); + + r = __pFaceDetectorImpl->ExtractFaceComponents(*(preprocessedFaceBuffer.GetBuffer()), resolution, faceRect, eyeRight, eyeLeft, mouthRect); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + r = pGeoInfo->SetEyePosition(eyeLeft, eyeRight); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + r = pGeoInfo->SetMouthPosition(mouthRect); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + return pGeoInfo.release(); +} + +result +FaceDetector::GetFaceMovement(const FaceBuffer& prevData, const FaceBuffer& curData, const Tizen::Graphics::Rectangle& prevFaceRect, + int& xDiff, + int& yDiff) +{ + SysAssertf(__pFaceDetectorImpl != null, "Not yet constructed. Construct() should be called before use."); + + result r = E_SUCCESS; + Tizen::Graphics::Dimension resolution; + Tizen::Graphics::Point posDiff(0, 0); + + resolution = prevData.GetDimension(); + SysLogException(NID_UIX, E_SUCCESS, "XXXX - 001 Entering GetFaceMovement prevData.x = %d, prevData.y = %d", resolution.width, resolution.height); + SysLogException(NID_UIX, E_SUCCESS, "XXXX - 002 Entering GetFaceMovement curData.x = %d, curData.y = %d", curData.GetDimension().width, curData.GetDimension().height); + + SysTryReturn(NID_UIX, + resolution == curData.GetDimension(), E_INVALID_ARG, E_INVALID_ARG, + "[%s] The size of @c prevData and @c curData should be the same.", GetErrorMessage(E_INVALID_ARG)); + + SysTryReturn(NID_UIX, + prevFaceRect.x >= 0 && prevFaceRect.y >= 0 && prevFaceRect.width > 0 && prevFaceRect.height > 0 && + prevFaceRect.x + prevFaceRect.width < resolution.width && prevFaceRect.y + prevFaceRect.height < resolution.height, + E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c prevFaceRect is not within the @c preprocessedData.", GetErrorMessage(E_INVALID_ARG)); + + r = __pFaceDetectorImpl->GetPosDifference(*(prevData.GetBuffer()), *(curData.GetBuffer()), resolution, prevFaceRect, posDiff); + SysTryReturn(NID_UIX, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + + xDiff = posDiff.x; + yDiff = posDiff.y; + return r; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVisionFaceRecognitionInfo.cpp b/src/FUixVisionFaceRecognitionInfo.cpp new file mode 100644 index 0000000..032bc0d --- /dev/null +++ b/src/FUixVisionFaceRecognitionInfo.cpp @@ -0,0 +1,91 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVisionFaceRecognitionInfo.cpp + * @brief This is the implementation file for the %FaceRecognitionInfo class. + * + * This files contains implementation of the %FaceRecognitionInfo class. + */ + +// Includes +#include +#include +#include +#include +#include +#include +#include + +namespace Tizen { namespace Uix { namespace Vision +{ + +FaceRecognitionInfo::FaceRecognitionInfo(void) + : __pfaceFeatures(null) +{ + +} + +result +FaceRecognitionInfo::Construct(const Tizen::Base::ByteBuffer& faceFeatures) +{ + SysAssertf(__pfaceFeatures == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class."); + + __pfaceFeatures = new (std::nothrow) Tizen::Base::ByteBuffer; + SysTryReturn(NID_UIX, __pfaceFeatures != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + result r = __pfaceFeatures->Construct(faceFeatures); + if (IsFailed(r)) + { + SysLogException(NID_UIX, E_INVALID_ARG, "[%s] The faceFeatures is not constructed.", GetErrorMessage(E_INVALID_ARG)); + delete __pfaceFeatures; + __pfaceFeatures = null; + } + + return r; +} + +FaceRecognitionInfo::~FaceRecognitionInfo(void) +{ + if (__pfaceFeatures != null) + { + delete __pfaceFeatures; + __pfaceFeatures = null; + } +} + +Tizen::Graphics::Rectangle +FaceRecognitionInfo::GetFacePosition(void) const +{ + return __faceRect; +} + +const Tizen::Base::ByteBuffer* +FaceRecognitionInfo::GetFaceFeatures(void) const +{ + SysAssertf(__pfaceFeatures != null, "Not yet constructed. Construct() should be called before use."); + + return __pfaceFeatures; +} + +void +FaceRecognitionInfo::SetFacePosition(int x, int y, int width, int height) +{ + __faceRect = Tizen::Graphics::Rectangle(x, y, width, height); +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVisionFaceRecognizer.cpp b/src/FUixVisionFaceRecognizer.cpp new file mode 100644 index 0000000..0a7cc73 --- /dev/null +++ b/src/FUixVisionFaceRecognizer.cpp @@ -0,0 +1,623 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVisionFaceRecognizer.cpp + * @brief This file contains implementation of FaceRecognizer class. + * + * + * This file contains the implementation of FaceRecognizer class. + */ + +// includes +#include +#include +#include +#include +#include +#include "FUixVision_FaceRecognizerImpl.h" + +#define EYE_DISTANCE_SQUARE 11 * 11 + +// namespace +using namespace Tizen::Base; +//using namespace Tizen::Com; + +namespace Tizen { namespace Uix { namespace Vision +{ + +/////////////////////////////////////////////////////////////////// +// Life-time +FaceRecognizer::FaceRecognizer(void) + : __pFaceRecognizerImpl(null) +{ + +} + +FaceRecognizer::~FaceRecognizer(void) +{ + if (__pFaceRecognizerImpl != null) + { + delete __pFaceRecognizerImpl; + __pFaceRecognizerImpl = null; + } +} + +result +FaceRecognizer::Construct(void) +{ + SysAssertf(__pFaceRecognizerImpl == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class."); + + result r = E_SUCCESS; + + std::unique_ptr< _FaceRecognizerImpl > pFaceRecognizerImpl(new (std::nothrow) _FaceRecognizerImpl()); + SysTryReturn(NID_UIX, pFaceRecognizerImpl != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pFaceRecognizerImpl->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, r, r, "[%s] Construct failed", GetErrorMessage(r)); + + __pFaceRecognizerImpl = pFaceRecognizerImpl.release(); + + return r; +} + +result +FaceRecognizer::GetRange(FaceRecognizerConfigProperty configProperty, long& min, long& max, long& steppingDelta, + long& defaultVal) const +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + switch (configProperty) + { + case FACERECOGNIZER_MAXNUMBER_VIDEO: + // fall through + case FACERECOGNIZER_MAXNUMBER_IMAGE: + // fall through + case FACERECOGNIZER_SCALE_VIDEO: + // fall through + case FACERECOGNIZER_SCALE_IMAGE: + break; + + default: + SysLogException(NID_UIX, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + return E_UNSUPPORTED_OPERATION; + } + + return __pFaceRecognizerImpl->GetRange(configProperty, min, max, steppingDelta, defaultVal); +} + +long +FaceRecognizer::GetProperty(FaceRecognizerConfigProperty configProperty) const +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + SysTryCatch(NID_UIX, configProperty >= FACERECOGNIZER_MAXNUMBER_VIDEO && configProperty <= FACERECOGNIZER_SCALE_IMAGE, + r = E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, + "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + + return __pFaceRecognizerImpl->GetProperty(configProperty); +CATCH: + SetLastResult(r); + return (long) -1; +} + +result +FaceRecognizer::SetProperty(FaceRecognizerConfigProperty configProperty, long value) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + switch (configProperty) + { + case FACERECOGNIZER_MAXNUMBER_VIDEO: + // fall through + case FACERECOGNIZER_MAXNUMBER_IMAGE: + // fall through + case FACERECOGNIZER_SCALE_VIDEO: + // fall through + case FACERECOGNIZER_SCALE_IMAGE: + break; + + default: + SysLogException(NID_UIX, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + return E_UNSUPPORTED_OPERATION; + } + + return __pFaceRecognizerImpl->SetProperty(configProperty, value); +} + +Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* +FaceRecognizer::GetSupportedFormatListN(void) const +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + return __pFaceRecognizerImpl->GetSupportedFormatListN(); +} + +Tizen::Base::Collection::IList* +FaceRecognizer::ExtractFaceInfoFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* pList = null; + + pList = GetSupportedFormatListN(); + SysTryCatch(NID_UIX, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult())); + + SysTryCatch(NID_UIX, (pList->Contains(format) == true), r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format is invalid." + , GetErrorMessage(E_INVALID_ARG)); + + pList->RemoveAll(); + delete pList; + pList = null; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + // Below check routine includes the Pixelformat. Therefore it is checked after verifying format is valid. + if (format == Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR) + { + bytePerPixel = 1.5f; + } + else if (format == Tizen::Graphics::PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + SysTryCatch(NID_UIX, + !(Float::Compare((float) byteBuffer.GetLimit(), (float) (resolution.width * resolution.height * bytePerPixel))), r = E_INVALID_ARG, + E_INVALID_ARG, + "[%s] The specified @c byteBuffer does not have the size specified by the @c width, @c height, and @c format.", + GetErrorMessage(E_INVALID_ARG)); + + + return __pFaceRecognizerImpl->ExtractFaceFeaturesFromBufferN(byteBuffer, resolution, format); + +CATCH: + if (pList != null) + { + pList->RemoveAll(); + delete pList; + pList = null; + } + + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IList* +FaceRecognizer::ExtractFaceInfoFromStillImageN(const Tizen::Graphics::Bitmap& bitmap) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + return __pFaceRecognizerImpl->ExtractFaceFeaturesFromBitmapN(bitmap); +} + +Tizen::Base::Collection::IList* +FaceRecognizer::ExtractFaceInfoFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, format > Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN && format < Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX, r = + E_INVALID_ARG, E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(E_INVALID_ARG)); + + return __pFaceRecognizerImpl->ExtractFaceFeaturesFromBitmapN(byteBuffer, resolution, format); +CATCH: + SetLastResult(r); + return null; +} + +bool +FaceRecognizer::IsMatching(const FaceRecognitionInfo& face1, const FaceRecognitionInfo& face2) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + const Tizen::Base::ByteBuffer* faceFeatures1 = null; + const Tizen::Base::ByteBuffer* faceFeatures2 = null; + + faceFeatures1 = face1.GetFaceFeatures(); + SysTryCatch(NID_UIX, faceFeatures1 != null, r = E_INVALID_ARG, E_INVALID_ARG, + ("[%s] A specified FaceRecognitionInfo is not constructed yet.", GetErrorMessage(E_INVALID_ARG))); + + faceFeatures2 = face2.GetFaceFeatures(); + SysTryCatch(NID_UIX, faceFeatures2 != null, r = E_INVALID_ARG, E_INVALID_ARG, + ("[%s] A specified FaceRecognitionInfo is not constructed yet.", GetErrorMessage(E_INVALID_ARG))); + + return __pFaceRecognizerImpl->IsMatching(*(faceFeatures1), *(faceFeatures2)); + +CATCH: + SetLastResult(r); + return false; +} + +int +FaceRecognizer::MeasureSimilarity(const FaceRecognitionInfo& face1, const FaceRecognitionInfo& face2) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + const Tizen::Base::ByteBuffer* faceFeatures1 = null; + const Tizen::Base::ByteBuffer* faceFeatures2 = null; + + faceFeatures1 = face1.GetFaceFeatures(); + SysTryCatch(NID_UIX, faceFeatures1 != null, r = E_INVALID_ARG, E_INVALID_ARG, + ("[%s] A specified FaceRecognitionInfo is not constructed yet.", GetErrorMessage(E_INVALID_ARG))); + + faceFeatures2 = face2.GetFaceFeatures(); + SysTryCatch(NID_UIX, faceFeatures2 != null, r = E_INVALID_ARG, E_INVALID_ARG, + ("[%s] A specified FaceRecognitionInfo is not constructed yet.", GetErrorMessage(E_INVALID_ARG))); + + return __pFaceRecognizerImpl->MeasureSimilarity(*(faceFeatures1), *(faceFeatures2)); + +CATCH: + SetLastResult(r); + return -1; +} + +/*** since 2.0 ***/ +Tizen::Base::ByteBuffer* +FaceRecognizer::ExtractFeatureN(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + Tizen::Graphics::Dimension resolution; + Tizen::Graphics::Point eyeRight; + Tizen::Graphics::Point eyeLeft; + Tizen::Graphics::Rectangle faceRect; + + resolution = preprocessedFaceBuffer.GetDimension(); + faceComponentPos.GetEyePosition(eyeLeft, eyeRight); + faceRect = faceComponentPos.GetFacePosition(); + SysTryCatch(NID_UIX, + eyeLeft.x >= 0 && eyeLeft.y >= 0 && eyeRight.x >= 0 && eyeRight.y >= 0 && + eyeRight.x <= resolution.width && eyeRight.y <= resolution.height && eyeLeft.y <= resolution.height, + r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c eyes's positions in the faceComponentPos should be withiin the @c preprocessedFaceBuffer.", + GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, eyeLeft.x < eyeRight.x, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, + "[%s] The value of the x position for the right eye should be greater than left one.", GetErrorMessage(E_OPERATION_FAILED)); + + if (eyeLeft.y != eyeRight.y) + { + SysTryCatch(NID_UIX, + ((eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x)) + ((eyeRight.y - eyeLeft.y) * (eyeRight.y - eyeLeft.y)) > + EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to extract the facial information.", GetErrorMessage(E_OPERATION_FAILED)); + } + else + { + SysTryCatch(NID_UIX, (eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x) > EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to extract the facial information.", GetErrorMessage(E_OPERATION_FAILED)); + } + + return __pFaceRecognizerImpl->ExtractFeatureN(*(preprocessedFaceBuffer.GetBuffer()), resolution, faceRect, eyeLeft, eyeRight); + +CATCH: + SetLastResult(r); + return null; +} + +EyeState +FaceRecognizer::GetEyeState(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + Tizen::Graphics::Dimension resolution; + Tizen::Graphics::Rectangle faceRect; + Tizen::Graphics::Point eyeRight; + Tizen::Graphics::Point eyeLeft; + + resolution = preprocessedFaceBuffer.GetDimension(); + faceComponentPos.GetEyePosition(eyeLeft, eyeRight); + faceRect = faceComponentPos.GetFacePosition(); + SysTryCatch(NID_UIX, + eyeLeft.x >= 0 && eyeLeft.y >= 0 && eyeRight.x >= 0 && eyeRight.y >= 0 && + eyeRight.x <= resolution.width && eyeRight.y <= resolution.height && eyeLeft.y <= resolution.height, + r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c eyes's positions in the faceComponentPos should be withiin the @c preprocessedFaceBuffer.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, eyeLeft.x < eyeRight.x, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, + "[%s] The value of the x position for the right eye should be greater than left one.", GetErrorMessage(E_OPERATION_FAILED)); + + if (eyeLeft.y != eyeRight.y) + { + SysTryCatch(NID_UIX, + ((eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x)) + ((eyeRight.y - eyeLeft.y) * (eyeRight.y - eyeLeft.y)) > + EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to detect the eye state.", GetErrorMessage(E_OPERATION_FAILED)); + } + else + { + SysTryCatch(NID_UIX, (eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x) > EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to detect the eye state.", GetErrorMessage(E_OPERATION_FAILED)); + } + return __pFaceRecognizerImpl->DetectEyeState(*(preprocessedFaceBuffer.GetBuffer()), resolution, faceRect, eyeLeft, eyeRight); + +CATCH: + SetLastResult(r); + return EYE_STATE_NONE; +} + +FacialExpression +FaceRecognizer::RecognizeExpression(const FaceBuffer& preprocessedFaceBuffer, const FaceComponentsPosition& faceComponentPos) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + Tizen::Graphics::Dimension resolution; + Tizen::Graphics::Rectangle faceRect; + Tizen::Graphics::Point eyeRight; + Tizen::Graphics::Point eyeLeft; + Tizen::Graphics::Rectangle mouthRect; + + resolution = preprocessedFaceBuffer.GetDimension(); + faceComponentPos.GetEyePosition(eyeLeft, eyeRight); + faceRect = faceComponentPos.GetFacePosition(); + mouthRect = faceComponentPos.GetMouthPosition(); + SysTryCatch(NID_UIX, + eyeLeft.x >= 0 && eyeLeft.y >= 0 && eyeRight.x >= 0 && eyeRight.y >= 0 && + eyeRight.x <= resolution.width && eyeRight.y <= resolution.height && eyeLeft.y <= resolution.height, + r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c eyes's positions in the faceComponentPos should be withiin the @c preprocessedFaceBuffer.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, eyeLeft.x < eyeRight.x, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, + "[%s] The value of the x position for the right eye should be greater than left one.", GetErrorMessage(E_OPERATION_FAILED)); + + if (eyeLeft.y != eyeRight.y) + { + SysTryCatch(NID_UIX, + ((eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x)) + ((eyeRight.y - eyeLeft.y) * (eyeRight.y - eyeLeft.y)) > + EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to recognize the facial expression.", GetErrorMessage(E_OPERATION_FAILED)); + } + else + { + SysTryCatch(NID_UIX, (eyeRight.x - eyeLeft.x) * (eyeRight.x - eyeLeft.x) > EYE_DISTANCE_SQUARE, + r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Fail to recognize the facial expression.", GetErrorMessage(E_OPERATION_FAILED)); + } + return __pFaceRecognizerImpl->RecognizeExpression(*(preprocessedFaceBuffer.GetBuffer()), resolution, faceRect, mouthRect); + +CATCH: + SetLastResult(r); + return FACIAL_EXPRESSION_NONE; +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* +FaceRecognizer::DetectBlinksFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN< format&& Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX > format, + r = E_INVALID_ARG, E_INVALID_ARG, "[%s] The specified @c format is not supported.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888) || (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565), + r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format(%d) is invalid.", GetErrorMessage(E_INVALID_ARG), format); + + if (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888) + { + bytePerPixel = 4.0f; + } + else if (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + !(Float::Compare((float) byteBuffer.GetLimit(), (float) (resolution.width * resolution.height * bytePerPixel))), + r = E_INVALID_ARG, E_INVALID_ARG, "[%s] The specified @c byteBuffer(%d) does not have the size specified by" + "the @c width(%d), @c height(%d), and @c format(%d).", + GetErrorMessage(E_INVALID_ARG), byteBuffer.GetLimit(), resolution.width, resolution.height, bytePerPixel); + + return __pFaceRecognizerImpl->DetectBlinksFromBitmapN(byteBuffer, resolution, format); + +CATCH: + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* +FaceRecognizer::DetectBlinksFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::PixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* pList = null; + + pList = GetSupportedFormatListN(); + SysTryCatch(NID_UIX, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult())); + + SysTryCatch(NID_UIX, (pList->Contains(format) == true), r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format is invalid." + , GetErrorMessage(E_INVALID_ARG)); + + pList->RemoveAll(); + delete pList; + pList = null; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + // Below check routine includes the Pixelformat. Therefore it is checked after verifying format is valid. + if (format == Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR) + { + bytePerPixel = 1.5f; + } + else if (format == Tizen::Graphics::PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + !(Float::Compare((float) byteBuffer.GetLimit(), (float) (resolution.width * resolution.height * bytePerPixel))), r = E_INVALID_ARG, + E_INVALID_ARG, "[%s] The specified @c byteBuffer(%d) does not have the size specified by the @c width(%d), @c height(%d), and" + "@c format(%d).", GetErrorMessage(E_INVALID_ARG), byteBuffer.GetLimit(), resolution.width, resolution.height, bytePerPixel); + + return __pFaceRecognizerImpl->DetectBlinksFromBufferN(byteBuffer, resolution, format); +CATCH: + if (pList != null) + { + pList->RemoveAll(); + delete pList; + pList = null; + } + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* +FaceRecognizer::RecognizeExpressionsFromStillImageN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN< format&& Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX > format, r = + E_INVALID_ARG, E_INVALID_ARG, + "[%s] The specified @c format is not supported.", GetErrorMessage(E_INVALID_ARG)); + + SysTryCatch(NID_UIX, (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888) || (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565), + r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format(%d) is invalid.", GetErrorMessage(E_INVALID_ARG), format); + + if (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888) + { + bytePerPixel = 4.0f; + } + else if (format == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + !(Float::Compare((float) byteBuffer.GetLimit(), (float) (resolution.width * resolution.height * bytePerPixel))), r = E_INVALID_ARG, + E_INVALID_ARG, "[%s] The specified @c byteBuffer(%d) does not have the size specified by the @c width(%d), @c height(%d), and" + "@c format(%d).", GetErrorMessage(E_INVALID_ARG), byteBuffer.GetLimit(), resolution.width, resolution.height, bytePerPixel); + + return __pFaceRecognizerImpl->RecognizeExpressionsFromBitmapN(byteBuffer, resolution, format); +CATCH: + SetLastResult(r); + return null; +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* +FaceRecognizer::RecognizeExpressionsFromVideoStreamN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::PixelFormat format) +{ + SysAssertf(__pFaceRecognizerImpl != null, "Not yet constructed. Construct() should be called before use."); + + ClearLastResult(); + result r = E_SUCCESS; + float bytePerPixel = 0.0f; + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* pList = null; + + pList = GetSupportedFormatListN(); + SysTryCatch(NID_UIX, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult())); + + SysTryCatch(NID_UIX, (pList->Contains(format) == true), r = E_INVALID_ARG, E_INVALID_ARG, "[%s] A specified format is invalid.", + GetErrorMessage(E_INVALID_ARG)); + + pList->RemoveAll(); + delete pList; + pList = null; + + SysTryCatch(NID_UIX, 0 < resolution.width, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The width of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + SysTryCatch(NID_UIX, 0 < resolution.height, r = E_INVALID_ARG, E_INVALID_ARG, + "[%s] The height of the resolution should be greater than 0.", GetErrorMessage(E_INVALID_ARG)); + + // Below check routine includes the Pixelformat. Therefore it is checked after verifying format is valid. + if (format == Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR) + { + bytePerPixel = 1.5f; + } + else if (format == Tizen::Graphics::PIXEL_FORMAT_RGB565) + { + bytePerPixel = 2.0f; + } + + SysTryCatch(NID_UIX, + !(Float::Compare((float) byteBuffer.GetLimit(), (float) (resolution.width * resolution.height * bytePerPixel))), r = E_INVALID_ARG, + E_INVALID_ARG, "[%s] The specified @c byteBuffer(%d) does not have the size specified by the @c width(%d), @c height(%d), and" + " @c format(%d).", GetErrorMessage(E_INVALID_ARG), byteBuffer.GetLimit(), resolution.width, resolution.height, bytePerPixel); + + return __pFaceRecognizerImpl->RecognizeExpressionsFromBufferN(byteBuffer, resolution, format); +CATCH: + if (pList != null) + { + pList->RemoveAll(); + delete pList; + pList = null; + } + SetLastResult(r); + return null; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVision_FaceDetectorImpl.cpp b/src/FUixVision_FaceDetectorImpl.cpp new file mode 100644 index 0000000..229802d --- /dev/null +++ b/src/FUixVision_FaceDetectorImpl.cpp @@ -0,0 +1,761 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceDetectorImpl.cpp + * @brief This file contains internal implementation of FaceDetector class. + * + * + * This file contains the internal implementation of FaceDetector class. + */ + +#include +#include "FUixVision_FaceDetectorImpl.h" + +using namespace Tizen::Base; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Collection; + +namespace Tizen { namespace Uix { namespace Vision +{ +long _FaceDetectorImpl::__maxFacesAtomic = 5; +long _FaceDetectorImpl::__scaleAtomic = 1; + +static const int _MAX_FD_VIDEO_DEFAULT = 1; +static const int _MAX_FD_IMAGE_DEFAULT = 5; +static const int _MAX_FD_VIDEO_MAXNUM = 5; +static const int _MAX_FD_IMAGE_MAXNUM = 10; +static const int _MIN_FD_VIDEO_MAXNUM = 1; +static const int _MIN_FD_IMAGE_MAXNUM = 1; +static const int _FD_SCALE_VIDEO_DEFAULT = 1; +static const int _FD_SCALE_IMAGE_DEFAULT = 1; +static const int _MAX_FD_SCALE_VIDEO = 3; +static const int _MAX_FD_SCALE_IMAGE = 3; +static const int _MIN_FD_SCALE_VIDEO = 1; +static const int _MIN_FD_SCALE_IMAGE = 1; +static const int _FT_INTERVAL_DEFAULT = 20; +static const int _FACEENGINE_INIT_SUCCESS = 1; +static const int _FACEENGINE_RETURN_SUCCESS = 1; + + +_FaceDetectorImpl::_FaceDetectorImpl(void) + : __maxFacesVideo(0) + , __scaleVideo(0) + , __maxFacesImage(0) + , __scaleImage(0) + , __isTrackingMode(false) + , __pFaceEngineInfo(null) + , __pFaceUtil(null) + , __prevDetectMode(__FACEDETECT_MODE_UNINITIALIZED) +{ +} + +_FaceDetectorImpl::~_FaceDetectorImpl(void) +{ + //Tracking mode does not release the resources + ReleaseFaceEngine(); + + delete __pFaceEngineInfo; + delete __pFaceUtil; +} + +bool +_FaceDetectorImpl::ToBeInitialized(FaceDetectMode currMode) +{ + if (__prevDetectMode == currMode) + { + return false; + } + + ReleaseFaceEngine(); + + __prevDetectMode = currMode; + + return true; +} + +bool +_FaceDetectorImpl::ReleaseFaceEngine() +{ + if (__prevDetectMode != __FACEDETECT_MODE_UNINITIALIZED) + { + int retValue = caApp_FaceEngineRelease(__pFaceEngineInfo); + SysTryReturn(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, false, E_FAILURE, + "[%s] Failed to release face engine", GetErrorMessage(E_FAILURE)); + } + __prevDetectMode = __FACEDETECT_MODE_UNINITIALIZED; + + return true; +} + +result +_FaceDetectorImpl::Construct(void) +{ + result r = E_SUCCESS; + long min = 0; + long max = 0; + long steppingDelta = 0; + + GetRange(FACEDETECTOR_MAXNUMBER_VIDEO, min, max, steppingDelta, __maxFacesVideo); + GetRange(FACEDETECTOR_MAXNUMBER_IMAGE, min, max, steppingDelta, __maxFacesImage); + GetRange(FACEDETECTOR_SCALE_VIDEO, min, max, steppingDelta, __scaleVideo); + GetRange(FACEDETECTOR_SCALE_IMAGE, min, max, steppingDelta, __scaleImage); + GetRange(FACEDETECTOR_MAXNUMBER_FACES, min, max, steppingDelta, __maxFacesAtomic); + GetRange(FACEDETECTOR_SCALE_FACTOR, min, max, steppingDelta, __scaleAtomic); + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfo(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< _FaceUtil > pFaceUtil(new (std::nothrow) _FaceUtil); + SysTryReturn(NID_UIX, pFaceUtil != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceEngineInfo = pFaceEngineInfo.release(); + __pFaceUtil = pFaceUtil.release(); + + return r; +} + +result +_FaceDetectorImpl::GetRange(FaceDetectorConfigProperty configProperty, long& min, long& max, long& steppingDelta, + long& defaultVal) const +{ + result res = E_SUCCESS; + + switch (configProperty) + { + case FACEDETECTOR_MAXNUMBER_VIDEO: + { + min = _MIN_FD_VIDEO_MAXNUM; + max = _MAX_FD_VIDEO_MAXNUM; + steppingDelta = 1; + defaultVal = _MAX_FD_VIDEO_DEFAULT; + } + break; + + case FACEDETECTOR_MAXNUMBER_IMAGE: + { + min = _MIN_FD_IMAGE_MAXNUM; + max = _MAX_FD_IMAGE_MAXNUM; + steppingDelta = 1; + defaultVal = _MAX_FD_IMAGE_DEFAULT; + } + break; + + case FACEDETECTOR_SCALE_VIDEO: + { + min = _MIN_FD_SCALE_VIDEO; + max = _MAX_FD_SCALE_VIDEO; + defaultVal = _FD_SCALE_VIDEO_DEFAULT; + steppingDelta = 1; + } + break; + + case FACEDETECTOR_SCALE_IMAGE: + { + min = _MIN_FD_SCALE_IMAGE; + max = _MAX_FD_SCALE_IMAGE; + defaultVal = _FD_SCALE_IMAGE_DEFAULT; + steppingDelta = 1; + } + break; + + case FACEDETECTOR_MAXNUMBER_FACES: + { + min = _MIN_FD_IMAGE_MAXNUM; + max = _MAX_FD_IMAGE_MAXNUM; + steppingDelta = 1; + defaultVal = _MAX_FD_IMAGE_DEFAULT; + } + break; + + case FACEDETECTOR_SCALE_FACTOR: + { + min = _MIN_FD_SCALE_IMAGE; + max = _MAX_FD_SCALE_IMAGE; + steppingDelta = 1; + defaultVal = _FD_SCALE_IMAGE_DEFAULT; + } + break; + + default: + { + min = 0; + max = 0; + steppingDelta = 1; + defaultVal = 0; + SysTryReturn(NID_UIX, false, E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + break; + } + } + + return res; +} + +long +_FaceDetectorImpl::GetProperty(FaceDetectorConfigProperty configProperty) const +{ + ClearLastResult(); + switch (configProperty) + { + case FACEDETECTOR_MAXNUMBER_VIDEO: + return __maxFacesVideo; + + case FACEDETECTOR_MAXNUMBER_IMAGE: + return __maxFacesImage; + + case FACEDETECTOR_SCALE_VIDEO: + return __scaleVideo; + + case FACEDETECTOR_SCALE_IMAGE: + return __scaleImage; + + case FACEDETECTOR_MAXNUMBER_FACES: + return __maxFacesAtomic; + + case FACEDETECTOR_SCALE_FACTOR: + return __scaleAtomic; + + default: + SetLastResult(E_UNSUPPORTED_OPERATION); + SysTryReturn(NID_UIX, false, -1, -1, "[%s] The device does not support this property.", GetErrorMessage(E_UNSUPPORTED_OPERATION)); + break; + } + return (long) -1; +} + +result +_FaceDetectorImpl::SetProperty(FaceDetectorConfigProperty configProperty, long value) +{ + long min = 0; + long max = 0; + long steppingDelta = 0; + long defaultVal = 0; + + GetRange(configProperty, min, max, steppingDelta, defaultVal); + SysTryReturn(NID_UIX, value >= min && value <= max && value % steppingDelta == 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, + "[%s] The specified value (%d) is out of range.", GetErrorMessage(E_OUT_OF_RANGE), value); + + switch (configProperty) + { + case FACEDETECTOR_MAXNUMBER_VIDEO: + __maxFacesVideo = value; + break; + + case FACEDETECTOR_MAXNUMBER_IMAGE: + __maxFacesImage = value; + break; + + case FACEDETECTOR_SCALE_VIDEO: + __scaleVideo = value; + break; + + case FACEDETECTOR_SCALE_IMAGE: + __scaleImage = value; + break; + + case FACEDETECTOR_MAXNUMBER_FACES: + __maxFacesAtomic = value; + break; + + case FACEDETECTOR_SCALE_FACTOR: + __scaleAtomic = value; + break; + + default: + SysTryReturn(NID_UIX, false, E_UNSUPPORTED_OPERATION, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + break; + } + + return E_SUCCESS; +} + +Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* +_FaceDetectorImpl::GetSupportedFormatListN(void) const +{ + std::unique_ptr< Tizen::Base::Collection::LinkedListT< Tizen::Graphics::PixelFormat >, CollectionAllElementDelete > + pFormatList(new (std::nothrow) Tizen::Base::Collection::LinkedListT< Tizen::Graphics::PixelFormat >); + SysTryReturn(NID_UIX, pFormatList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + pFormatList->InsertAt(Tizen::Graphics::PIXEL_FORMAT_RGB565, 0); + pFormatList->InsertAt(Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR, 0); + + return pFormatList.release(); +} + +Tizen::Base::Collection::IList* +_FaceDetectorImpl::DetectFacesFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + result r = E_SUCCESS; + int retValue = 0; + unsigned char* pImageBuffer = null; + Tizen::Graphics::Rectangle* pRect = null; + + ClearLastResult(); + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Failed to allocate memory", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryCatch(NID_UIX, pBuffer != null, r = E_OUT_OF_MEMORY, r = E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + if (format == PIXEL_FORMAT_YCbCr420_PLANAR) + { + pImageBuffer = (unsigned char*) byteBuffer.GetPointer(); + } + else if (format == PIXEL_FORMAT_RGB565) + { + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, r = E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACEDETECT_MODE_VIDEO)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesVideo, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, r = E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, r = E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + if (__pFaceEngineInfo->g_iFaceDetectNum > 0) + { + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + pRect = + new (std::nothrow) Tizen::Graphics::Rectangle(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + SysTryCatch(NID_UIX, pRect != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Add(*pRect); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + } + } + + return pDetectList.release(); + +CATCH: + if (pRect != null) + { + delete pRect; + } + SetLastResult(r); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +Tizen::Base::Collection::IList* +_FaceDetectorImpl::DetectFacesFromBitmapN(const Tizen::Graphics::Bitmap& bitmap) +{ + result r = E_SUCCESS; + BufferInfo bitmapInfo; + unsigned char* pImageBuffer = null; + int retValue = 0; + Tizen::Graphics::Rectangle* pRect = null; + + ClearLastResult(); + + r = const_cast< Tizen::Graphics::Bitmap* >(&bitmap)->Lock(bitmapInfo); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[bitmapInfo.width * bitmapInfo.height]); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryCatch(NID_UIX, pDetectList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + if (bitmapInfo.pixelFormat == PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) bitmapInfo.pPixels), pImageBuffer, bitmapInfo.width, bitmapInfo.height); + } + else if (bitmapInfo.pixelFormat == PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) bitmapInfo.pPixels), pImageBuffer, bitmapInfo.width, bitmapInfo.height); + } + + if (ToBeInitialized(__FACEDETECT_MODE_IMAGE)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, bitmapInfo.width, bitmapInfo.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + if (__pFaceEngineInfo->g_iFaceDetectNum > 0) + { + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + //The null assingment is to avoid possible memory leak + pRect = null; + pRect = + new (std::nothrow) Tizen::Graphics::Rectangle(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + SysTryCatch(NID_UIX, pRect != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceUtil->ConvertVirtualToPhysicalCoordinates(bitmap.GetWidth(), bitmap.GetHeight(), bitmapInfo.width, bitmapInfo.height, pRect); + + r = pDetectList->Add(*pRect); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + } + } + + r = const_cast< Tizen::Graphics::Bitmap* >(&bitmap)->Unlock(); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + ReleaseFaceEngine(); + + return pDetectList.release(); + +CATCH: + if (pRect) + { + delete pRect; + } + ReleaseFaceEngine(); + SetLastResult(r); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +Tizen::Base::Collection::IList* +_FaceDetectorImpl::DetectFacesFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + ClearLastResult(); + result r = E_SUCCESS; + int retValue = 0; + unsigned char* pImageBuffer = null; + Tizen::Graphics::Rectangle* pRect = null; + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryCatch(NID_UIX, pDetectList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + if (format == BITMAP_PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + else if (format == BITMAP_PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACEDETECT_MODE_IMAGE)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + if (__pFaceEngineInfo->g_iFaceDetectNum > 0) + { + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + //The null assingment is to avoid possible memory leak + pRect = null; + pRect = + new (std::nothrow) Tizen::Graphics::Rectangle(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + SysTryCatch(NID_UIX, pRect != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Add(*pRect); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + } + } + + ReleaseFaceEngine(); + + return pDetectList.release(); + +CATCH: + if (pRect) + { + delete pRect; + } + SetLastResult(r); + ReleaseFaceEngine(); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +Tizen::Base::ByteBuffer* +_FaceDetectorImpl::ConvertToGrayN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::PixelFormat format) +{ + result r = E_SUCCESS; + ClearLastResult(); + int capacity = 0; + + std::unique_ptr< Tizen::Base::ByteBuffer > pGrayBuf(new (std::nothrow) Tizen::Base::ByteBuffer()); + SysTryReturn(NID_UIX, pGrayBuf != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + capacity = byteBuffer.GetCapacity(); + r = pGrayBuf->Construct(capacity); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + switch (format) + { + case PIXEL_FORMAT_RGB565: + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), (unsigned char*) pGrayBuf->GetPointer(), + resolution.width, resolution.height); + break; + + case PIXEL_FORMAT_ARGB8888: + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) byteBuffer.GetPointer()), (unsigned char*) pGrayBuf->GetPointer(), + resolution.width, resolution.height); + break; + + case PIXEL_FORMAT_YCbCr420_PLANAR: + memcpy((unsigned char*)(pGrayBuf->GetPointer()), (unsigned char*)(byteBuffer.GetPointer()), capacity); + break; + + default: + break; + } + + return pGrayBuf.release(); +} + + +Tizen::Base::Collection::IList* +_FaceDetectorImpl::DetectFacesN(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, + FaceDetectionOption mode) +{ + int retValue = 0; + result r = E_SUCCESS; + unsigned char* pImageBuffer = null; + Tizen::Graphics::Rectangle* pRect = null; + + ClearLastResult(); + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + pImageBuffer = (unsigned char*) grayBuffer.GetPointer(); + + if (ToBeInitialized(__FACEDETECT_MODE_IMAGE)) + { + if (mode == FACE_DETECTION_OPTION_FAST) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesAtomic, __scaleAtomic); + } + else + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLo_YAWo, FD_SIZE_COVERAGE_HIGH, __maxFacesAtomic, __scaleAtomic); + } + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + if (__pFaceEngineInfo->g_iFaceDetectNum > 0) + { + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + //The null assingment is to avoid possible memory leak + pRect = null; + pRect = + new (std::nothrow) Tizen::Graphics::Rectangle(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + SysTryCatch(NID_UIX, pRect != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Add(*pRect); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + } + } + + ReleaseFaceEngine(); + return pDetectList.release(); +CATCH: + if (pRect) + { + delete pRect; + } + SetLastResult(r); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +result +_FaceDetectorImpl::ExtractFaceComponents(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point& eyeRight, + Tizen::Graphics::Point& eyeLeft, Tizen::Graphics::Rectangle& mouthRect) +{ + result r = E_SUCCESS; + int retVal = 0; + FaceEngineInfo* pFaceEngineInfo = null; + + unsigned char* pImageBuffer = (unsigned char*) grayBuffer.GetPointer(); + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfoTemp(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfoTemp != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to allocate memory.", GetErrorMessage(E_OUT_OF_MEMORY)); + + pFaceEngineInfo = pFaceEngineInfoTemp.get(); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to allocate memory.", GetErrorMessage(E_OUT_OF_MEMORY)); + + ReleaseFaceEngine(); + + retVal = caApp_FaceEngineInit(pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryReturn(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, E_FAILURE, E_FAILURE, "[%s] Face Engine Init failed.", GetErrorMessage(E_FAILURE)); + + pFaceEngineInfo->g_iFaceDetectNum = 1; + pFaceEngineInfo->g_FaceROI[0].x = faceRect.x; + pFaceEngineInfo->g_FaceROI[0].y = faceRect.y; + pFaceEngineInfo->g_FaceROI[0].width = faceRect.width; + pFaceEngineInfo->g_FaceROI[0].height = faceRect.height; + + retVal = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, pFaceEngineInfo, 0); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_OPERATION_FAILED, r = E_OPERATION_FAILED, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OPERATION_FAILED)); + + retVal = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, pFaceEngineInfo, 0); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_OPERATION_FAILED, r = E_OPERATION_FAILED, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OPERATION_FAILED)); + + SysTryCatch(NID_UIX, ((pFaceEngineInfo->g_EyeROI[0].lx >= 0) && (pFaceEngineInfo->g_EyeROI[0].ly >= 0) && + (pFaceEngineInfo->g_EyeROI[0].rx >= 0) && (pFaceEngineInfo->g_EyeROI[0].ry >= 0)), + r = E_OPERATION_FAILED, r = E_OPERATION_FAILED, "[%s] Failed to create the Buffer.", GetErrorMessage(E_OPERATION_FAILED)); + + + SysTryCatch(NID_UIX, ((pFaceEngineInfo->g_MouthROI[0].x >= 0) && (pFaceEngineInfo->g_MouthROI[0].y >= 0) && + (pFaceEngineInfo->g_MouthROI[0].width > 0) && (pFaceEngineInfo->g_MouthROI[0].height > 0)), + r = E_OPERATION_FAILED, r = E_OPERATION_FAILED, "[%s] Failed to create the Buffer.", GetErrorMessage(E_FAILURE)); + + + retVal = caApp_RunBlinkDetection(pImageBuffer, resolution.width, resolution.height, pFaceEngineInfo, true); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_OPERATION_FAILED, r = E_OPERATION_FAILED, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OPERATION_FAILED)); + + + eyeLeft.x = pFaceEngineInfo->g_EyeROI[0].lx; + eyeLeft.y = pFaceEngineInfo->g_EyeROI[0].ly; + eyeRight.x = pFaceEngineInfo->g_EyeROI[0].rx; + eyeRight.y = pFaceEngineInfo->g_EyeROI[0].ry; + + mouthRect.x = pFaceEngineInfo->g_MouthROI[0].x; + mouthRect.y = pFaceEngineInfo->g_MouthROI[0].y; + mouthRect.width = pFaceEngineInfo->g_MouthROI[0].width; + mouthRect.height = pFaceEngineInfo->g_MouthROI[0].height; + + caApp_FaceEngineRelease(pFaceEngineInfo); + return E_SUCCESS; +CATCH: + caApp_FaceEngineRelease(pFaceEngineInfo); + return r; +} + + +result +_FaceDetectorImpl::GetPosDifference(const Tizen::Base::ByteBuffer& prevGrayBuffer, const Tizen::Base::ByteBuffer& curGrayBuffer, + const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, + Tizen::Graphics::Point& posDiff) +{ + caFaceROI ROI = {0, 0, 0, 0}; + int move_width = 0; + int move_height = 0; + int retVal = 0; + result r = E_SUCCESS; + + __isTrackingMode = true; + + ROI.x = faceRect.x; + ROI.y = faceRect.y; + ROI.width = faceRect.width; + ROI.height = faceRect.height; + + + retVal = caApp_TraceRegion((unsigned char*) prevGrayBuffer.GetPointer(), (unsigned char*) curGrayBuffer.GetPointer(), + ROI, resolution.width, resolution.height, &move_width, &move_height); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Failed to create the Buffer.", GetErrorMessage(E_OPERATION_FAILED)); + + posDiff.x = move_width; + posDiff.y = move_height; + + return E_SUCCESS; + +CATCH: + return r; +} + + +_FaceDetectorImpl* +_FaceDetectorImpl::GetInstance(FaceDetector* pFaceDetector) +{ + return pFaceDetector->__pFaceDetectorImpl; +} + +const _FaceDetectorImpl* +_FaceDetectorImpl::GetInstance(const FaceDetector* pFaceDetector) +{ + return pFaceDetector->__pFaceDetectorImpl; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVision_FaceDetectorImpl.h b/src/FUixVision_FaceDetectorImpl.h new file mode 100644 index 0000000..77937b0 --- /dev/null +++ b/src/FUixVision_FaceDetectorImpl.h @@ -0,0 +1,290 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceDetectorImpl.h + * @brief This file contains declaration of FUixVision_FaceDetectorImpl class. + * + * + * This header file contains the declarations of the FUixVision_FaceDetectorImpl class. + */ + +#ifndef _FUIX_VISION_INTERNAL_FACEDETECTOR_IMPL_H_ +#define _FUIX_VISION_INTERNAL_FACEDETECTOR_IMPL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caFaceAPP_interface.h" +#include "FUixVision_FaceUtil.h" + +struct CollectionAllElementDelete +{ + template< typename Collection > + void operator ()(Collection* c) + { + c->RemoveAll(); + delete c; + } +}; + +namespace Tizen { namespace Uix { namespace Vision +{ + +class _FaceDetectorImpl + : public Tizen::Base::Object +{ + + typedef enum + { + __FACEDETECT_MODE_UNINITIALIZED = 0x100, + __FACEDETECT_MODE_IMAGE, + __FACEDETECT_MODE_VIDEO, + }FaceDetectMode; + +public: + /** + * This is the default constructor for this class. + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 1.0 + */ + _FaceDetectorImpl(void); + + /** + * This is the destructor for this class. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 1.0 + */ + virtual ~_FaceDetectorImpl(void); + + /** + * Initializes this instance of FaceDetector. + * + * @return An error code + * @exception E_SUCCESS The method was successful. + * @exception E_OUT_OF_MEMORY Insufficient memory. + * @since 1.0 + */ + result Construct(void); + + /** + * Retrieves the range and default value of a specified configuration property. + * + * @return The error code. + * @param[in] configProperty Specifies the property to query. + * @param[out] min Receives the minimum value of the property. + * @param[out] max Receives the maximun value of the property. + * @param[out] steppingDelta Receives the step size for the property. The step size is the smallest increment by which the property can change. + * @param[out] defaultVal Receives the default value of the property. + * @exception E_SUCCESS - This method is successful. + * @exception E_UNSUPPORTED_OPERATION - The device does not support this property. + */ + result GetRange(FaceDetectorConfigProperty configProperty, long& min, long& max, long& steppingDelta, long& defaultVal) const; + + /** + * Retrieves the current setting of a specified configuration property. + * + * @return The value of the property. + * @param[in] configProperty Specifies the property to query. + * @exception E_SUCCESS - This method is successful. + * @exception E_UNSUPPORTED_OPERATION - The device does not support this property. + */ + long GetProperty(FaceDetectorConfigProperty configProperty) const; + + /** + * Sets the value of a specified property. + * + * @return The error code. + * @param[in] configProperty Specifies the property to query. + * @param[in] value Specifes the new value of the property. + * @exception E_SUCCESS - This method is successful. + * @exception E_UNSUPPORTED_OPERATION - The device does not support this property. + * @exception E_OUT_OF_RANGE - The specified value is out of range. + * @see GetRange + */ + result SetProperty(FaceDetectorConfigProperty configProperty, long value); + + /** + * Retrieves the supported format list. + * + * @return The list of the supported pixel format. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + */ + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* GetSupportedFormatListN(void) const; + + /** + * Searches for faces from a video image. + * + * @return The the list of detected faces' position. + * @param[in] byteBuffer Specifies the pointer pointing to the buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] format Specifies the format of input image. This should be one of the supported formats. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + */ + Tizen::Base::Collection::IList* DetectFacesFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::PixelFormat format); + + /** + * Detects faces from still image. + * + * @return The the list of detected faces' position. + * @param[in] bitmap Specifies the bitmap file containing the input image data. + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + */ + Tizen::Base::Collection::IList* DetectFacesFromBitmapN(const Tizen::Graphics::Bitmap& bitmap); + + /** + * Detects faces from still image. + * + * @return The the list of detected faces' position. + * @param[in] byteBuffer Specifies the pointer pointing to the buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] format The color format defined by Tizen::Graphics::BitmapPixelFormat @n + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + */ + Tizen::Base::Collection::IList* DetectFacesFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, Tizen::Graphics::BitmapPixelFormat format); + + /** + * Convert input image data to the gray scale. + * + * @return The gray scale data. + * @param[in] byteBuffer Specifies the buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] format The color format defined by Tizen::Graphics::PixelFormat @n + * + * @exception E_SUCCESS The method was successful. + * @exception E_OUT_OF_MEMORY Insufficient memory. + * + * @since 2.0 + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::ByteBuffer* ConvertToGrayN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, Tizen::Graphics::PixelFormat format); + + /** + * Searches faces. + * + * @return The list of the detected face positions @n + * Each list's item has a pointer of Tizen::Graphics::Rectangle value. @n + * An empty list, if there are no detected faces and there is no error @n + * The faces are not detected when the faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @c null, if an exception occurs. @n + * @param[in] grayBuffer Specifies the grayscale buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] mode Specifies the detection mode. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * + * @since 2.0 + * @remarks The specific error code can be accessed using the GetLastResult() method. + */ + Tizen::Base::Collection::IList* DetectFacesN(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, FaceDetectionOption mode); + + /** + * Extracts eye position. + * + * @return An error code + * @param[in] grayBuffer Specifies the grayscale buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] faceRect The face position + * @param[out] eyeRight The right eye position to be detected + * @param[out] eyeLeft The left eye position to be detected + * @param[out] mouthRect The mouth position + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @exception E_OPERATION_FAILED There are no extracted eye position. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @since 2.0 + */ + result ExtractFaceComponents(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point& eyeRight, Tizen::Graphics::Point& eyeLeft, Tizen::Graphics::Rectangle& mouthRect); + + /** + * Tracks the interest region. + * + * @return An error code + * @param[in] prevGrayBuffer The previous buffer containing the input image data + * @param[in] curGrayBuffer The current buffer containing the input image data + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] faceRect The region which want to be traced.@n + * @param[out] posDiff The offset wich are moved from previous to current image. + * + * @exception E_SUCCESS The method was successful. + * @exception E_OPERATION_FAILED Failed to track the specified region. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @since 2.0 + */ + result GetPosDifference(const Tizen::Base::ByteBuffer& prevGrayBuffer, const Tizen::Base::ByteBuffer& curGrayBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point& posDiff); + + static _FaceDetectorImpl* GetInstance(FaceDetector* pFaceDetector); + static const _FaceDetectorImpl* GetInstance(const FaceDetector* pFaceDetector); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceDetectorImpl(const _FaceDetectorImpl& value); + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceDetectorImpl& operator =(const _FaceDetectorImpl& value); + + void ConvertArgb8888ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertRgb565ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertVirtualToPhysicalCoordinates(int bitmapWidth, int bitmapHeight, int bufferWidth, int bufferHeight, Tizen::Graphics::Rectangle* pRect); + result Initilize(int initMode, FaceDetectionOption detectMode); + result Release(void); + bool ToBeInitialized(FaceDetectMode currMode); + bool ReleaseFaceEngine(); + + friend class _FaceRecognizerImpl; + +private: + static long __maxFacesAtomic; + static long __scaleAtomic; + long __maxFacesVideo; + long __scaleVideo; + long __maxFacesImage; + long __scaleImage; + bool __isTrackingMode; + FaceEngineInfo* __pFaceEngineInfo; + _FaceUtil* __pFaceUtil; + FaceDetectMode __prevDetectMode; +}; + +} } } //Tizen::Uix::Vision + +#endif diff --git a/src/FUixVision_FaceRecognizerImpl.cpp b/src/FUixVision_FaceRecognizerImpl.cpp new file mode 100644 index 0000000..b65a6c1 --- /dev/null +++ b/src/FUixVision_FaceRecognizerImpl.cpp @@ -0,0 +1,1295 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceRecognizerImpl.cpp + * @brief This file contains internal implementation of FaceRecognizer Implementation class. + * + * + * This file contains internal implementation of FaceRecognizer Implementation class. + */ + +#include +#include +#include +#include +#include "FUixVision_FaceRecognizerImpl.h" +#include "FUixVision_FaceDetectorImpl.h" + +using namespace Tizen::Base; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Collection; + +namespace Tizen { namespace Uix { namespace Vision +{ +static const int _FR_MAXNUM_VIDEO_DEFAULT = 1; +static const int _FR_MAXNUM_IMAGE_DEFAULT = 10; +static const int _FR_MAXNUM_VIDEO_MAX = 5; +static const int _FR_MAXNUM_IMAGE_MAX = 10; +static const int _FR_MAXNUM_VIDEO_MIN = 1; +static const int _FR_MAXNUM_IMAGE_MIN = 1; +static const int _FR_SCALE_VIDEO_DEFAULT = 3; +static const int _FR_SCALE_IMAGE_DEFAULT = 1; +static const int _FR_SCALE_VIDEO_MAX = 3; +static const int _FR_SCALE_IMAGE_MAX = 3; +static const int _FR_SCALE_VIDEO_MIN = 1; +static const int _FR_SCALE_IMAGE_MIN = 1; + +static const int _FT_INTERVAL_DEFAULT = 20; +static const int _FACEENGINE_INIT_SUCCESS = 1; +static const int _FACEENGINE_RETURN_SUCCESS = 1; +static char _FACE_ENGINE_BIN_PATH[] = "/usr/share/face-engine/data/"; + +class _RectHashCodeProvider + : public IHashCodeProviderT< Tizen::Graphics::Rectangle > +{ +public: + _RectHashCodeProvider(void) {} + virtual ~_RectHashCodeProvider(void) {} + + int GetHashCode(const Tizen::Graphics::Rectangle& obj) const + { + return obj.x; + } +}; + +class _RectComparerT + : public virtual IComparerT< Tizen::Graphics::Rectangle > + , public Object +{ +public: + _RectComparerT(void) {} + virtual ~_RectComparerT(void) {} + result Compare(const Tizen::Graphics::Rectangle& obj1, const Tizen::Graphics::Rectangle& obj2, int& cmp) const + { + if (obj1 == obj2) + { + cmp = 0; + return E_SUCCESS; + } + else + { + cmp = -1; + return E_INVALID_ARG; + } + } +}; + +result +_FaceRecognizerImpl::Construct(void) +{ + long min = 0; + long max = 0; + long steppingDelta = 0; + result res = E_SUCCESS; + + GetRange(FACERECOGNIZER_MAXNUMBER_VIDEO, min, max, steppingDelta, __maxFacesVideo); + GetRange(FACERECOGNIZER_MAXNUMBER_IMAGE, min, max, steppingDelta, __maxFacesImage); + GetRange(FACERECOGNIZER_SCALE_VIDEO, min, max, steppingDelta, __scaleVideo); + GetRange(FACERECOGNIZER_SCALE_IMAGE, min, max, steppingDelta, __scaleImage); + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfo(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< _FaceUtil > pFaceUtil(new (std::nothrow) _FaceUtil); + SysTryReturn(NID_UIX, pFaceUtil != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceEngineInfo = pFaceEngineInfo.release(); + __pFaceUtil = pFaceUtil.release(); + + return res; +} + +_FaceRecognizerImpl::_FaceRecognizerImpl(void) + : __scaleVideo(0) + , __scaleImage(0) + , __maxFacesVideo(0) + , __maxFacesImage(0) + , __pFaceEngineInfo(null) + , __pFaceUtil(null) + , __prevRecognizeMode(__FACERECOGNIZE_MODE_UNINITIALIZED) +{ + +} + +_FaceRecognizerImpl::~_FaceRecognizerImpl(void) +{ + ReleaseFaceEngine(); + + delete __pFaceEngineInfo; + delete __pFaceUtil; +} + +bool +_FaceRecognizerImpl::ToBeInitialized(FaceRecognizeMode currMode) +{ + if (__prevRecognizeMode == currMode) + { + return false; + } + + ReleaseFaceEngine(); + + __prevRecognizeMode = currMode; + + return true; +} + +bool +_FaceRecognizerImpl::ReleaseFaceEngine() +{ + if (__prevRecognizeMode != __FACERECOGNIZE_MODE_UNINITIALIZED) + { + int retValue = caApp_FaceEngineRelease(__pFaceEngineInfo); + SysTryReturn(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, false, E_FAILURE, + "[%s] Failed to release face engine", GetErrorMessage(E_FAILURE)); + } + + __prevRecognizeMode = __FACERECOGNIZE_MODE_UNINITIALIZED; + + return true; +} + +result +_FaceRecognizerImpl::GetRange(FaceRecognizerConfigProperty configProperty, long& min, long& max, long& steppingDelta, + long& defaultVal) const +{ + result res = E_SUCCESS; + + switch (configProperty) + { + case FACERECOGNIZER_MAXNUMBER_VIDEO: + { + min = _FR_MAXNUM_VIDEO_MIN; + max = _FR_MAXNUM_VIDEO_MAX; + steppingDelta = 1; + defaultVal = _FR_MAXNUM_VIDEO_DEFAULT; + } + break; + + case FACERECOGNIZER_MAXNUMBER_IMAGE: + { + min = _FR_MAXNUM_IMAGE_MIN; + max = _FR_MAXNUM_IMAGE_MAX; + steppingDelta = 1; + defaultVal = _FR_MAXNUM_IMAGE_DEFAULT; + } + break; + + case FACERECOGNIZER_SCALE_VIDEO: + { + min = _FR_SCALE_VIDEO_MIN; + max = _FR_SCALE_VIDEO_MAX; + defaultVal = _FR_SCALE_VIDEO_DEFAULT; + steppingDelta = 1; + } + break; + + case FACERECOGNIZER_SCALE_IMAGE: + { + min = _FR_SCALE_IMAGE_MIN; + max = _FR_SCALE_IMAGE_MAX; + defaultVal = _FR_SCALE_IMAGE_DEFAULT; + steppingDelta = 1; + } + break; + + default: + { + min = 0; + max = 0; + steppingDelta = 1; + defaultVal = 0; + SysLogException(NID_UIX, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + return E_UNSUPPORTED_OPERATION; + } + break; + } + + return res; +} + +long +_FaceRecognizerImpl::GetProperty(FaceRecognizerConfigProperty configProperty) const +{ + ClearLastResult(); + switch (configProperty) + { + case FACERECOGNIZER_MAXNUMBER_VIDEO: + return __maxFacesVideo; + + case FACERECOGNIZER_MAXNUMBER_IMAGE: + return __maxFacesImage; + + case FACERECOGNIZER_SCALE_VIDEO: + return __scaleVideo; + + case FACERECOGNIZER_SCALE_IMAGE: + return __scaleImage; + + default: + { + SysLogException(NID_UIX, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + } + break; + } + return long(-1); +} + +result +_FaceRecognizerImpl::SetProperty(FaceRecognizerConfigProperty configProperty, long value) +{ + long min = 0; + long max = 0; + long steppingDelta = 0; + long defaultVal = 0; + result res = E_SUCCESS; + + //configProperty is always available. Becuase this is checked before calling this function. + res = GetRange(configProperty, min, max, steppingDelta, defaultVal); + SysTryReturn(NID_UIX, value >= min && value <= max && value % steppingDelta == 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, + "[%s] The specified value (%d) is out of range.", GetErrorMessage(E_OUT_OF_RANGE), value); + + switch (configProperty) + { + case FACERECOGNIZER_MAXNUMBER_VIDEO: + __maxFacesVideo = value; + break; + + case FACERECOGNIZER_MAXNUMBER_IMAGE: + __maxFacesImage = value; + break; + + case FACERECOGNIZER_SCALE_VIDEO: + __scaleVideo = value; + break; + + case FACERECOGNIZER_SCALE_IMAGE: + __scaleImage = value; + break; + + default: + SysLogException(NID_UIX, E_UNSUPPORTED_OPERATION, "[%s] The device does not support this property.", + GetErrorMessage(E_UNSUPPORTED_OPERATION)); + return E_UNSUPPORTED_OPERATION; + } + + return res; +} + +Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* +_FaceRecognizerImpl::GetSupportedFormatListN(void) const +{ + std::unique_ptr< Tizen::Base::Collection::LinkedListT< Tizen::Graphics::PixelFormat >, CollectionAllElementDeleter > + pFormatList(new (std::nothrow) Tizen::Base::Collection::LinkedListT< Tizen::Graphics::PixelFormat >); + SysTryReturn(NID_UIX, pFormatList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", + GetErrorMessage(E_OUT_OF_MEMORY)); + + pFormatList->InsertAt(Tizen::Graphics::PIXEL_FORMAT_RGB565, 0); + pFormatList->InsertAt(Tizen::Graphics::PIXEL_FORMAT_YCbCr420_PLANAR, 0); + + return pFormatList.release(); +} + +Tizen::Base::Collection::IList* +_FaceRecognizerImpl::ExtractFaceFeaturesFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + ClearLastResult(); + + result r = E_SUCCESS; + int retValue = 0; + int featureLength = 0; + unsigned char* pImageBuffer = null; + ByteBuffer buffer; + + std::unique_ptr< FaceRecognitionInfo > pFaceInfo; + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", + GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + if (format == PIXEL_FORMAT_YCbCr420_PLANAR) + { + pImageBuffer = (unsigned char*) byteBuffer.GetPointer(); + } + else if (format == PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_VIDEO_FACE)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesVideo, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retValue = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retValue = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExInit(FR_MODE_MPL2, _FACE_ENGINE_BIN_PATH); + + featureLength = caApp_FtsExVecLength(); + SysTryCatch(NID_UIX, featureLength > 0, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + long* pFaceData = caApp_FtsExGetFeatureVector(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, pFaceData != null, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + r = buffer.Construct(featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct Bytebuffer.", GetErrorMessage(r)); + + r = buffer.SetArray((byte*) pFaceData, 0, featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to set the array.", GetErrorMessage(r)); + + pFaceInfo = std::unique_ptr< FaceRecognitionInfo >(new (std::nothrow) FaceRecognitionInfo); + SysTryCatch(NID_UIX, pFaceInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to allocate Memory.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pFaceInfo->Construct(buffer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct the FaceRecognitionInfo.", GetErrorMessage(r)); + + pFaceInfo->SetFacePosition(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(*(pFaceInfo.release())); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = E_FAILURE, r, "[%s] Failed to add the FaceRecognitionInfo.", GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExRelease(); + + return pDetectList.release(); + +CATCH: + SetLastResult(r); + caApp_FtsExRelease(); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +Tizen::Base::Collection::IList* +_FaceRecognizerImpl::ExtractFaceFeaturesFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + ClearLastResult(); + + result r = E_SUCCESS; + unsigned char* pImageBuffer = null; + int retValue = 0; + int featureLength = 0; + + std::unique_ptr< FaceRecognitionInfo > pFaceInfo; + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", + GetErrorMessage(E_OUT_OF_MEMORY)); + r = pDetectList->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryCatch(NID_UIX, pBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer.", GetErrorMessage(E_OUT_OF_MEMORY)); + + if (format == BITMAP_PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + else if (format == BITMAP_PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_IMAGE_FACE)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retValue = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retValue = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExInit(FR_MODE_MPL2, _FACE_ENGINE_BIN_PATH); + + featureLength = caApp_FtsExVecLength(); + SysTryCatch(NID_UIX, featureLength > 0, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + long* pFaceData = caApp_FtsExGetFeatureVector(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, pFaceData != null, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + ByteBuffer buffer; + r = buffer.Construct(featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct Bytebuffer.", GetErrorMessage(r)); + + r = buffer.SetArray((byte*) pFaceData, 0, featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to set the array.", GetErrorMessage(r)); + + pFaceInfo = std::unique_ptr< FaceRecognitionInfo >(new (std::nothrow) FaceRecognitionInfo); + SysTryCatch(NID_UIX, pFaceInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to allocate memory.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pFaceInfo->Construct(buffer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct the FaceRecognitionInfo.", GetErrorMessage(E_FAILURE)); + + pFaceInfo->SetFacePosition(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(*(pFaceInfo.release())); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = E_FAILURE, r, "[%s] Failed to add the FaceRecognitionInfo.", GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExRelease(); + ReleaseFaceEngine(); + return pDetectList.release(); + +CATCH: + SetLastResult(r); + caApp_FtsExRelease(); + ReleaseFaceEngine(); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +Tizen::Base::Collection::IList* +_FaceRecognizerImpl::ExtractFaceFeaturesFromBitmapN(const Tizen::Graphics::Bitmap& bitmap) +{ + ClearLastResult(); + result r = E_SUCCESS; + unsigned char* pImageBuffer = null; + int retValue = 0; + int featureLength = 0; + std::unique_ptr< FaceRecognitionInfo > pFaceInfo; + + BufferInfo bitmapInfo; + + r = const_cast< Tizen::Graphics::Bitmap* >(&bitmap)->Lock(bitmapInfo); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pDetectList(new (std::nothrow) Tizen::Base::Collection::ArrayList()); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + r = pDetectList->Construct(); + SysTryReturn(NID_UIX, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[bitmapInfo.width * bitmapInfo.height]); + SysTryCatch(NID_UIX, pBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + pImageBuffer = pBuffer.get(); + + if (bitmapInfo.pixelFormat == PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) bitmapInfo.pPixels), pImageBuffer, bitmapInfo.width, bitmapInfo.height); + } + else if (bitmapInfo.pixelFormat == PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) bitmapInfo.pPixels), pImageBuffer, bitmapInfo.width, bitmapInfo.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_IMAGE_FACE)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, bitmapInfo.width, bitmapInfo.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retValue = caApp_RunEyeDetection(pImageBuffer, bitmapInfo.width, bitmapInfo.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retValue = caApp_RunMouthDetection(pImageBuffer, bitmapInfo.width, bitmapInfo.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExInit(FR_MODE_MPL2, _FACE_ENGINE_BIN_PATH); + + featureLength = caApp_FtsExVecLength(); + SysTryCatch(NID_UIX, featureLength > 0, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + long* pFaceData = caApp_FtsExGetFeatureVector(pImageBuffer, bitmapInfo.width, bitmapInfo.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, pFaceData != null, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + ByteBuffer buffer; + r = buffer.Construct(featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct Bytebuffer.", GetErrorMessage(r)); + + r = buffer.SetArray((byte*) pFaceData, 0, featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to set the array.", GetErrorMessage(r)); + + pFaceInfo = std::unique_ptr< FaceRecognitionInfo >(new (std::nothrow) FaceRecognitionInfo); + SysTryCatch(NID_UIX, pFaceInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pFaceInfo->Construct(buffer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Failed to construct the FaceRecognitionInfo.", GetErrorMessage(r)); + + Tizen::Graphics::Rectangle* pRect = + new (std::nothrow) Tizen::Graphics::Rectangle(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + SysTryCatch(NID_UIX, pRect != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceUtil->ConvertVirtualToPhysicalCoordinates(bitmap.GetWidth(), bitmap.GetHeight(), bitmapInfo.width, bitmapInfo.height, pRect); + + pFaceInfo->SetFacePosition(pRect->x, pRect->y, pRect->width, pRect->height); + + delete pRect; + + r = pDetectList->Add(*(pFaceInfo.release())); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = E_FAILURE, r, "[%s] Failed to add the FaceRecognitionInfo.", GetErrorMessage(E_FAILURE)); + } + + caApp_FtsExRelease(); + + r = const_cast< Tizen::Graphics::Bitmap* >(&bitmap)->Unlock(); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(r)); + + ReleaseFaceEngine(); + return pDetectList.release(); +CATCH: + SetLastResult(r); + caApp_FtsExRelease(); + ReleaseFaceEngine(); + pDetectList->RemoveAll(true); + return pDetectList.release(); +} + +int +_FaceRecognizerImpl::MeasureSimilarity(const Tizen::Base::ByteBuffer& face1, const Tizen::Base::ByteBuffer& face2) +{ + ClearLastResult(); + + caApp_FtsExInit(FR_MODE_MPL2, _FACE_ENGINE_BIN_PATH); + + long similarityVal = caApp_FtsExCompareFeatureVector((long*) face1.GetPointer(), (long*) face2.GetPointer()); + + caApp_FtsExRelease(); + return (int) (((float) similarityVal / 1023) * 100); +} + +bool +_FaceRecognizerImpl::IsMatching(const Tizen::Base::ByteBuffer& face1, const Tizen::Base::ByteBuffer& face2) +{ + if (MeasureSimilarity(face1, face2) > 65) + { + return true; + } + else + { + return false; + } +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* +_FaceRecognizerImpl::DetectBlinksFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + ClearLastResult(); + result r = E_SUCCESS; + unsigned char* pImageBuffer = null; + int retVal = 0; + + IHashCodeProviderT< Tizen::Graphics::Rectangle >* pRectProvider = null; + std::unique_ptr< _RectHashCodeProvider > pUniqRectProvider(new (std::nothrow) _RectHashCodeProvider); + SysTryReturn(NID_UIX, pUniqRectProvider != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + IComparerT< Tizen::Graphics::Rectangle >* pRectComparer = null; + std::unique_ptr< _RectComparerT > pUniqRectComparer(new (std::nothrow) _RectComparerT); + SysTryReturn(NID_UIX, pUniqRectComparer != null, null, E_OUT_OF_MEMORY, + "[%s] Failed to create _RectComparerT.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::HashMapT< Tizen::Graphics::Rectangle, EyeState >, CollectionAllElementDeleter > + pDetectList(new (std::nothrow) HashMapT< Tizen::Graphics::Rectangle, EyeState >); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryCatch(NID_UIX, pBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer.", + GetErrorMessage(E_OUT_OF_MEMORY)); + + pRectProvider = pUniqRectProvider.get(); + SysTryCatch(NID_UIX, pRectProvider != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + pRectComparer = pUniqRectComparer.get(); + SysTryCatch(NID_UIX, pRectComparer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(0, 0, *pRectProvider, *pRectComparer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + + if (format == BITMAP_PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + else if (format == BITMAP_PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_IMAGE_FACE)) + { + retVal = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retVal = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retVal = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retVal = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retVal = caApp_RunBlinkDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, true); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + EyeState eyeState; + + if (*(__pFaceEngineInfo->g_Blink[i]) == 0) + { + eyeState = EYE_STATE_BOTH_OPEN; + } + else if (*(__pFaceEngineInfo->g_Blink[i]) == 3) + { + eyeState = EYE_STATE_BOTH_CLOSED; + } + else + { + eyeState = EYE_STATE_NONE; + } + + Rectangle rect(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(rect, eyeState); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + } + + ReleaseFaceEngine(); + + return pDetectList.release(); + +CATCH: + SetLastResult(r); + ReleaseFaceEngine(); + pDetectList->RemoveAll(); + return pDetectList.release(); +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* +_FaceRecognizerImpl::RecognizeExpressionsFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + Tizen::Graphics::BitmapPixelFormat format) +{ + ClearLastResult(); + result r = E_SUCCESS; + + int retVal = 0; + unsigned char* pImageBuffer = null; + + IHashCodeProviderT< Tizen::Graphics::Rectangle >* pRectProvider = null; + std::unique_ptr< _RectHashCodeProvider > pUniqRectProvider(new (std::nothrow) _RectHashCodeProvider); + SysTryReturn(NID_UIX, pUniqRectProvider != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + IComparerT< Tizen::Graphics::Rectangle >* pRectComparer = null; + std::unique_ptr< _RectComparerT > pUniqRectComparer(new (std::nothrow) _RectComparerT); + SysTryReturn(NID_UIX, pUniqRectComparer != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::HashMapT< Tizen::Graphics::Rectangle, FacialExpression >, CollectionAllElementDeleter > + pDetectList(new (std::nothrow) HashMapT< Tizen::Graphics::Rectangle, FacialExpression >); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryCatch(NID_UIX, pBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer.", + GetErrorMessage(E_OUT_OF_MEMORY)); + + pRectProvider = pUniqRectProvider.get(); + SysTryCatch(NID_UIX, pRectProvider != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + pRectComparer = pUniqRectComparer.get(); + SysTryCatch(NID_UIX, pRectComparer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(0, 0, *pRectProvider, *pRectComparer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + + if (format == BITMAP_PIXEL_FORMAT_RGB565) + { + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + else if (format == BITMAP_PIXEL_FORMAT_ARGB8888) + { + __pFaceUtil->ConvertArgb8888ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_IMAGE_FACE)) + { + retVal = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retVal = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retVal = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retVal = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retVal = caApp_RunFERDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, true); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + FacialExpression expression = FACIAL_EXPRESSION_NONE; + + switch (*(__pFaceEngineInfo->g_Expression[i])) + { + case FACE_EXPRESSION_NUETRAL: + expression = FACIAL_EXPRESSION_NEUTRAL; + break; + + case FACE_EXPRESSION_ANGRY: + expression = FACIAL_EXPRESSION_ANGRY; + break; + + case FACE_EXPRESSION_SMILE: + expression = FACIAL_EXPRESSION_HAPPY; + break; + + case FACE_EXPRESSION_SURPRISE: + expression = FACIAL_EXPRESSION_SURPRISED; + break; + + case FACE_EXPRESSION_UNKNOWN: + expression = FACIAL_EXPRESSION_NONE; + break; + + default: + break; + } + Rectangle rect(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(rect, expression); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + } + + ReleaseFaceEngine(); + + return pDetectList.release(); + +CATCH: + ReleaseFaceEngine(); + SetLastResult(r); + pDetectList->RemoveAll(); + return pDetectList.release(); +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* +_FaceRecognizerImpl::DetectBlinksFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + ClearLastResult(); + result r = E_SUCCESS; + int retValue = 0; + unsigned char* pImageBuffer = null; + + IHashCodeProviderT< Tizen::Graphics::Rectangle >* pRectProvider = null; + std::unique_ptr< _RectHashCodeProvider > pUniqRectProvider(new (std::nothrow) _RectHashCodeProvider); + SysTryReturn(NID_UIX, pUniqRectProvider != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + IComparerT< Tizen::Graphics::Rectangle >* pRectComparer = null; + std::unique_ptr< _RectComparerT > pUniqRectComparer(new (std::nothrow) _RectComparerT); + SysTryReturn(NID_UIX, pUniqRectComparer != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::HashMapT< Tizen::Graphics::Rectangle, EyeState >, CollectionAllElementDeleter > + pDetectList(new (std::nothrow) HashMapT< Tizen::Graphics::Rectangle, EyeState >); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + pRectProvider = pUniqRectProvider.get(); + SysTryCatch(NID_UIX, pRectProvider != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + pRectComparer = pUniqRectComparer.get(); + SysTryCatch(NID_UIX, pRectComparer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(0, 0, *pRectProvider, *pRectComparer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + + if (format == PIXEL_FORMAT_YCbCr420_PLANAR) + { + pImageBuffer = (unsigned char*) byteBuffer.GetPointer(); + } + else if (format == PIXEL_FORMAT_RGB565) + { + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_VIDEO_BLINK)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesVideo, _FT_INTERVAL_DEFAULT); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retValue = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retValue = caApp_RunBlinkDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, true); + //retValue = caApp_RunBlinkDetectionSingleFace(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i, true); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + EyeState eyeState; + + if (*(__pFaceEngineInfo->g_Blink[i]) == 0) + { + eyeState = EYE_STATE_BOTH_OPEN; + } + else if (*(__pFaceEngineInfo->g_Blink[i]) == 3) + { + eyeState = EYE_STATE_BOTH_CLOSED; + } + else + { + eyeState = EYE_STATE_NONE; + } + + Rectangle rect(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(rect, eyeState); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + } + + return pDetectList.release(); +CATCH: + pDetectList->RemoveAll(); + SetLastResult(r); + return pDetectList.release(); +} + +Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* +_FaceRecognizerImpl::RecognizeExpressionsFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, + const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::PixelFormat format) +{ + static bool ExpressionStateFirst = true; + ClearLastResult(); + result r = E_SUCCESS; + int retValue = 0; + unsigned char* pImageBuffer = null; + + IHashCodeProviderT< Tizen::Graphics::Rectangle >* pRectProvider = null; + std::unique_ptr< _RectHashCodeProvider > pUniqRectProvider(new (std::nothrow) _RectHashCodeProvider); + SysTryReturn(NID_UIX, pUniqRectProvider != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + IComparerT< Tizen::Graphics::Rectangle >* pRectComparer = null; + std::unique_ptr< _RectComparerT > pUniqRectComparer(new (std::nothrow) _RectComparerT); + SysTryReturn(NID_UIX, pUniqRectComparer != null, null, E_OUT_OF_MEMORY, + "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< Tizen::Base::Collection::HashMapT< Tizen::Graphics::Rectangle, FacialExpression >, CollectionAllElementDeleter > + pDetectList(new (std::nothrow) HashMapT< Tizen::Graphics::Rectangle, FacialExpression >); + SysTryReturn(NID_UIX, pDetectList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", + GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< unsigned char[] > pBuffer(new (std::nothrow) unsigned char[resolution.width * resolution.height]); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed." + , GetErrorMessage(E_OUT_OF_MEMORY)); + + pRectProvider = pUniqRectProvider.get(); + SysTryCatch(NID_UIX, pRectProvider != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + pRectComparer = pUniqRectComparer.get(); + SysTryCatch(NID_UIX, pRectComparer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, + "[%s] Failed to create the IMapT.", GetErrorMessage(E_OUT_OF_MEMORY)); + + r = pDetectList->Construct(0, 0, *pRectProvider, *pRectComparer); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + + if (format == PIXEL_FORMAT_YCbCr420_PLANAR) + { + pImageBuffer = (unsigned char*) byteBuffer.GetPointer(); + } + else if (format == PIXEL_FORMAT_RGB565) + { + pImageBuffer = pBuffer.get(); + SysTryCatch(NID_UIX, pImageBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_OUT_OF_MEMORY)); + __pFaceUtil->ConvertRgb565ToGray(*((unsigned char*) byteBuffer.GetPointer()), pImageBuffer, resolution.width, resolution.height); + } + + if (ToBeInitialized(__FACERECOGNIZE_MODE_VIDEO_BLINK)) + { + retValue = caApp_FaceEngineInit(__pFaceEngineInfo, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesVideo, 25); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + ExpressionStateFirst = false; + } + + retValue = caApp_RunFaceDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + for (int i = 0; i < __pFaceEngineInfo->g_iFaceDetectNum; i++) + { + retValue = caApp_RunEyeDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + retValue = caApp_RunMouthDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, i); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + retValue = caApp_RunFERDetection(pImageBuffer, resolution.width, resolution.height, __pFaceEngineInfo, true); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + FacialExpression expression = FACIAL_EXPRESSION_NONE; + + switch (*(__pFaceEngineInfo->g_Expression[i])) + { + case EXP_NUETRAL: + expression = FACIAL_EXPRESSION_NEUTRAL; + break; + + case EXP_ANGRY: + expression = FACIAL_EXPRESSION_ANGRY; + break; + + case EXP_SMILE: + expression = FACIAL_EXPRESSION_HAPPY; + break; + + case EXP_SURPRISE: + expression = FACIAL_EXPRESSION_SURPRISED; + break; + + default: + expression = FACIAL_EXPRESSION_NONE; + break; + } + + Rectangle rect(__pFaceEngineInfo->g_FaceROI[i].x, __pFaceEngineInfo->g_FaceROI[i].y, + __pFaceEngineInfo->g_FaceROI[i].width, __pFaceEngineInfo->g_FaceROI[i].height); + + r = pDetectList->Add(rect, expression); + SysTryCatch(NID_UIX, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r)); + } + + return pDetectList.release(); + +CATCH: + pDetectList->RemoveAll(); + SetLastResult(r); + return pDetectList.release(); +} + +Tizen::Base::ByteBuffer* +_FaceRecognizerImpl::ExtractFeatureN(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point eyeLeft, + Tizen::Graphics::Point eyeRight) +{ + ClearLastResult(); + result r = E_SUCCESS; + int featureLength = 0; + int retValue = 0; + long* pFaceData = null; + FaceEngineInfo* __pFaceEngineInfoTemp = null; + + std::unique_ptr< ByteBuffer > pBuffer(new (std::nothrow) Tizen::Base::ByteBuffer()); + SysTryReturn(NID_UIX, pBuffer != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfo(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, null, E_OUT_OF_MEMORY, "[%s] Failed to create the Buffer.", GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceEngineInfoTemp = pFaceEngineInfo.get(); + SysTryReturn(NID_UIX, __pFaceEngineInfoTemp != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + retValue = caApp_FaceEngineInit(__pFaceEngineInfoTemp, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH, __maxFacesImage, 20); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + __pFaceEngineInfoTemp->g_FaceROI[0].x = faceRect.x; + __pFaceEngineInfoTemp->g_FaceROI[0].y = faceRect.y; + __pFaceEngineInfoTemp->g_FaceROI[0].width = faceRect.width; + __pFaceEngineInfoTemp->g_FaceROI[0].height = faceRect.height; + __pFaceEngineInfoTemp->g_EyeROI[0].lx = eyeLeft.x; + __pFaceEngineInfoTemp->g_EyeROI[0].ly = eyeLeft.y; + __pFaceEngineInfoTemp->g_EyeROI[0].rx = eyeRight.x; + __pFaceEngineInfoTemp->g_EyeROI[0].ry = eyeRight.y; + + caApp_FtsExInit(FR_MODE_MPL2, _FACE_ENGINE_BIN_PATH); + + featureLength = caApp_FtsExVecLength(); + SysTryCatch(NID_UIX, featureLength > 0, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + pFaceData = caApp_FtsExGetFeatureVector((unsigned char*) grayBuffer.GetPointer(), resolution.width, resolution.height, __pFaceEngineInfoTemp, 0); + SysTryCatch(NID_UIX, pFaceData != null, r = E_FAILURE, E_FAILURE, "[%s] Failed caApp_FtsExInit", GetErrorMessage(E_FAILURE)); + + r = pBuffer->Construct(featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = E_FAILURE, r, "[%s] Failed to construct Bytebuffer.", GetErrorMessage(E_FAILURE)); + + r = pBuffer->SetArray((byte*) pFaceData, 0, featureLength * sizeof(long)); + SysTryCatch(NID_UIX, r == E_SUCCESS, r = E_FAILURE, r, "[%s] Failed to set the array.", GetErrorMessage(E_FAILURE)); + + caApp_FtsExRelease(); + + retValue = caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SysTryCatch(NID_UIX, retValue == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to delete FaceEngine.", GetErrorMessage(E_FAILURE)); + + return pBuffer.release(); + +CATCH: + caApp_FtsExRelease(); + caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SetLastResult(r); + return null; +} + +EyeState +_FaceRecognizerImpl::DetectEyeState(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point& eyeLeft, + Tizen::Graphics::Point& eyeRight) +{ + ClearLastResult(); + result r = E_SUCCESS; + EyeState eyeState = EYE_STATE_NONE; + int retVal = 0; + FaceEngineInfo* __pFaceEngineInfoTemp = null; + + //Way to get the index is to loop for all rects and get the index.. + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfo(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, eyeState, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + __pFaceEngineInfoTemp = pFaceEngineInfo.get(); + SysTryReturn(NID_UIX, __pFaceEngineInfoTemp != null, eyeState, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + retVal = caApp_FaceEngineInit(__pFaceEngineInfoTemp, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH,__maxFacesImage, 20); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + __pFaceEngineInfoTemp->g_FaceROI[0].x = faceRect.x; + __pFaceEngineInfoTemp->g_FaceROI[0].y = faceRect.y; + __pFaceEngineInfoTemp->g_FaceROI[0].width = faceRect.width; + __pFaceEngineInfoTemp->g_FaceROI[0].height = faceRect.height; + + __pFaceEngineInfoTemp->g_EyeROI[0].lx = eyeLeft.x; + __pFaceEngineInfoTemp->g_EyeROI[0].ly = eyeLeft.y; + __pFaceEngineInfoTemp->g_EyeROI[0].rx = eyeRight.x; + __pFaceEngineInfoTemp->g_EyeROI[0].ry = eyeRight.y; + + retVal = caApp_RunBlinkDetection((unsigned char*) grayBuffer.GetPointer(), resolution.width, resolution.height, __pFaceEngineInfoTemp, true); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + if (*(__pFaceEngineInfoTemp->g_Blink[0]) == 0) + { + eyeState = EYE_STATE_BOTH_OPEN; + } + else if (*(__pFaceEngineInfoTemp->g_Blink[0]) == 3) + { + eyeState = EYE_STATE_BOTH_CLOSED; + } + else + { + eyeState = EYE_STATE_NONE; + } + + retVal = caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to delete FaceEngine.", GetErrorMessage(E_FAILURE)); + + return eyeState; + +CATCH: + caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SetLastResult(r); + return EYE_STATE_NONE; +} + +FacialExpression +_FaceRecognizerImpl::RecognizeExpression(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, + const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Rectangle& mouthRect) +{ + ClearLastResult(); + result r = E_SUCCESS; + int retVal = 0; + FacialExpression expression = FACIAL_EXPRESSION_NONE; + FaceEngineInfo* __pFaceEngineInfoTemp = null; + + std::unique_ptr< FaceEngineInfo > pFaceEngineInfo(new (std::nothrow) FaceEngineInfo); + SysTryReturn(NID_UIX, pFaceEngineInfo != null, expression, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + __pFaceEngineInfoTemp = pFaceEngineInfo.get(); + SysTryReturn(NID_UIX, __pFaceEngineInfoTemp != null, expression, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + retVal = caApp_FaceEngineInit(__pFaceEngineInfoTemp, FD_MODE_ROLx_YAWx, FD_SIZE_COVERAGE_HIGH,__maxFacesImage, 20); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + __pFaceEngineInfoTemp->g_FaceROI[0].x = faceRect.x; + __pFaceEngineInfoTemp->g_FaceROI[0].y = faceRect.y; + __pFaceEngineInfoTemp->g_FaceROI[0].width = faceRect.width; + __pFaceEngineInfoTemp->g_FaceROI[0].height = faceRect.height; + + __pFaceEngineInfoTemp->g_MouthROI[0].x = mouthRect.x; + __pFaceEngineInfoTemp->g_MouthROI[0].y = mouthRect.y; + __pFaceEngineInfoTemp->g_MouthROI[0].width = mouthRect.width; + __pFaceEngineInfoTemp->g_MouthROI[0].height = mouthRect.height; + + retVal = caApp_RunFERDetection((unsigned char*) grayBuffer.GetPointer(), resolution.width, resolution.height, __pFaceEngineInfoTemp, true); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_RETURN_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to create the Buffer." + , GetErrorMessage(E_FAILURE)); + + switch (*(__pFaceEngineInfoTemp->g_Expression[0])) + { + case FACE_EXPRESSION_NUETRAL: + expression = FACIAL_EXPRESSION_NEUTRAL; + break; + + case FACE_EXPRESSION_ANGRY: + expression = FACIAL_EXPRESSION_ANGRY; + break; + + case FACE_EXPRESSION_SMILE: + expression = FACIAL_EXPRESSION_HAPPY; + break; + + case FACE_EXPRESSION_SURPRISE: + expression = FACIAL_EXPRESSION_SURPRISED; + break; + + case FACE_EXPRESSION_UNKNOWN: + expression = FACIAL_EXPRESSION_NONE; + break; + + default: + break; + } + + retVal = caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SysTryCatch(NID_UIX, retVal == _FACEENGINE_INIT_SUCCESS, r = E_FAILURE, E_FAILURE, "[%s] Failed to delete FaceEngine.", GetErrorMessage(E_FAILURE)); + + return expression; +CATCH: + caApp_FaceEngineRelease(__pFaceEngineInfoTemp); + SetLastResult(r); + return FACIAL_EXPRESSION_NONE; +} + + +_FaceRecognizerImpl* +_FaceRecognizerImpl::GetInstance(FaceRecognizer* pFaceRecognizer) +{ + return pFaceRecognizer->__pFaceRecognizerImpl; +} + +const _FaceRecognizerImpl* +_FaceRecognizerImpl::GetInstance(const FaceRecognizer* pFaceRecognizer) +{ + return pFaceRecognizer->__pFaceRecognizerImpl; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVision_FaceRecognizerImpl.h b/src/FUixVision_FaceRecognizerImpl.h new file mode 100644 index 0000000..efd20bd --- /dev/null +++ b/src/FUixVision_FaceRecognizerImpl.h @@ -0,0 +1,363 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceRecognizerImpl.h + * @brief This file contains declaration of the FUixVision_FaceRecognizerImpl class. + * + * + * This header file contains the declarations of the FUixVision_FaceRecognizerImpl class. + */ + +#ifndef _FUIX_VISION_INTERNAL_FACE_RECOGNIZER_IMPL_H_ +#define _FUIX_VISION_INTERNAL_FACE_RECOGNIZER_IMPL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caFaceAPP_interface.h" +#include "FUixVision_FaceUtil.h" + +struct CollectionAllElementDeleter +{ + template< typename Collection > + void operator ()(Collection* c) + { + c->RemoveAll(); + delete c; + } +}; + +namespace Tizen { namespace Uix { namespace Vision +{ + +typedef enum +{ + __FACERECOGNIZE_MODE_UNINITIALIZED = 0x100, + __FACERECOGNIZE_MODE_IMAGE_FACE, + __FACERECOGNIZE_MODE_VIDEO_FACE, + __FACERECOGNIZE_MODE_VIDEO_BLINK, + __FACERECOGNIZE_MODE_VIDEO_EXPRESSION +}FaceRecognizeMode; + +class _FaceRecognizerImpl + : public Tizen::Base::Object +{ + +public: + /** + * This is the default constructor for this class. + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 2.0 + */ + _FaceRecognizerImpl(void); + + /** + * This is the destructor for this class. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~_FaceRecognizerImpl(void); + + result Construct(void); + + /** + * Retrieves the supported format list. + * + * @return The list of the supported pixel format. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + */ + Tizen::Base::Collection::IListT< Tizen::Graphics::PixelFormat >* GetSupportedFormatListN(void) const; + + /** + * Extracts the facial template that represents the face from the video image. + * + * @return The list of the FaceRecognitionInfo objects which contain the extracted facial features. + * @param[in] byteBuffer Specifies the pointer pointing to the buffer containing the input image data. + * @param[in] resolution Specifies the width and height of the input image. + * @param[in] format Specifies the format of input image. This should be one of the supported formats. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + * @see FaceRecognitionInfo + */ + Tizen::Base::Collection::IList* ExtractFaceFeaturesFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::PixelFormat format); + + /** + * Extracts the facial template that represents the face from the still image. + * + * @return The list of the FaceInfo objects which contain the extracted facial features. + * @param[in] bitmap Specifies the bitmap file containing the input image data. + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + * @see FaceRecognitionInfo + */ + Tizen::Base::Collection::IList* ExtractFaceFeaturesFromBitmapN(const Tizen::Graphics::Bitmap& bitmap); + + /** + * Extracts the facial template that represents the face from the still image. + * + * @return The list of the FaceRecognitionInfo objects which contain the extracted facial features. + * @param[in] byteBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] format The color format defined by Tizen::Graphics:: BitmapPixelFormat @n + * @exception E_SUCCESS - This method is successful. + * @exception E_OUT_OF_MEMORY - Failed to allocate required/requested memory. + * @see FaceRecognitionInfo + */ + Tizen::Base::Collection::IList* ExtractFaceFeaturesFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, Tizen::Graphics::BitmapPixelFormat format); + + /** + * Recognizes whether two given faces are matching or not. + * + * @return The result of match, if two faces are matching it return true; otherwise false. + * @param[in] face1 Specifies the face features of the first face. + * @param[in] face2 Specifies the face features of the second face. + * @see FaceRecognitionInfo + */ + bool IsMatching(const Tizen::Base::ByteBuffer& face1, const Tizen::Base::ByteBuffer& face2); + + /** + * Get the similarity of the two specified faces. + * + * @return The similarity. + * @param[in] face1 Specifies the face features of the first face. + * @param[in] face2 Specifies the face features of the second face. + * @exception E_SUCCESS - This method is successful. + */ + int MeasureSimilarity(const Tizen::Base::ByteBuffer& face1, const Tizen::Base::ByteBuffer& face2); + + + /** + * Retrieves the range and default value of a specified configuration property. + * + * @return The error code. + * @param[in] configProperty Specifies the property to query. + * @param[out] min Receives the minimum value of the property. + * @param[out] max Receives the maximun value of the property. + * @param[out] steppingDelta Receives the step size for the property. The step size is the smallest increment by which the property can change. + * @param[out] defaultVal Receives the default value of the property. + * @exception E_SUCCESS This method is successful. + * @exception E_INVALID_ARG The device does not support this property. + */ + result GetRange(FaceRecognizerConfigProperty configProperty, long& min, long& max, long& steppingDelta, long& defaultVal) const; + + /** + * Retrieves the current setting of a specified configuration property. + * + * @return The value of the property. + * @param[in] configProperty Specifies the property to query. + * @exception E_SUCCESS This method is successful. + * @exception E_INVALID_ARG The device does not support this property. + */ + long GetProperty(FaceRecognizerConfigProperty configProperty) const; + + /** + * Sets the value for a specified property.. + * + * @return The error code. + * @param[in] configProperty Specifies the property to query. + * @param[in] value Specifes the new value of the property. + * @exception E_SUCCESS This method is successful. + * @exception E_INVALID_ARG The argument passed to a method contains an invalid value. @n + *   The @c value is out of range. @n + *   The @c configProperty is not supported property. + */ + result SetProperty(FaceRecognizerConfigProperty configProperty, long value); + + + /** + * Extracts the eye state from the still image. + * + * @return The list of eye state @n + * Each list's item has EyeState value. @n + * EYE_STATE_NONE, if there are no detected eye states and there is no error @n + * The eyes' states are not detected when the faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @c null, if an exception occurs. @n + * + * @param[in] byteBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] format The color format defined by Tizen::Graphics:: BitmapPixelFormat @n + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @see EyeState + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* DetectBlinksFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, Tizen::Graphics::BitmapPixelFormat format); + + + /** + * Extracts the eye state from the video image. + * + * @return The list of eye state @n + * Each list's item has EyeState value. @n + * EYE_STATE_NONE, if there are no detected eye states and there is no error @n + * The eyes' states are not detected when the faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @c null, if an exception occurs. @n + * + * @param[in] byteBuffer The buffer containing the input image data. + * @param[in] resolution The width and height of the input image @n + * @param[in] format Specifies the format of input image. This should be one of the supported formats. + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @see EyeState + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, EyeState >* DetectBlinksFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::PixelFormat format); + + /** + * Extracts the facial expression the face from the still image. + * + * @return The list of facial expression @n + * Each list's item has FacialExpression value. @n + * FACIAL_EXPRESSION_NONE, if there are no detected eye states and there is no error @n + * The expressions are not detected when the faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @c null, if an exception occurs. @n + * + * @param[in] byteBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] format The color format defined by Tizen::Graphics:: BitmapPixelFormat @n + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @see FacialExpression + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* RecognizeExpressionsFromBitmapN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, Tizen::Graphics::BitmapPixelFormat format); + + /** + * Extracts the facial expression from the video image. + * + * @return The list of facial expression @n + * Each list's item has FacialExpression value. @n + * FACIAL_EXPRESSION_NONE, if there are no detected eye states and there is no error @n + * The expressions are not recognized when the faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @c null, if an exception occurs. @n + * + * @param[in] byteBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] format Specifies the format of input image. This should be one of the supported formats. + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @see EyeState + */ + Tizen::Base::Collection::IMapT< Tizen::Graphics::Rectangle, FacialExpression >* RecognizeExpressionsFromBufferN(const Tizen::Base::ByteBuffer& byteBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::PixelFormat format); + + /** + * Extracts the facial template that represents the face + * + * @return The facial template that represents the face + * @c null, if an exception occurs. @n + * @param[in] grayBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] eyeRight The right eye position + * @param[in] eyeLeft The left eye position + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @exception E_OPERATION_FAILED There are no extracted facial information. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + */ + Tizen::Base::ByteBuffer* ExtractFeatureN(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, + Tizen::Graphics::Point eyeLeft, Tizen::Graphics::Point eyeRight); + + /** + * Extracts the eye state. + * + * @return The EyeState + * @c EYE_STATE_NONE, if an exception occurs. @n + * @param[in] grayBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] eyeRight The right eye position + * @param[in] eyeLeft The left eye position + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @exception E_OPERATION_FAILED There are no detected eye state. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @see EyeState + */ + EyeState DetectEyeState(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Point& eyeLeft, Tizen::Graphics::Point& eyeRight); + + /** + * Extracts the facial expression. + * + * @return The FacialExpression + * @c FACIAL_EXPRESSION_NONE, if an exception occurs. @n + * @param[in] grayBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] eyeRight The right eye position + * @param[in] eyeLeft The left eye position + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @exception E_OPERATION_FAILED There are no recognized facial expression. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + * @see FacialExpression + */ + FacialExpression RecognizeExpression(const Tizen::Base::ByteBuffer& grayBuffer, const Tizen::Graphics::Dimension& resolution, const Tizen::Graphics::Rectangle& faceRect, Tizen::Graphics::Rectangle& mouthRect); + + static _FaceRecognizerImpl* GetInstance(FaceRecognizer* pFaceRecognizer); + static const _FaceRecognizerImpl* GetInstance(const FaceRecognizer* pFaceRecognizer); + +private: + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceRecognizerImpl& operator =(const _FaceRecognizerImpl& faceImpl); + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceRecognizerImpl(const _FaceRecognizerImpl& faceImpl); + + void ConvertRgb565ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertArgb8888ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertVirtualToPhysicalCoordinates(int bitmapWidth, int bitmapHeight, int bufferWidth, int bufferHeight, Tizen::Graphics::Rectangle* pRect); + bool ToBeInitialized(FaceRecognizeMode currMode); + bool ReleaseFaceEngine(); + +private: + long __scaleVideo; + long __scaleImage; + long __maxFacesVideo; + long __maxFacesImage; + FaceEngineInfo* __pFaceEngineInfo; + _FaceUtil* __pFaceUtil; + FaceRecognizeMode __prevRecognizeMode; +}; + +} } } //Tizen::Uix::Vision +#endif diff --git a/src/FUixVision_FaceUtil.cpp b/src/FUixVision_FaceUtil.cpp new file mode 100644 index 0000000..cde82e0 --- /dev/null +++ b/src/FUixVision_FaceUtil.cpp @@ -0,0 +1,144 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceUtil.cpp + * @brief This file contains internal implementation of FaceUtil Implementation class. + * + * + * This file contains internal implementation of FaceUtil Implementation class. + */ + +#include +#include +#include +#include +#include "FUixVision_FaceUtil.h" + +using namespace Tizen::Base; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Collection; + +namespace Tizen { namespace Uix { namespace Vision +{ + +result +_FaceUtil::Construct(void) +{ + return E_SUCCESS; +} + +_FaceUtil::_FaceUtil(void) +{ +} + +_FaceUtil::~_FaceUtil(void) +{ + +} + +void +_FaceUtil::ConvertRgb565ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned char* pDst = null; + unsigned char* pEnd = null; + unsigned short* pSrc = null; + + unsigned short r = 0; + unsigned short g = 0; + unsigned short b = 0; + long lt = 0; + + SysAssert(pGrayBuf != null); + if (pGrayBuf == null) + { + return; + } + + pSrc = (unsigned short*) &buf; + pDst = (unsigned char*) pGrayBuf; + pEnd = (unsigned char*) ((unsigned char*) pGrayBuf + height * width); + + while (pDst < pEnd) + { + r = (unsigned char) ((*pSrc >> 11) << 3); // R + g = (unsigned char) ((*pSrc & 0x07e0) >> 3); // +G + b = (unsigned char) ((*pSrc++ & 0x001f) << 3); // +B + + // Y = 0.299 R + 0.587 G + 0.114 B + lt = (306L * (long) r + 601L * (long) g + 117L * (long) b); + *pDst++ = (unsigned char) (lt >> 10); + //(BYTE)(((int)R+(int)G+(int)B) /3); + } +} + +void +_FaceUtil::ConvertArgb8888ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height) +{ + if (pGrayBuf == null) + { + return; + } + unsigned long* pSrc = (unsigned long*) &buf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + unsigned long r = (*pSrc >> 16) & 0xFF; + unsigned long g = (*pSrc >> 8) & 0xFF; + unsigned long b = (*pSrc++) & 0xFF; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} + +void +_FaceUtil::ConvertVirtualToPhysicalCoordinates(int bitmapWidth, int bitmapHeight, int bufferWidth, int bufferHeight, Tizen::Graphics::Rectangle* pRect) +{ + // no need to convert if both are same + if (bufferWidth == bitmapWidth || bufferHeight == bitmapHeight) + { + return; + } + + // Avoid 'division by zero' + if (bufferWidth <= 0 || bufferHeight <= 0) + { + return; + } + + // convert physical coordinate to virtual coordinate + int x1 = pRect->x; + int x2 = x1 + pRect->width; + int y1 = pRect->y; + int y2 = y1 + pRect->height; + + x1 = x1 * bitmapWidth / bufferWidth; + x2 = x2 * bitmapWidth / bufferWidth; + y1 = y1 * bitmapHeight / bufferHeight; + y2 = y2 * bitmapHeight / bufferHeight; + + pRect->x = x1; + pRect->y = y1; + pRect->width = x2 - x1; + pRect->height = y2 - y1; + + return; +} + +} } } //Tizen::Uix::Vision diff --git a/src/FUixVision_FaceUtil.h b/src/FUixVision_FaceUtil.h new file mode 100644 index 0000000..0b24d69 --- /dev/null +++ b/src/FUixVision_FaceUtil.h @@ -0,0 +1,119 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FUixVision_FaceUtil.h + * @brief This file contains declaration of the FUixVision_FaceUtil class. + * + * + * This header file contains the declarations of the FUixVision_FaceUtil class. + */ + +#ifndef _FUIX_VISION_INTERNAL_FACE_UTIL_H_ +#define _FUIX_VISION_INTERNAL_FACE_UTIL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Tizen { namespace Uix { namespace Vision +{ + +typedef enum +{ + FACE_EXPRESSION_UNKNOWN, + FACE_EXPRESSION_NUETRAL, /**< Normal expression */ + FACE_EXPRESSION_ANGRY, /**< Angry expression */ + FACE_EXPRESSION_SMILE, /**< Cheerful expression */ + FACE_EXPRESSION_SURPRISE, /**< Suprised expression */ +} face_engine_expression; + +/** + * @brief Enumerations of the eye state for the FacialEngine API. + */ +typedef enum +{ + FACE_EYE_UNKNOWN, /**< The no eye state, when the eye detect fails */ + FACE_EYE_OPENED, /**< The state when eye is opened */ + FACE_EYE_CLOSED, /**< The state when eye is closed */ +} face_engine_eye; + +class _FaceUtil + : public Tizen::Base::Object +{ + +public: + /** + * This is the default constructor for this class. + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + * + * @since 2.0 + */ + _FaceUtil(void); + + /** + * This is the destructor for this class. + * This destructor overrides Tizen::Base::Object::~Object(). + * + * @since 2.0 + */ + virtual ~_FaceUtil(void); + + result Construct(void); + + /** + * Extracts the facial template that represents the face + * + * @return The facial template that represents the face + * @c null, if an exception occurs. @n + * @param[in] grayBuffer The buffer containing the input image data + * @param[in] resolution The width and height of the input image @n + * @param[in] eyeRight The right eye position + * @param[in] eyeLeft The left eye position + * @exception E_SUCCESS This method is successful. + * @exception E_OUT_OF_MEMORY Failed to allocate required/requested memory. + * @exception E_FAILURE A system error occurred. + * @exception E_OPERATION_FAILED There are no extracted facial information. But there is no error @n + * It can be happened when the detected faces are too small or the image is not clear. @n + * This is the result of a normal operation. @n + */ + void ConvertRgb565ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertArgb8888ToGray(const unsigned char& buf, unsigned char* pGrayBuf, int width, int height); + void ConvertVirtualToPhysicalCoordinates(int bitmapWidth, int bitmapHeight, int bufferWidth, int bufferHeight, Tizen::Graphics::Rectangle* pRect); + +private: + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceUtil& operator =(const _FaceUtil& faceImpl); + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + _FaceUtil(const _FaceUtil& faceImpl); + +}; + +} } } //Tizen::Uix::Vision +#endif diff --git a/src/caBasicDef.h b/src/caBasicDef.h new file mode 100644 index 0000000..9fe6d7c --- /dev/null +++ b/src/caBasicDef.h @@ -0,0 +1,233 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.1 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef _CA_BASIC_INFO_DEF_H_ +#define _CA_BASIC_INFO_DEF_H_ + +#include +#include +#include +#include + +#include "caBasicDef_ENUM.h" + +#if !defined(TRUE) || !defined(FALSE) +#define TRUE 1 +#define FALSE 0 +#endif + +#define caMacro_MIN(v1, v2) (((v1) > (v2)) ? (v2) : (v1)) +#define caMacro_MAX(v1, v2) (((v1) < (v2)) ? (v2) : (v1)) +#define caMacro_ABS(v) (((v) < 0) ? -(v) : (v)) +#define caMacro_SQR(v) ((v) * (v)) +#define caMacro_ROUND(v) ((int) ((v) + 0.5)) +#define caMacro_TRUNC(v) ((int) (v)) +#define caMacro_CLIP255(v) ((v) > 255 ? 255 : (v)) +#define caMacro_CLIP0(v) ((v) < 0 ? 0 : (v)) +#define caMacro_CLIP0_255(v) (SMCLIP255(SMCLIP0(v))) +#define DIST_L2(x1, y1, x2, y2) (sqrt((double) SQR((x1) - (x2)) + (double) SQR((y1) - (y2)))) + +typedef float smSingle, smFloat; +typedef unsigned char smUInt8, smByte, BYTE, smUChar; +typedef unsigned short smUInt16; +typedef short smInt16; +typedef unsigned long smUInt32; +typedef long smInt32; +typedef int smInt; +typedef unsigned int smUInt; +typedef int smBool; +typedef smBool smBOOL; +typedef float smReal; + +#ifndef BOOL +typedef int BOOL; +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +typedef struct caPoint +{ + int x, y; +} caPoint; +typedef caPoint SMyPoint; + +typedef struct caFaceROI +{ + int x, y; + int width, height; +} caFaceROI; +typedef caFaceROI smFaceRect; + +typedef struct caEyeROI +{ + int lx, ly; + int rx, ry; +} caEyeROI; +typedef caEyeROI smEyePos; + +typedef struct caMouthROI +{ + int x, y; + int width, height; +} caMouthROI; +typedef caMouthROI smMouthRect; + +typedef struct caMouthPOS +{ + int lx, ly; + int rx, ry; +} caMouthPOS; +typedef caMouthPOS smMouthPOS; + +typedef struct caNoseTipPOS +{ + int x, y; +} caNoseTipPOS; + +typedef struct +{ + int x, y; +}SMyPoint2; + +typedef struct +{ + int left, top, right, bottom; +}SMyRect2; + +typedef struct +{ + int w; + int h; + int c; + unsigned char* pData; +} caByteImage; + +typedef struct +{ + int nData[4]; +} caVec4i; + +typedef struct +{ + int x, y; +} caVec2i; + +typedef struct +{ + double x, y; +} caVec2f; + +typedef struct +{ + PreviewMode RunMode; + int FrameOrder; + unsigned char* pFrameBuf; +}FrameMgr; + +typedef struct +{ + caPoint* faceCenterPt; + int* iResourceIndex; + int iFaceDetectedNum; + int* iSelected; + caPoint* mouthPt; + caEyeROI* eyePt; +}FaceSyncInfo; + +typedef struct +{ + BEAUTY_MODE btMode; + BEAUTY_LEVEL btLevel; +}AppFaceBeautyInfo; + +typedef struct +{ + int iMaxPicNum; + int* iValidFaceNum; + int* bp_Blur; + int** bp_Blink; + int** bp_Exp; +}AppBestPicInfo; + +typedef struct +{ + int g_SeqMax; + caEyeROI* g_SeqEye; + int g_SeqCount; + int g_SeqIsFixed; +}SequenceInfo; + +typedef struct +{ + int g_iFaceDetectInterval; + int g_iFaceLimitNum; + int g_iFaceSize; + caFDMode g_iFDMode; + int g_iFaceDetectNum; + + int* g_FaceConfidence; + int* g_FaceRIPAngle; + int* g_FacePyramidLevel; + int* g_IsValidFace; + caFaceROI* g_FaceROI; + caEyeROI* g_EyeROI; + caMouthROI* g_MouthROI; + caMouthPOS* g_MouthPOS; + caPoint* g_MouthPt; + int** g_Expression; + int** g_Blink; + + int* g_coreNeedToContinued; + int* g_coreFaceIndex; + + SequenceInfo* g_SequenceInfo; + + AppFaceBeautyInfo g_AppFBT_Info; +}FaceEngineInfo; + +#define DETECT_PARTIAL_FACE_BOTTOM 1 +#define DETECT_PARTIAL_FACE_RIGHT 1 +#define DETECT_PARTIAL_FACE_LEFT 1 +#define DETECT_PARTIAL_FACE_LEFTDOWN 1 +#define DETECT_PARTIAL_FACE_RIGHTDOWN 1 +#define DETECT_PARTIAL_FACE_UPPER 1 +#define DETECT_PARTIAL_FACE_CENTER 1 +#define DETECT_EXTENDED_BUFFER 0 + +#define PLATFORM_WINDOW 0 +#define PLATFORM_SLP 1 +#define PLATFORM_ANDROID 0 +#define PLATFORM_BADA 0 + +#define SLP_SPEEDVERSION 0 +#define ANIMATIONTHEME_ON 1 +#define SISO_SUPPORT 0 + +#define SUPPORT_VD 0 + +#define ANIMATION_INFINITE 999999 +#define DET_SEQUENCE 7 +#define WINK_RATIO 1.4 +#define WINK_MIN_THRESHOLD 13000 +#define WINK_MAX_THRESHOLD 14000 +#endif diff --git a/src/caBasicDef_ENUM.h b/src/caBasicDef_ENUM.h new file mode 100644 index 0000000..29aeb4b --- /dev/null +++ b/src/caBasicDef_ENUM.h @@ -0,0 +1,198 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.1 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef _CA_BASIC_INFO_DEF_ENUM_H_ +#define _CA_BASIC_INFO_DEF_ENUM_H_ + +typedef enum +{ + FD_MODE_ROLx_YAWx = 0x01, + FD_MODE_ROLx_YAWo = 0x02, + FD_MODE_ROLo_YAWo = 0x03, + FD_MODE_ROLo_YAWx = 0x04, +}caFDMode; + +typedef enum +{ + FD_SIZE_COVERAGE_VT_CALL = 0x00, + FD_SIZE_COVERAGE_LOW = 0x01, + FD_SIZE_COVERAGE_MID = 0x02, + FD_SIZE_COVERAGE_HIGH = 0x03, +}caFDSizeCoverage; + +typedef enum +{ + FR_MODE_CGL = 0x01, + FR_MODE_GBL = 0x02, + FR_MODE_MSL = 0x03, + FR_MODE_CGL_MSL = 0x04, + FR_MODE_GBL_MSL = 0x05, + FR_MODE_MPL2 = 0x06, + FR_MODE_MPL2_MSL = 0x07, + FR_MODE_ULBP = 0x08, +}caFRMode; + +typedef enum +{ + RM_FD_FAIL = 0x0001, + RM_ED_FAIL = 0x0002, + RM_ET_FAIL = 0x0003, + RM_FT_FAIL = 0x0004, + RM_MD_FAIL = 0x0005, + + RM_FD_SUCCESS = 0x0010, + RM_ED_SUCCESS = 0x0020, + RM_FT_SUCCESS = 0x0030, + RM_MD_SUCCESS = 0x0040, + + RM_FER_VIEW_MODE = 0x0000, + RM_FD_INIT_FAIL = 0x1000, + RM_ED_INIT_FAIL = 0x2000, + + RM_BACK_NORMAL = 0x0100, + RM_BACK_VERYHIGH = 0x0200, + RM_BACK_HIGH = 0x0300, + RM_BACK_LOW = 0x0400, + RM_BACK_VERYLOW = 0x0500, +}RetMessage; + + +typedef enum +{ + PREV_MODE_FACE_DETECTION, + PREV_MODE_FACE_TRACKING, + PREV_MODE_FACE_EXTRACTION, + PREV_MODE_EYE_DETECTION, + PREV_MODE_EYE_TRACKING, + PREV_MODE_BYPASS, +}PreviewMode; + +typedef enum +{ + FDT_INIT = 0x00, + FDT_SAME = 0x01, + FDT_INCREASE = 0x02, + FDT_DECREASE = 0x03 +}FaceDetectTrend; + +typedef enum +{ + ETM_FACEDETECTED = 0x10, + ETM_EYEDETECTED = 0x20, + ETM_NONEDETECTED = 0x30, +}EyeTraceMode; +typedef enum +{ + MSG_FT_SUCCESS = 0x01, + MSG_FT_ALL_FACE_MISS = 0x02, + MSG_FT_SOME_FACE_MISS = 0x03, + + MSG_FD_SUCCESS_FIRST = 0x11, + MSG_FD_SUCCESS = 0x12, + MSG_FD_FAIL = 0x13, + MSG_FD_ONGOING = 0x14, +}PreviewStateMsg; + +typedef enum +{ + MD_MODE_RECT = 0x01, + MD_MODE_POINT = 0x02, + MD_MODE_BOTH = 0x03, +}MD_DETECTION_MODE; + +typedef enum +{ + FT_MODE_1_DIRECTION = 0x00, + FT_MODE_3_DIRECTION = 0x02, + FT_MODE_4_DIRECTION = 0x03, +}FACE_TRACKING_MODE; + +typedef enum +{ + FBT_MODE_SOFTEN = 0x01, + FBT_MODE_SLENDER = 0x02, + FBT_MODE_BOTH = 0x03, +}BEAUTY_MODE; + +typedef enum +{ + FBT_LEVEL_VERY_STRONG = 0x05, + FBT_LEVEL_STRONG = 0x04, + FBT_LEVEL_MEDIUM = 0x03, + FBT_LEVEL_WEAK = 0x02, + FBT_LEVEL_VERY_WEAK = 0x01, +}BEAUTY_LEVEL; + +typedef enum +{ + IMG_FORMAT_RGB24 = 0x001, + IMG_FORMAT_RGB16 = 0x002, + IMG_FORMAT_ARGB = 0x003, + + IMG_FORMAT_YUV422_YUYV = 0x010, + IMG_FORMAT_YUV422_YVYU = 0x020, + + IMG_FORMAT_YUV420_PL = 0x100, + IMG_FORMAT_YUV420_SP_UV = 0x200, + IMG_FORMAT_YUV420_SP_VU = 0x300, +}IMAGE_DATE_FORMAT; + + +typedef enum +{ + EXP_NUETRAL = 0x000, + EXP_ANGRY = 0x001, + EXP_SMILE = 0x002, + EXP_SURPRISE = 0x003, +}EXPRESSIONMODE; + +typedef enum +{ + BD_OPEN = 0x000, + BD_LEFT = 0x001, + BD_RIGHT = 0x002, + BD_CLOSE = 0x003, +}BLINKMODE; + +typedef enum +{ + DT_FACE = 0x0001, + DT_FACEEYE = 0x0010, + DT_FACEEYEMOUTH1 = 0x0100, + DT_FACEEYEMOUTH2 = 0x0200, +}DTMODE; + +typedef enum +{ + DIRECTION_NONE = 0x0000, + DIRECTION_UP = 0x0001, + DIRECTION_RIGHT = 0x0002, + DIRECTION_LEFT = 0x0003, + DIRECTION_DOWN = 0x0004, +}DIRMODE; + +typedef enum +{ + PARTIAL_FD_CENTER = 0x0000, + PARTIAL_FD_LEFT = 0x0001, + PARTIAL_FD_LEFTBOTTOM = 0x0002, + PARTIAL_FD_RIGHT = 0x0003, + PARTIAL_FD_RIGHTBOTTOM = 0x0004, + PARTIAL_FD_BOTTOM = 0x0005, + PARTIAL_FD_TOP = 0x0006, +}PFDMODE; +#endif diff --git a/src/caFaceAPP_interface.h b/src/caFaceAPP_interface.h new file mode 100644 index 0000000..1096340 --- /dev/null +++ b/src/caFaceAPP_interface.h @@ -0,0 +1,75 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.1 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef _CA_FACE_APP_INTERFACE_H_ +#define _CA_FACE_APP_INTERFACE_H_ + +#include "caBasicDef.h" +#include "caBasicDef_ENUM.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern double g_DiffValue; +extern int g_cand_left; +extern int g_cand_right; +extern int g_previous_direction; +extern int g_isBlink; +extern int g_bMemoryAllocSuccess; + +extern caFaceROI g_FBTCandidateROI; +int caApp_FaceEngineInit(FaceEngineInfo* fe, caFDMode FDMode, caFDSizeCoverage coverage, int iFaceMaxNum, int iInterval); +int caApp_FaceEngineCoreInit(FaceEngineInfo* fe, int nFaceLimit); + +int caApp_FaceEngineReInit(FaceEngineInfo* fe); +int caApp_FaceEngineCoreReInit(FaceEngineInfo* fe); + +int caApp_FaceEngineRelease(FaceEngineInfo* fe); +int caApp_FaceEngineCoreRelease(FaceEngineInfo* fe); + +int caApp_RunFERDetection(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, BOOL bSingleImage); +int caApp_RunBlinkDetection(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, BOOL bSingleImage); +int caApp_RunWinkDetection(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, BOOL bSingleImage); +int caApp_RunFERDetectionSingleFace(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, int faceidx, BOOL bSingleImage); +int caApp_RunBlinkDetectionSingleFace(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, int faceidx, BOOL bSingleImage); +int caApp_RunWinkDetectionSingleFace(unsigned char* pSrc, int wd, int ht, FaceEngineInfo* coreFE, int faceidx, BOOL bSingleImage); + +int caApp_SetMouthForFER(unsigned char* pY, int wd, int ht, FaceEngineInfo* coreFE, EXPRESSIONMODE expression); +PreviewStateMsg caApp_TraceFace(int iFrmCnt, unsigned char* pOldFrmBuf, unsigned char* pCurFrmBuf, int wd, int ht, FaceEngineInfo* fe, FaceEngineInfo* corefe, int iScenario, int iDTMode); + + +int caApp_FinalArrageFaceEngineInfo(FaceEngineInfo* srcInfo, int nRatioSrcPerRsz, FaceEngineInfo* dstInfo); + +DIRMODE caApp_DetectFace4D(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe, unsigned char* pRotbuf, DIRMODE dirmode, DTMODE dtmode); +int caApp_DetectFaceEye4D(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe, int bIncludingEye); + +int caApp_RunFaceDetection(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe); +int caApp_RunEyeDetection(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe, int faceidx); +int caApp_RunMouthDetection(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe, int faceidx); + +int caApp_FtsExInit(caFRMode FRMode, char* binPath); +void caApp_FtsExRelease(); +long* caApp_FtsExGetFeatureVector(unsigned char* pY, int wd, int ht, FaceEngineInfo* fe, int nFaceIndex); +long caApp_FtsExCompareFeatureVector(long* enroll, long* test); +int caApp_FtsExVecLength(); + +int caApp_TraceRegion(unsigned char* pOldFrame, unsigned char* pNewFrame, caFaceROI mb, int frame_width, int frame_height, int* mv_w, int* mv_h); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file -- 2.7.4