├── EMOTIONS.txt ├── Kiavash1.jpg ├── FILES.txt ├── README.md ├── .gitignore ├── video_tracking.cpp ├── render_face_detections.h ├── render_face_detections_lines.cpp ├── LICENSE └── emotiondetection.cpp /EMOTIONS.txt: -------------------------------------------------------------------------------- 1 | Happy 2 | Happy -------------------------------------------------------------------------------- /Kiavash1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rageappliedgame/EmotionDetectionAsset_CPP/HEAD/Kiavash1.jpg -------------------------------------------------------------------------------- /FILES.txt: -------------------------------------------------------------------------------- 1 | C:\\Users\\kbh\\Desktop\\Emotion and CK+\\Kiavash1.jpg 2 | C:\\Users\\kbh\\Desktop\\Emotion and CK+\\Kiavash1.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EmotionDetectionAsset_CPP 2 | 3 | Implementation of 'Emotion Detection Asset C++' v1.0. 4 | 5 | Author: Kiavash Bahreini. 6 | 7 | Organization: Open University of the Netherlands (OUNL). 8 | 9 | Task: T2.3a of the RAGE project. The project website is http://rageproject.eu. 10 | 11 | For any questions please contact: 12 | 13 | Kiavash Bahreini via kiavash.bahreini [AT] ou [DOT] nl 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /video_tracking.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Open University of the Netherlands (OUNL) 3 | * 4 | * Author: Kiavash Bahreini. 5 | * Organization: Open University of the Netherlands (OUNL). 6 | * Project: The RAGE project 7 | * Project URL: http://rageproject.eu. 8 | * Task: T2.3 of the RAGE project; Development of assets for emotion detection. 9 | * 10 | * For any questions please contact: 11 | * 12 | * Kiavash Bahreini via kiavash.bahreini [AT] ou [DOT] nl 13 | * 14 | * Licensed under the Apache License, Version 2.0 (the "License"); 15 | * you may not use this file except in compliance with the License. 16 | * This project has received funding from the European Union’s Horizon 17 | * 2020 research and innovation programme under grant agreement No 644187. 18 | * You may obtain a copy of the License at 19 | * 20 | * http://www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an "AS IS" BASIS, 24 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | /* 30 | * This code is based on the dlib c++ library. 31 | * 32 | * URL: http://dlib.net/. 33 | */ 34 | 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | using namespace dlib; 43 | using namespace std; 44 | 45 | int main(int argc, char** argv) try 46 | { 47 | if (argc != 2) 48 | { 49 | cout << "Call this program like this: " << endl; 50 | cout << "./video_tracking_ex ../video_frames" << endl; 51 | return 1; 52 | } 53 | 54 | // Get the list of video frames. 55 | std::vector files = get_files_in_directory_tree(argv[1], match_ending(".jpg")); 56 | std::sort(files.begin(), files.end()); 57 | if (files.size() == 0) 58 | { 59 | cout << "No images found in " << argv[1] << endl; 60 | return 1; 61 | } 62 | 63 | // Load the first frame. 64 | array2d img; 65 | load_image(img, files[0]); 66 | // Now create a tracker and start a track on the juice box. If you look at the first 67 | // frame you will see that the juice box is centered at pixel point(92,110) and 38 68 | // pixels wide and 86 pixels tall. 69 | correlation_tracker tracker; 70 | tracker.start_track(img, centered_rect(point(93,110), 38, 86)); 71 | 72 | // Now run the tracker. All we have to do is call tracker.update() and it will keep 73 | // track of the juice box! 74 | image_window win; 75 | for (unsigned long i = 1; i < files.size(); ++i) 76 | { 77 | load_image(img, files[i]); 78 | tracker.update(img); 79 | 80 | win.set_image(img); 81 | win.clear_overlay(); 82 | win.add_overlay(tracker.get_position()); 83 | 84 | cout << "hit enter to process next frame" << endl; 85 | cin.get(); 86 | } 87 | } 88 | catch (std::exception& e) 89 | { 90 | cout << e.what() << endl; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /render_face_detections.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Facial Emotion Recognition in C++ versions 2.0 (Updated on Monday 11 June 2018). 3 | * 4 | * Emotion recognition is done based on facial expressions using image files and the webcam. 5 | * 6 | * Copyright 2017 Open University of the Netherlands (OUNL) 7 | * 8 | * Author: Kiavash Bahreini. 9 | * Organization: Open University of the Netherlands (OUNL). 10 | * Project: The RAGE project 11 | * Project URL: http://rageproject.eu. 12 | * Task: T2.3 of the RAGE project; Development of assets for emotion detection. 13 | * 14 | * For any questions please contact: 15 | * 16 | * Kiavash Bahreini via kiavash.bahreini [AT] ou [DOT] nl 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * This project has received funding from the European Union’s Horizon 21 | * 2020 research and innovation programme under grant agreement No 644187. 22 | * You may obtain a copy of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an "AS IS" BASIS, 28 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | * See the License for the specific language governing permissions and 30 | * limitations under the License. 31 | */ 32 | 33 | /* 34 | * This code is based on the dlib c++ library. 35 | * 36 | * URL: http://dlib.net/. 37 | */ 38 | 39 | /* 40 | * In order to capture the video from a camera this code uses 41 | * the Opencv version 2.4.11 and/or higher. 42 | * URL: https://sourceforge.net/projects/opencvlibrary/files/opencv-win/ 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #ifndef DLIB_RENDER_FACE_DeTECTIONS_H_ 53 | #define DLIB_RENDER_FACE_DeTECTIONS_H_ 54 | 55 | #include "full_object_detection.h" 56 | #include "../gui_widgets.h" 57 | #include "render_face_detections_abstract.h" 58 | #include 59 | 60 | namespace dlib 61 | { 62 | inline std::vector render_face_detections ( 63 | const std::vector& dets, 64 | const rgb_pixel color = rgb_pixel(0,255,0) 65 | ) 66 | { 67 | //std::vector lines; 68 | 69 | std::vector circle; 70 | for (unsigned long i = 0; i < dets.size(); ++i) 71 | { 72 | DLIB_CASSERT(dets[i].num_parts() == 68, 73 | "\t std::vector render_face_detections()" 74 | << "\n\t Invalid inputs were given to this function. " 75 | << "\n\t dets[" << i << "].num_parts(): " << dets[i].num_parts() 76 | ); 77 | 78 | const full_object_detection& d = dets[i]; 79 | 80 | for (unsigned long i = 0; i <= 67; ++i) { 81 | //lines.push_back(image_window::overlay_line(d.part(i), d.part(i - 1), color)); 82 | circle.push_back(image_window::overlay_circle(d.part(i), 3, rgb_pixel(255, 0, 0))); 83 | } 84 | 85 | return circle; 86 | } 87 | 88 | // ---------------------------------------------------------------------------------------- 89 | 90 | inline std::vector render_face_detections ( 91 | const full_object_detection& det, 92 | const rgb_pixel color = rgb_pixel(0,255,0) 93 | ) 94 | { 95 | std::vector dets; 96 | dets.push_back(det); 97 | return render_face_detections(dets, color); 98 | } 99 | 100 | // ---------------------------------------------------------------------------------------- 101 | 102 | } 103 | 104 | #endif // DLIB_RENDER_FACE_DeTECTIONS_H_ 105 | 106 | -------------------------------------------------------------------------------- /render_face_detections_lines.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Facial Emotion Recognition in C++ versions 2.0 (Updated on Monday 11 June 2018). 3 | * 4 | * Emotion recognition is done based on facial expressions using image files and the webcam. 5 | * 6 | * Copyright 2017 Open University of the Netherlands (OUNL) 7 | * 8 | * Author: Kiavash Bahreini. 9 | * Organization: Open University of the Netherlands (OUNL). 10 | * Project: The RAGE project 11 | * Project URL: http://rageproject.eu. 12 | * Task: T2.3 of the RAGE project; Development of assets for emotion detection. 13 | * 14 | * For any questions please contact: 15 | * 16 | * Kiavash Bahreini via kiavash.bahreini [AT] ou [DOT] nl 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * This project has received funding from the European Union’s Horizon 21 | * 2020 research and innovation programme under grant agreement No 644187. 22 | * You may obtain a copy of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an "AS IS" BASIS, 28 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | * See the License for the specific language governing permissions and 30 | * limitations under the License. 31 | */ 32 | 33 | /* 34 | * This code is based on the dlib c++ library. 35 | * 36 | * URL: http://dlib.net/. 37 | */ 38 | 39 | /* 40 | * In order to capture the video from a camera this code uses 41 | * the Opencv version 2.4.11 and/or higher. 42 | * URL: https://sourceforge.net/projects/opencvlibrary/files/opencv-win/ 43 | */ 44 | #ifndef DLIB_RENDER_FACE_DeTECTIONS_LINES_H_ 45 | #define DLIB_RENDER_FACE_DeTECTIONS_LINES_H_ 46 | 47 | #include "full_object_detection.h" 48 | #include "../gui_widgets.h" 49 | #include "render_face_detections_abstract.h" 50 | #include 51 | 52 | namespace dlib 53 | { 54 | inline std::vector render_face_detections_lines( 55 | const std::vector& dets, 56 | const rgb_pixel color = rgb_pixel(0, 255, 0) 57 | ) 58 | { 59 | std::vector lines; 60 | for (unsigned long i = 0; i < dets.size(); ++i) 61 | { 62 | DLIB_CASSERT(dets[i].num_parts() == 68, 63 | "\t std::vector render_face_detections_lines()" 64 | << "\n\t Invalid inputs were given to this function. " 65 | << "\n\t dets[" << i << "].num_parts(): " << dets[i].num_parts() 66 | ); 67 | 68 | const full_object_detection& d = dets[i]; 69 | 70 | lines.push_back(image_window::overlay_line(d.part(17), d.part(36), rgb_pixel(0, 0, 255))); 71 | lines.push_back(image_window::overlay_line(d.part(17), d.part(39), rgb_pixel(0, 0, 255))); 72 | lines.push_back(image_window::overlay_line(d.part(19), d.part(36), rgb_pixel(0, 0, 255))); 73 | lines.push_back(image_window::overlay_line(d.part(19), d.part(39), rgb_pixel(0, 0, 255))); 74 | lines.push_back(image_window::overlay_line(d.part(21), d.part(36), rgb_pixel(0, 0, 255))); 75 | lines.push_back(image_window::overlay_line(d.part(21), d.part(39), rgb_pixel(0, 0, 255))); 76 | lines.push_back(image_window::overlay_line(d.part(22), d.part(42), rgb_pixel(0, 0, 255))); 77 | lines.push_back(image_window::overlay_line(d.part(22), d.part(45), rgb_pixel(0, 0, 255))); 78 | lines.push_back(image_window::overlay_line(d.part(24), d.part(42), rgb_pixel(0, 0, 255))); 79 | lines.push_back(image_window::overlay_line(d.part(24), d.part(45), rgb_pixel(0, 0, 255))); 80 | lines.push_back(image_window::overlay_line(d.part(26), d.part(42), rgb_pixel(0, 0, 255))); 81 | lines.push_back(image_window::overlay_line(d.part(26), d.part(45), rgb_pixel(0, 0, 255))); 82 | lines.push_back(image_window::overlay_line(d.part(43), d.part(47), rgb_pixel(0, 0, 255))); 83 | lines.push_back(image_window::overlay_line(d.part(43), d.part(46), rgb_pixel(0, 0, 255))); 84 | lines.push_back(image_window::overlay_line(d.part(44), d.part(47), rgb_pixel(0, 0, 255))); 85 | lines.push_back(image_window::overlay_line(d.part(44), d.part(46), rgb_pixel(0, 0, 255))); 86 | lines.push_back(image_window::overlay_line(d.part(48), d.part(54), rgb_pixel(0, 0, 255))); 87 | lines.push_back(image_window::overlay_line(d.part(51), d.part(57), rgb_pixel(0, 0, 255))); 88 | lines.push_back(image_window::overlay_line(d.part(51), d.part(48), rgb_pixel(0, 0, 255))); 89 | lines.push_back(image_window::overlay_line(d.part(51), d.part(54), rgb_pixel(0, 0, 255))); 90 | lines.push_back(image_window::overlay_line(d.part(57), d.part(48), rgb_pixel(0, 0, 255))); 91 | lines.push_back(image_window::overlay_line(d.part(57), d.part(54), rgb_pixel(0, 0, 255))); 92 | lines.push_back(image_window::overlay_line(d.part(19), d.part(17), rgb_pixel(0, 0, 255))); 93 | lines.push_back(image_window::overlay_line(d.part(19), d.part(21), rgb_pixel(0, 0, 255))); 94 | lines.push_back(image_window::overlay_line(d.part(24), d.part(22), rgb_pixel(0, 0, 255))); 95 | lines.push_back(image_window::overlay_line(d.part(24), d.part(26), rgb_pixel(0, 0, 255))); 96 | lines.push_back(image_window::overlay_line(d.part(21), d.part(22), rgb_pixel(0, 0, 255))); 97 | lines.push_back(image_window::overlay_line(d.part(36), d.part(39), rgb_pixel(0, 0, 255))); 98 | lines.push_back(image_window::overlay_line(d.part(42), d.part(45), rgb_pixel(0, 0, 255))); 99 | lines.push_back(image_window::overlay_line(d.part(37), d.part(41), rgb_pixel(0, 0, 255))); 100 | lines.push_back(image_window::overlay_line(d.part(37), d.part(40), rgb_pixel(0, 0, 255))); 101 | lines.push_back(image_window::overlay_line(d.part(38), d.part(41), rgb_pixel(0, 0, 255))); 102 | lines.push_back(image_window::overlay_line(d.part(38), d.part(40), rgb_pixel(0, 0, 255))); 103 | lines.push_back(image_window::overlay_line(d.part(36), d.part(48), rgb_pixel(0, 0, 255))); 104 | lines.push_back(image_window::overlay_line(d.part(39), d.part(51), rgb_pixel(0, 0, 255))); 105 | lines.push_back(image_window::overlay_line(d.part(42), d.part(51), rgb_pixel(0, 0, 255))); 106 | lines.push_back(image_window::overlay_line(d.part(45), d.part(54), rgb_pixel(0, 0, 255))); 107 | } 108 | return lines; 109 | } 110 | 111 | // ---------------------------------------------------------------------------------------- 112 | 113 | inline std::vector render_face_detections_lines( 114 | const full_object_detection& det, 115 | const rgb_pixel color = rgb_pixel(0, 255, 0) 116 | ) 117 | { 118 | std::vector dets; 119 | dets.push_back(det); 120 | return render_face_detections_lines(dets, color); 121 | } 122 | 123 | // ---------------------------------------------------------------------------------------- 124 | } 125 | 126 | #endif // DLIB_RENDER_FACE_DeTECTIONS_LINES_H_ 127 | 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /emotiondetection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Facial Emotion Recognition in C++ versions 2.0 (Updated on Monday 11 June 2018). 3 | * 4 | * Emotion recognition is done based on facial expressions using image files and the webcam. 5 | * 6 | * Copyright 2017 Open University of the Netherlands (OUNL) 7 | * 8 | * Author: Kiavash Bahreini. 9 | * Organization: Open University of the Netherlands (OUNL). 10 | * Project: The RAGE project 11 | * Project URL: http://rageproject.eu. 12 | * Task: T2.3 of the RAGE project; Development of assets for emotion detection. 13 | * 14 | * For any questions please contact: 15 | * 16 | * Kiavash Bahreini via kiavash.bahreini [AT] ou [DOT] nl 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * This project has received funding from the European Union’s Horizon 21 | * 2020 research and innovation programme under grant agreement No 644187. 22 | * You may obtain a copy of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an "AS IS" BASIS, 28 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | * See the License for the specific language governing permissions and 30 | * limitations under the License. 31 | */ 32 | 33 | /* 34 | * This code is based on the dlib c++ library. 35 | * 36 | * URL: http://dlib.net/. 37 | */ 38 | 39 | /* 40 | * In order to capture the video from a camera this code uses 41 | * the Opencv version 2.4.11 and/or higher. 42 | * URL: https://sourceforge.net/projects/opencvlibrary/files/opencv-win/ 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | 55 | //To capture the video from a camera 56 | #include "C:\opencv-2.4.11\opencv\sources\modules\core\include\opencv2\highgui\highgui.hpp" 57 | 58 | #include 59 | #include 60 | 61 | using namespace dlib; 62 | using namespace std; 63 | 64 | // ---------------------------------------------------------------------------------------- 65 | // See http://stackoverflow.com/questions/876901/calculating-execution-time-in-c 66 | #ifndef SYSOUT_F 67 | #define SYSOUT_F(f, d) cout << f << std::setprecision (3) << (int)(d * 1000.0) << "ms" << endl // For Visual studio 68 | #endif 69 | 70 | #ifndef speedtest___ 71 | #define speedtest___(data) for (long blockTime = NULL; (blockTime == NULL ? (blockTime = clock()) != NULL : false); SYSOUT_F(data, (double) (clock() - blockTime) / CLOCKS_PER_SEC)) 72 | #endif 73 | 74 | int webcam(); 75 | // ---------------------------------------------------------------------------------------- 76 | long double calculateEuclideanDistance(const short int x, const short int y, const short int a, const short int b) { 77 | //Solution: http://www.cut-the-knot.org/pythagoras/DistanceFormula.shtml 78 | //dist((x, y), (a, b)) = √(x - a)² + (y - b)² 79 | return (sqrt(pow(x - a, 2) + pow(y - b, 2))); 80 | } 81 | // ------------------------- 82 | long double * setPointsToCalculateEuclideanDistance(full_object_detection shape) { 83 | 84 | static long double EuclideanDistanceArray[54]; 85 | 86 | //Left eyebrow to the left eye 87 | EuclideanDistanceArray[0] = calculateEuclideanDistance(shape.part(17).x(), shape.part(17).y(), shape.part(36).x(), shape.part(36).y()); 88 | EuclideanDistanceArray[1] = calculateEuclideanDistance(shape.part(17).x(), shape.part(17).y(), shape.part(39).x(), shape.part(39).y()); 89 | EuclideanDistanceArray[2] = calculateEuclideanDistance(shape.part(36).x(), shape.part(36).y(), shape.part(39).x(), shape.part(39).y()); 90 | 91 | EuclideanDistanceArray[3] = calculateEuclideanDistance(shape.part(19).x(), shape.part(19).y(), shape.part(36).x(), shape.part(36).y()); 92 | EuclideanDistanceArray[4] = calculateEuclideanDistance(shape.part(19).x(), shape.part(19).y(), shape.part(39).x(), shape.part(39).y()); 93 | EuclideanDistanceArray[5] = EuclideanDistanceArray[2]; 94 | 95 | EuclideanDistanceArray[6] = calculateEuclideanDistance(shape.part(21).x(), shape.part(21).y(), shape.part(36).x(), shape.part(36).y()); 96 | EuclideanDistanceArray[7] = calculateEuclideanDistance(shape.part(21).x(), shape.part(21).y(), shape.part(39).x(), shape.part(39).y()); 97 | EuclideanDistanceArray[8] = EuclideanDistanceArray[2]; 98 | 99 | //Right eyebrow to the right eye 100 | EuclideanDistanceArray[9] = calculateEuclideanDistance(shape.part(22).x(), shape.part(22).y(), shape.part(42).x(), shape.part(42).y()); 101 | EuclideanDistanceArray[10] = calculateEuclideanDistance(shape.part(22).x(), shape.part(22).y(), shape.part(45).x(), shape.part(45).y()); 102 | EuclideanDistanceArray[11] = calculateEuclideanDistance(shape.part(42).x(), shape.part(42).y(), shape.part(45).x(), shape.part(45).y()); 103 | 104 | EuclideanDistanceArray[12] = calculateEuclideanDistance(shape.part(24).x(), shape.part(24).y(), shape.part(42).x(), shape.part(42).y()); 105 | EuclideanDistanceArray[13] = calculateEuclideanDistance(shape.part(24).x(), shape.part(24).y(), shape.part(45).x(), shape.part(45).y()); 106 | EuclideanDistanceArray[14] = EuclideanDistanceArray[11]; 107 | 108 | EuclideanDistanceArray[15] = calculateEuclideanDistance(shape.part(26).x(), shape.part(26).y(), shape.part(42).x(), shape.part(42).y()); 109 | EuclideanDistanceArray[16] = calculateEuclideanDistance(shape.part(26).x(), shape.part(26).y(), shape.part(45).x(), shape.part(45).y()); 110 | EuclideanDistanceArray[17] = EuclideanDistanceArray[11]; 111 | 112 | //Left eye 113 | EuclideanDistanceArray[18] = calculateEuclideanDistance(shape.part(37).x(), shape.part(37).y(), shape.part(40).x(), shape.part(40).y()); 114 | EuclideanDistanceArray[19] = calculateEuclideanDistance(shape.part(37).x(), shape.part(37).y(), shape.part(41).x(), shape.part(41).y()); 115 | EuclideanDistanceArray[20] = calculateEuclideanDistance(shape.part(40).x(), shape.part(40).y(), shape.part(41).x(), shape.part(41).y()); 116 | 117 | EuclideanDistanceArray[21] = calculateEuclideanDistance(shape.part(38).x(), shape.part(38).y(), shape.part(40).x(), shape.part(40).y()); 118 | EuclideanDistanceArray[22] = calculateEuclideanDistance(shape.part(38).x(), shape.part(38).y(), shape.part(41).x(), shape.part(41).y()); 119 | EuclideanDistanceArray[23] = EuclideanDistanceArray[20]; 120 | 121 | EuclideanDistanceArray[24] = calculateEuclideanDistance(shape.part(43).x(), shape.part(43).y(), shape.part(46).x(), shape.part(46).y()); 122 | EuclideanDistanceArray[25] = calculateEuclideanDistance(shape.part(43).x(), shape.part(43).y(), shape.part(47).x(), shape.part(47).y()); 123 | EuclideanDistanceArray[26] = calculateEuclideanDistance(shape.part(46).x(), shape.part(46).y(), shape.part(47).x(), shape.part(47).y()); 124 | 125 | EuclideanDistanceArray[27] = calculateEuclideanDistance(shape.part(44).x(), shape.part(44).y(), shape.part(46).x(), shape.part(46).y()); 126 | EuclideanDistanceArray[28] = calculateEuclideanDistance(shape.part(44).x(), shape.part(44).y(), shape.part(47).x(), shape.part(47).y()); 127 | EuclideanDistanceArray[29] = EuclideanDistanceArray[26]; 128 | 129 | //Top of the mouth 130 | EuclideanDistanceArray[30] = calculateEuclideanDistance(shape.part(48).x(), shape.part(48).y(), shape.part(51).x(), shape.part(51).y()); 131 | EuclideanDistanceArray[31] = calculateEuclideanDistance(shape.part(51).x(), shape.part(51).y(), shape.part(54).x(), shape.part(54).y()); 132 | EuclideanDistanceArray[32] = calculateEuclideanDistance(shape.part(48).x(), shape.part(48).y(), shape.part(54).x(), shape.part(54).y()); 133 | 134 | //Buttom of the mouth 135 | EuclideanDistanceArray[33] = calculateEuclideanDistance(shape.part(48).x(), shape.part(48).y(), shape.part(57).x(), shape.part(57).y()); 136 | EuclideanDistanceArray[34] = calculateEuclideanDistance(shape.part(54).x(), shape.part(54).y(), shape.part(57).x(), shape.part(57).y()); 137 | EuclideanDistanceArray[35] = EuclideanDistanceArray[32]; 138 | 139 | //Left eyebrow 140 | EuclideanDistanceArray[36] = calculateEuclideanDistance(shape.part(17).x(), shape.part(17).y(), shape.part(19).x(), shape.part(19).y()); 141 | EuclideanDistanceArray[37] = calculateEuclideanDistance(shape.part(19).x(), shape.part(19).y(), shape.part(21).x(), shape.part(21).y()); 142 | EuclideanDistanceArray[38] = calculateEuclideanDistance(shape.part(17).x(), shape.part(17).y(), shape.part(21).x(), shape.part(21).y()); 143 | 144 | //Right eyebrow 145 | EuclideanDistanceArray[39] = calculateEuclideanDistance(shape.part(22).x(), shape.part(22).y(), shape.part(24).x(), shape.part(24).y()); 146 | EuclideanDistanceArray[40] = calculateEuclideanDistance(shape.part(24).x(), shape.part(24).y(), shape.part(26).x(), shape.part(26).y()); 147 | EuclideanDistanceArray[41] = calculateEuclideanDistance(shape.part(22).x(), shape.part(22).y(), shape.part(26).x(), shape.part(26).y()); 148 | 149 | //Eyebrows to the top nose 150 | EuclideanDistanceArray[42] = calculateEuclideanDistance(shape.part(21).x(), shape.part(21).y(), shape.part(27).x(), shape.part(27).y()); 151 | EuclideanDistanceArray[43] = calculateEuclideanDistance(shape.part(22).x(), shape.part(22).y(), shape.part(27).x(), shape.part(27).y()); 152 | EuclideanDistanceArray[44] = calculateEuclideanDistance(shape.part(21).x(), shape.part(21).y(), shape.part(22).x(), shape.part(22).y()); 153 | 154 | //Left eye to the mouth 155 | EuclideanDistanceArray[45] = calculateEuclideanDistance(shape.part(36).x(), shape.part(36).y(), shape.part(60).x(), shape.part(60).y()); 156 | EuclideanDistanceArray[46] = calculateEuclideanDistance(shape.part(48).x(), shape.part(48).y(), shape.part(60).x(), shape.part(60).y()); 157 | EuclideanDistanceArray[47] = calculateEuclideanDistance(shape.part(36).x(), shape.part(36).y(), shape.part(48).x(), shape.part(48).y()); 158 | 159 | //Right eye to the mouth 160 | EuclideanDistanceArray[48] = calculateEuclideanDistance(shape.part(45).x(), shape.part(45).y(), shape.part(64).x(), shape.part(64).y()); 161 | EuclideanDistanceArray[49] = calculateEuclideanDistance(shape.part(54).x(), shape.part(54).y(), shape.part(64).x(), shape.part(64).y()); 162 | EuclideanDistanceArray[50] = calculateEuclideanDistance(shape.part(45).x(), shape.part(45).y(), shape.part(54).x(), shape.part(54).y()); 163 | 164 | //Mouth to eyes 165 | EuclideanDistanceArray[51] = calculateEuclideanDistance(shape.part(39).x(), shape.part(39).y(), shape.part(51).x(), shape.part(51).y()); 166 | EuclideanDistanceArray[52] = calculateEuclideanDistance(shape.part(42).x(), shape.part(42).y(), shape.part(51).x(), shape.part(51).y()); 167 | EuclideanDistanceArray[53] = calculateEuclideanDistance(shape.part(39).x(), shape.part(39).y(), shape.part(42).x(), shape.part(42).y()); 168 | 169 | return EuclideanDistanceArray; 170 | } 171 | // ------------------------- 172 | long double calculateCosines(const long double a, const long double b, const long double c) { 173 | //General Solution: https://www.mathsisfun.com/algebra/trig-solving-triangles.html 174 | //Solution for this specific problem: https://www.mathsisfun.com/algebra/trig-solving-sss-triangles.html 175 | 176 | //To solve three sides of the triangle (called an SSS triangle) : 177 | 178 | //Use The Law of Cosines first to calculate one of the angles 179 | //then use The Law of Cosines again to find another angle 180 | //and finally use angles of a triangle add to 180° to find the last angle. 181 | 182 | //We use the "angle" version of the Law of Cosines : 183 | //cos(C) = (a² + b² − c²)/2ab 184 | //cos(A) = (b² + c² − a²)/2bc 185 | //cos(B) = (c² + a² − b²)/2ca 186 | 187 | return ((pow(a, 2) + pow(b, 2) - pow(c, 2)) / (2 * a*b)); 188 | } 189 | 190 | long double * callCalculateCosines(const long double * EuclideanDistanceArrayPointer) { 191 | 192 | static long double CalculateCosinesArray[54]; 193 | 194 | for (int i = 0; i < 54; i += 3) { 195 | CalculateCosinesArray[i] = calculateCosines(*(EuclideanDistanceArrayPointer + i), *(EuclideanDistanceArrayPointer + i + 1), *(EuclideanDistanceArrayPointer + i + 2)); 196 | CalculateCosinesArray[i + 1] = calculateCosines(*(EuclideanDistanceArrayPointer + i + 1), *(EuclideanDistanceArrayPointer + i + 2), *(EuclideanDistanceArrayPointer + i)); 197 | CalculateCosinesArray[i + 2] = calculateCosines(*(EuclideanDistanceArrayPointer + i + 2), *(EuclideanDistanceArrayPointer + i), *(EuclideanDistanceArrayPointer + i + 1)); 198 | } 199 | return CalculateCosinesArray; 200 | } 201 | 202 | long double calculateArcCosines(const long double a) { 203 | //General Solution: https://www.mathsisfun.com/algebra/trig-solving-triangles.html 204 | //Solution for this specific problem: https://www.mathsisfun.com/algebra/trig-solving-sss-triangles.html 205 | 206 | //To solve three sides of the triangle (called an SSS triangle) : 207 | 208 | //Use The Law of Cosines first to calculate one of the angles 209 | //then use The Law of Cosines again to find another angle 210 | //and finally use angles of a triangle add to 180° to find the last angle. 211 | 212 | //We use the "angle" version of the Law of Cosines : 213 | //cos(C) = (a² + b² − c²)/2ab 214 | //cos(A) = (b² + c² − a²)/2bc 215 | //cos(B) = (c² + a² − b²)/2ca 216 | 217 | return (acos(a) * 180.0 / 3.14159265); 218 | } 219 | 220 | long double * callCalculateArcCosines(const long double * CosinesArrayPointer) { 221 | 222 | static long double CalculateArcCosinesArray[54]; 223 | 224 | for (int i = 0; i < 54; i += 3) { 225 | CalculateArcCosinesArray[i] = calculateArcCosines(*(CosinesArrayPointer + i)); 226 | CalculateArcCosinesArray[i + 1] = calculateArcCosines(*(CosinesArrayPointer + i + 1)); 227 | //CalculateArcCosinesArray[i + 2] = 180 - CalculateArcCosinesArray[i] - CalculateArcCosinesArray[i + 1]; 228 | CalculateArcCosinesArray[i + 2] = calculateArcCosines(*(CosinesArrayPointer + i + 2)); 229 | } 230 | return CalculateArcCosinesArray; 231 | } 232 | int main(int argc, char** argv) 233 | { 234 | try 235 | { 236 | // This example takes in a shape model file and then a list of images to 237 | // process. We will take these filenames in as command line arguments. 238 | // Dlib comes with example images in the examples/faces folder so give 239 | // those as arguments to this program. 240 | //if (argc == 1) 241 | //{ 242 | //std::cout << "Call this program like this:" << endl; 243 | //std::cout << "./face_landmark_detection_ex shape_predictor_68_face_landmarks.dat faces/*.jpg" << endl; 244 | //std::cout << "\nYou can get the shape_predictor_68_face_landmarks.dat file from:\n"; 245 | //std::cout << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl; 246 | //return 0; 247 | //} 248 | 249 | 250 | // You may disable this line ("//int returnFromWebcam = webcam();") 251 | // if you would like to recognise emotions from image files. 252 | // Otherwise, this line will use your webcam to show you the feedback 253 | // based on your facial expressions in real-time mode. 254 | //int returnFromWebcam = webcam(); 255 | 256 | clock_t tStart = clock(); 257 | 258 | // We need a face detector. We will use this to get bounding boxes for 259 | // each face in an image. 260 | frontal_face_detector detector; 261 | speedtest___("get_frontal_face_detector: ") 262 | { 263 | detector = get_frontal_face_detector(); 264 | } 265 | // And we also need a shape_predictor. This is the tool that will predict face 266 | // landmark positions given an image and face bounding box. Here we are just 267 | // loading the model from the shape_predictor_68_face_landmarks.dat file you gave 268 | // as a command line argument. 269 | shape_predictor sp; 270 | speedtest___("deserialize database: ") 271 | { 272 | //deserialize(argv[1]) >> sp; 273 | deserialize("C:\\Users\\kbh\\Desktop\\dlib-master\\examples\\build\\Debug\\shape_predictor_68_face_landmarks.dat") >> sp; 274 | } 275 | 276 | image_window win;//, win_faces; 277 | // Loop over all the images provided on the command line. 278 | for (int i = 2; i < 3; ++i) 279 | { 280 | //std::cout << "processing image " << "C:\\Users\\kbh\\Desktop\\Emotion and CK+\\cohn-kanade-images\\S005\\001\\S005_001_00000011.png" << endl; 281 | array2d img; 282 | 283 | // std::ifstream file("C:\\Users\\kbh\\Desktop\\Emotion and CK+\\List of files sorted by emotions.txt"); 284 | // std::ifstream emotionFile("C:\\Users\\kbh\\Desktop\\Emotion and CK+\\List of emotions sorted by emotions.txt"); 285 | std::ifstream file("C:\\Users\\kbh\\Desktop\\Emotion and CK+\\FILES.txt"); 286 | std::ifstream emotionFile("C:\\Users\\kbh\\Desktop\\Emotion and CK+\\EMOTIONS.txt"); 287 | /* Happy=69+69=138 288 | / Sad=27+27=54 289 | / Surprise=83+83=166 290 | / Fear=25+25=50 291 | / Disgust=59+59=118 292 | / Anger=45+45=90 293 | / Neutral=123+123=246 294 | */ 295 | // std::string matrix[862]; //Number of files 296 | // std::string emotionMatrix[862]; //Number of emotions 297 | std::string matrix[2]; //Number of files 298 | std::string emotionMatrix[2]; //Number of emotions 299 | std::string line; 300 | std::string emotionLine; 301 | int row = 0; 302 | int emotionRow = 0; 303 | 304 | while (std::getline(file, line)) { 305 | std::istringstream stream(line); 306 | 307 | matrix[row] = line; 308 | row++; 309 | } 310 | while (std::getline(emotionFile, emotionLine)) { 311 | std::istringstream stream(emotionLine); 312 | 313 | emotionMatrix[emotionRow] = emotionLine; 314 | emotionRow++; 315 | } 316 | 317 | for (int i = 0; i < row; i++) { 318 | std::cout << matrix[i]; 319 | std::cout << "\n"; 320 | } 321 | for (int i = 0; i < emotionRow; i++) { 322 | std::cout << emotionMatrix[i]; 323 | std::cout << "\n"; 324 | } 325 | 326 | bool flag = 0;// make sure that the image is processed in flip and not flip modes 327 | 328 | for (int i = 0; i < row; i++) { 329 | 330 | load_image(img, matrix[i]); 331 | // Make the image larger so we can detect small faces. 332 | //pyramid_up(img); 333 | 334 | if (flag == 1) { 335 | 336 | //Rotate cimg to img 337 | dlib::array2d imgTempGray; 338 | assign_image(imgTempGray, img); 339 | flip_image_left_right(imgTempGray, img); 340 | 341 | flag = 0; 342 | } 343 | else { 344 | //load_image(img, matrix[i]); 345 | // Make the image larger so we can detect small faces. 346 | //pyramid_up(img); 347 | flag = 1; 348 | } 349 | // Now tell the face detector to give us a list of bounding boxes 350 | // around all the faces in the image. 351 | std::vector dets; 352 | speedtest___("detect faces: ") 353 | { 354 | dets = detector(img); 355 | } 356 | std::cout << "Number of faces detected: " << dets.size() << endl; 357 | 358 | // Now we will go ask the shape_predictor to tell us the pose of 359 | // each face we detected. 360 | std::vector shapes; 361 | speedtest___("detect features: ") 362 | { 363 | for (unsigned long j = 0; j < dets.size(); ++j) 364 | { 365 | full_object_detection shape = sp(img, dets[j]); 366 | std::cout << "number of parts: " << shape.num_parts() << endl; 367 | std::cout << "pixel position of first part: " << shape.part(0) << " " << shape.part(0).x() << " " << shape.part(0).y() << endl; 368 | std::cout << "pixel position of second part: " << shape.part(1) << endl; 369 | 370 | //////////////////////////////////////////////////////////////// 371 | std::ofstream fout("EmotionsDataset.txt", ofstream::app); 372 | if (!fout) 373 | throw dlib::error("ERROR: Unable to open image_metadata_stylesheet.xsl for writing."); 374 | 375 | ostringstream convert; 376 | convert << emotionMatrix[i];// << i; 377 | 378 | // A pointer to a long double to calculate the euclidean distance between the landmark points. 379 | const long double *EuclideanDistanceArrayPointer; 380 | EuclideanDistanceArrayPointer = setPointsToCalculateEuclideanDistance(shape); 381 | 382 | // A pointer to a long double to calculate the cosines between the three sides of the triangle. 383 | const long double *CosinesArrayPointer; 384 | CosinesArrayPointer = callCalculateCosines(EuclideanDistanceArrayPointer); 385 | 386 | // A pointer to a long double to calculate the arc cosines of the angles. 387 | const long double *ArcCosinesArrayPointer; 388 | ArcCosinesArrayPointer = callCalculateArcCosines(CosinesArrayPointer); 389 | 390 | 391 | for (int i = 0; i < 54; i++) 392 | fout << *(ArcCosinesArrayPointer + i) << ","; 393 | 394 | fout << convert.str().c_str() << endl; 395 | fout.close(); 396 | std::cout << "Write Done." << endl; 397 | 398 | //////////////////////////////////////////////////////////////// 399 | //*(ArcCosinesArrayPointer + i) 400 | const long double *R = ArcCosinesArrayPointer; 401 | //Happy 402 | //Rule 1 403 | if ( 404 | ((*(R + 30) >= 159.608 && *(R + 30) <= 160.424) || (*(R + 30) >= 160.424)) 405 | && (!(*(R + 30) >= 160.168 && *(R + 30) <= 160.675) || (!*(R + 30) <= 160.168)) 406 | && ((*(R + 35) >= 30.0655 && *(R + 35) <= 30.2536) || (*(R + 35) >= 30.2536 407 | && (!(*(R + 35) > 30.2536 && *(R + 35) <= 32.685)))) 408 | ) { 409 | cout << "Emotions = Happy(CF = 0.97)" << endl; 410 | } 411 | //Rule 2 412 | if ( 413 | ((*(R + 31) >= 9.85016 && *(R + 31) <= 9.96286) || (*(R + 31) <= 9.85016)) 414 | && ((*(R + 51) >= 35.5078 && *(R + 51) <= 35.5856) || (*(R + 31) >= 35.5856)) 415 | && ((*(R + 10) >= 22.9748 && *(R + 10) <= 23.0757) || (*(R + 10) <= 23.0757)) 416 | && ((*(R + 0) >= 24.8358 && *(R + 0) <= 24.9599) || (*(R + 0) <= 24.8358)) 417 | ) { 418 | cout << "Emotions = Happy(CF = 0.98)" << endl; 419 | } 420 | //Rule 3 421 | if ( 422 | ((*(R + 32) >= 13.8022 && *(R + 32) <= 14.6793) || (*(R + 32) <= 13.8022)) 423 | && ((*(R + 34) >= 25.1647 && *(R + 34) <= 25.4542) || (*(R + 34) >= 25.4542)) 424 | && ((*(R + 50) >= 3.7724 && *(R + 50) <= 3.79234) || (*(R + 50) >= 3.79234)) 425 | && ((*(R + 48) >= 64.551 && *(R + 48) <= 66.8476) || (*(R + 48) >= 66.8476)) 426 | ) { 427 | cout << "Emotions = Happy(CF = 0.9)" << endl; 428 | } 429 | //Rule 4 430 | if ( 431 | ((*(R + 31) >= 12.4074 && *(R + 31) <= 16.2636) || (*(R + 31) <= 12.4074)) 432 | && ((*(R + 35) >= 25.6426 && *(R + 35) <= 27.0878) || (*(R + 35) >= 25.0878)) 433 | && ((*(R + 37) >= 21.4168 && *(R + 37) <= 21.5797) || (*(R + 37) >= 21.5797)) 434 | && ((*(R + 0) >= 21.1748 && *(R + 0) <= 21.9187) || (*(R + 0) <= 21.1748)) 435 | ) { 436 | cout << "Emotions = Happy(CF = 0.95)" << endl; 437 | } 438 | //Rule 5 439 | if ( 440 | ((*(R + 32) >= 5.15255 && *(R + 32) <= 5.16574) || (*(R + 32) <= 5.15255)) 441 | && ((*(R + 32) >= 4.97626 && *(R + 32) <= 5.05265) || (*(R + 32) >= 5.05265)) 442 | ) { 443 | cout << "Emotions = Happy(CF = 0.66)" << endl; 444 | } 445 | //Sad 446 | //Rule 6 447 | if ( 448 | ((*(R + 34) >= 15.1591 && *(R + 34) <= 15.3646) || (*(R + 34) >= 15.1591)) 449 | && ((*(R + 42) >= 73.6283 && *(R + 42) <= 74.5163) || (*(R + 42) <= 73.6283)) 450 | && ((*(R + 32) >= 17.9646 && *(R + 32) <= 17.9917) || (*(R + 32) >= 17.9917)) 451 | && ((*(R + 13) >= 68.61 && *(R + 13) <= 70.3929) || (*(R + 13) >= 70.3929)) 452 | && ((*(R + 37) >= 22.5483 && *(R + 37) <= 22.8643) || (*(R + 37) <= 22.5483)) 453 | ) { 454 | cout << "Emotions = Sad(CF = 0.94)" << endl; 455 | } 456 | //Rule 7 457 | if ( 458 | ((*(R + 33) >= 142.341 && *(R + 33) <= 142.606) || (*(R + 33) >= 142.606)) 459 | && ((*(R + 44) >= 51.9081 && *(R + 44) <= 52.9607) || (*(R + 44) >= 52.9607)) 460 | && ((*(R + 50) >= 3.15842 && *(R + 50) <= 3.18719) || (*(R + 50) <= 3.15842)) 461 | && ((*(R + 31) >= 14.1431 && *(R + 31) <= 14.4425) || (*(R + 31) >= 14.4425)) 462 | ) { 463 | cout << "Emotions = Sad(CF = 0.82)" << endl; 464 | } 465 | //Rule 8 466 | if ( 467 | ((*(R + 46) >= 84.9609 && *(R + 46) <= 85.074) || (*(R + 46) <= 84.9609)) 468 | && ((*(R + 51) >= 36.248 && *(R + 51) <= 36.6846) || (*(R + 51) >= 36.6846)) 469 | ) { 470 | cout << "Emotions = Sad(CF = 0.81)" << endl; 471 | } 472 | //Rule 9 473 | if ( 474 | ((*(R + 42) >= 54.362 && *(R + 42) <= 54.4623) || (*(R + 42) <= 54.362)) 475 | && ((*(R + 3) >= 49.4672 && *(R + 3) <= 53.9726) || (*(R + 3) >= 53.9726)) 476 | && ((*(R + 18) >= 48.7314 && *(R + 18) <= 48.7806) || (*(R + 18) >= 48.7806)) 477 | ) { 478 | cout << "Emotions = Sad(CF = 0.84)" << endl; 479 | } 480 | //Rule 10 481 | if ( 482 | ((*(R + 1) >= 6.82602 && *(R + 1) <= 7.03498) || (*(R + 1) <= 6.82602)) 483 | && ((*(R + 15) >= 14.5889 && *(R + 15) <= 15.0512) || (*(R + 15) >= 15.0512)) 484 | ) { 485 | cout << "Emotions = Sad(CF = 0.53)" << endl; 486 | } 487 | //Surprise 488 | //Rule 11 489 | if ( 490 | ((*(R + 30) >= 126.304 && *(R + 30) <= 149.554) || (*(R + 30) <= 126.304)) 491 | && ((*(R + 34) >= 33.9611 && *(R + 34) <= 34.0477) || (*(R + 34) >= 34.0477)) 492 | ) { 493 | cout << "Emotions = Surprise(CF = 0.99)" << endl; 494 | } 495 | //Rule 12 496 | if ( 497 | ((*(R + 8) >= 40.2461 && *(R + 8) <= 40.3331) || (*(R + 8) >= 40.3331)) 498 | && ((*(R + 51) >= 45.1865 && *(R + 51) <= 45.2721) || (*(R + 30) <= 45.1865)) 499 | ) { 500 | cout << "Emotions = Surprise(CF = 0.98)" << endl; 501 | } 502 | //Rule 13 503 | if ( 504 | ((*(R + 17) >= 17.0409 && *(R + 17) <= 17.0477) || (*(R + 17) >= 17.0477)) 505 | && ((*(R + 17) >= 17.1027 && *(R + 17) <= 17.1054) || (*(R + 17) <= 17.1027)) 506 | ) { 507 | cout << "Emotions = Surprise(CF = 0.68)" << endl; 508 | } 509 | //Rule 14 510 | if ( 511 | ((*(R + 48) >= 42.3974 && *(R + 48) <= 43.2472) || (*(R + 48) <= 42.3974)) 512 | ) { 513 | cout << "Emotions = Surprise(CF = 0.60)" << endl; 514 | } 515 | //Fear 516 | //Rule 15 517 | if ( 518 | ((*(R + 26) >= 38.6598 && *(R + 26) <= 40.2364) || (*(R + 26) >= 40.2364)) 519 | && ((*(R + 50) >= 3.61388 && *(R + 50) <= 3.62035) || (*(R + 50) >= 3.62035)) 520 | && ((*(R + 19) >= 86.8202 && *(R + 19) <= 87.1376) || (*(R + 19) >= 87.1376)) 521 | && ((*(R + 32) >= 22.3228 && *(R + 32) <= 22.4199) || (*(R + 32) <= 22.3228)) 522 | && ((*(R + 44) >= 48.7314 && *(R + 44) <= 48.8141) || (*(R + 44) >= 48.8141)) 523 | ) { 524 | cout << "Emotions = Fear(CF = 0.90)" << endl; 525 | } 526 | //Rule 16 527 | if ( 528 | ((*(R + 49) >= 95.8395 && *(R + 49) <= 96.2791) || (*(R + 49) <= 95.8395)) 529 | && ((*(R + 49) >= 93.3419 && *(R + 49) <= 94.0108) || (*(R + 49) >= 94.0108)) 530 | && ((*(R + 8) >= 35.0195 && *(R + 8) <= 35.6748) || (*(R + 8) >= 35.6748)) 531 | && ((*(R + 30) >= 112.548 && *(R + 30) <= 127.911) || (*(R + 30) >= 127.911)) 532 | ) { 533 | cout << "Emotions = Fear(CF = 0.84)" << endl; 534 | } 535 | //Rule 17 536 | if ( 537 | ((*(R + 33) >= 113.647 && *(R + 33) <= 120.77) || (*(R + 33) >= 120.77)) 538 | && ((*(R + 35) >= 19.8265 && *(R + 35) <= 20.2393) || (*(R + 35) >= 20.2393)) 539 | && ((*(R + 22) >= 41.6335 && *(R + 22) <= 41.8665) || (*(R + 22) >= 41.8665)) 540 | && ((*(R + 51) >= 34.8844 && *(R + 51) <= 35.0913) || (*(R + 51) >= 35.0913)) 541 | && ((*(R + 12) >= 56.658 && *(R + 12) <= 56.7193) || (*(R + 12) <= 56.658)) 542 | ) { 543 | cout << "Emotions = Fear(CF = 0.87)" << endl; 544 | } 545 | //Disgust 546 | //Rule 18 547 | if ( 548 | ((*(R + 26) >= 26.9489 && *(R + 26) <= 27.5973) || (*(R + 26) <= 26.9489)) 549 | && ((*(R + 8) >= 25.3267 && *(R + 8) <= 26.1046) || (*(R + 8) <= 25.3267)) 550 | && ((*(R + 21) >= 59.7436 && *(R + 21) <= 60.0864) || (*(R + 21) >= 60.0864)) 551 | ) { 552 | cout << "Emotions = Disgust(CF = 0.96)" << endl; 553 | } 554 | //Rule 19 555 | if ( 556 | ((*(R + 26) >= 35.8377 && *(R + 26) <= 36.2538) || (*(R + 26) <= 35.8377)) 557 | && ((*(R + 30) >= 151.318 && *(R + 30) <= 151.76) || (*(R + 30) <= 151.76)) 558 | && ((*(R + 35) >= 18.6981 && *(R + 35) <= 18.7149) || (*(R + 35) >= 18.7149)) 559 | && ((*(R + 8) >= 25.9913 && *(R + 8) <= 26.0754) || (*(R + 8) <= 25.9913)) 560 | && ((*(R + 50) >= 3.1012 && *(R + 50) <= 3.21448) || (*(R + 50) >= 3.21448)) 561 | && ((*(R + 51) >= 40.4826 && *(R + 51) <= 40.6054) || (*(R + 51) <= 40.4826)) 562 | ) { 563 | cout << "Emotions = Disgust(CF = 0.96)" << endl; 564 | } 565 | //Rule 20 566 | if ( 567 | ((*(R + 26) >= 35.4509 && *(R + 26) <= 35.8195) || (*(R + 26) <= 35.4509)) 568 | && ((*(R + 30) >= 160.168 && *(R + 30) <= 160.675) || (*(R + 30) <= 160.168)) 569 | && ((*(R + 42) >= 91.4652 && *(R + 42) <= 91.8476) || (*(R + 42) >= 91.8476)) 570 | && ((*(R + 9) >= 28.8713 && *(R + 9) <= 31.4661) || (*(R + 9) >= 31.4661)) 571 | && ((*(R + 16) >= 151.557 && *(R + 16) <= 151.794) || (*(R + 16) <= 151.557)) 572 | ) { 573 | cout << "Emotions = Disgust(CF = 0.94)" << endl; 574 | } 575 | //Rule 21 576 | if ( 577 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.3107) || (*(R + 28) <= 38.1572)) 578 | && ((*(R + 31) >= 7.43669 && *(R + 31) <= 10.1433) || (*(R + 31) >= 10.1433)) 579 | && ((*(R + 26) >= 30.9638 && *(R + 26) <= 31.4521) || (*(R + 26) <= 30.9638)) 580 | && ((*(R + 4) >= 46.4321 && *(R + 4) <= 46.5831) || (*(R + 4) <= 46.4321)) 581 | && ((*(R + 45) >= 74.4759 && *(R + 45) <= 75.0686) || (*(R + 45) >= 75.0686)) 582 | ) { 583 | cout << "Emotions = Disgust(CF = 0.94)" << endl; 584 | } 585 | //Rule 22 586 | if ( 587 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.3782) || (*(R + 28) <= 38.1572)) 588 | && ((*(R + 32) >= 8.70181 && *(R + 32) <= 8.71473) || (*(R + 32) >= 8.71473)) 589 | && ((*(R + 9) >= 35.9909 && *(R + 9) <= 36.1861) || (*(R + 9) >= 36.1861)) 590 | && ((*(R + 8) >= 27.817 && *(R + 8) <= 27.929) || (*(R + 8) <= 27.817)) 591 | && ((*(R + 14) >= 46.8177 && *(R + 14) <= 47.5595) || (*(R + 14) <= 46.8177)) 592 | && ((*(R + 8) >= 17.2892 && *(R + 8) <= 18.9069) || (*(R + 8) >= 18.9069)) 593 | ) { 594 | cout << "Emotions = Disgust(CF = 0.93)" << endl; 595 | } 596 | //Rule 23 597 | if ( 598 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 39.6233) || (*(R + 28) <= 38.1572)) 599 | && ((*(R + 32) >= 15.3773 && *(R + 32) <= 15.6442) || (*(R + 32) >= 15.6442)) 600 | && ((*(R + 23) >= 90 && *(R + 23) <= 92.4002) || (*(R + 23) <= 90)) 601 | && ((*(R + 6) >= 34.6599 && *(R + 6) <= 35.2154) || (*(R + 6) >= 35.2154)) 602 | && ((*(R + 2) >= 144.482 && *(R + 2) <= 144.492) || (*(R + 2) >= 144.492)) 603 | ) { 604 | cout << "Emotions = Disgust(CF = 0.90)" << endl; 605 | } 606 | //Rule 24 607 | if ( 608 | ((*(R + 10) >= 26.4547 && *(R + 10) <= 27.2133) || (*(R + 10) <= 26.4547)) 609 | && ((*(R + 17) >= 35.5078 && *(R + 17) <= 35.5856) || (*(R + 17) >= 35.5856)) 610 | && ((*(R + 11) >= 22.9748 && *(R + 11) <= 23.0757) || (*(R + 11) <= 22.9748)) 611 | && ((*(R + 7) >= 24.8358 && *(R + 7) <= 24.9599) || (*(R + 7) >= 24.9599)) 612 | && ((*(R + 0) >= 24.8358 && *(R + 0) <= 24.9599) || (*(R + 0) <= 24.8358)) 613 | ) { 614 | cout << "Emotions = Disgust(CF = 0.86)" << endl; 615 | } 616 | //Anger 617 | //Rule 25 618 | if ( 619 | ((*(R + 7) >= 115.258 && *(R + 7) <= 117.446) || (*(R + 7) >= 117.446)) 620 | && ((*(R + 34) >= 17.2653 && *(R + 34) <= 19.2307) || (*(R + 34) <= 17.2653)) 621 | && ((*(R + 30) >= 152.184 && *(R + 30) <= 152.257) || (*(R + 30) >= 152.257)) 622 | && ((*(R + 36) >= 141.526 && *(R + 36) <= 141.77) || (*(R + 36) >= 141.77)) 623 | ) { 624 | cout << "Emotions = Anger(CF = 0.93)" << endl; 625 | } 626 | //Rule 26 627 | if ( 628 | ((*(R + 11) >= 122.859 && *(R + 11) <= 124.442) || (*(R + 11) >= 124.442)) 629 | && ((*(R + 22) >= 33.0558 && *(R + 22) <= 33.6901) || (*(R + 22) >= 33.6901)) 630 | && ((*(R + 8) >= 21.139 && *(R + 8) <= 21.5363) || (*(R + 8) <= 21.139)) 631 | ) { 632 | cout << "Emotions = Anger(CF = 0.90)" << endl; 633 | } 634 | //Rule 27 635 | if ( 636 | ((*(R + 11) >= 114.76 && *(R + 11) <= 115.918) || (*(R + 11) >= 115.918)) 637 | && ((*(R + 34) >= 17.0449 && *(R + 34) <= 17.049) || (*(R + 34) <= 17.0449)) 638 | && ((*(R + 39) >= 137.883 && *(R + 39) <= 138.125) || (*(R + 39) <= 137.883)) 639 | && ((*(R + 19) >= 86.0353 && *(R + 19) <= 86.1859) || (*(R + 19) >= 86.1859)) 640 | ) { 641 | cout << "Emotions = Anger(CF = 0.82)" << endl; 642 | } 643 | //Rule 28 644 | if ( 645 | ((*(R + 11) >= 123.048 && *(R + 11) <= 124.509) || (*(R + 11) >= 124.509)) 646 | && ((*(R + 51) >= 33.6707 && *(R + 51) <= 33.6995) || (*(R + 51) <= 33.6707)) 647 | && ((*(R + 18) >= 52.6819 && *(R + 18) <= 53.231) || (*(R + 18) >= 53.231)) 648 | ) { 649 | cout << "Emotions = Anger(CF = 0.83)" << endl; 650 | } 651 | //Rule 29 652 | if ( 653 | ((*(R + 34) >= 22.8636 && *(R + 34) <= 23.1986) || (*(R + 34) <= 22.8636)) 654 | && ((*(R + 31) >= 10.1964 && *(R + 31) <= 10.3628) || (*(R + 31) <= 10.1964)) 655 | && ((*(R + 46) >= 107.21 && *(R + 46) <= 107.447) || (*(R + 46) <= 107.21)) 656 | && ((*(R + 47) >= 3.29176 && *(R + 47) <= 3.4244) || (*(R + 47) <= 3.29176)) 657 | ) { 658 | cout << "Emotions = Anger(CF = 0.82)" << endl; 659 | } 660 | //Rule 30 661 | if ( 662 | ((*(R + 5) >= 68.4986 && *(R + 5) <= 68.8774) || (*(R + 5) <= 68.4986)) 663 | && ((*(R + 35) >= 18.6981 && *(R + 35) <= 18.7149) || (*(R + 35) <= 18.6981)) 664 | && ((*(R + 13) >= 66.8664 && *(R + 13) <= 67.7345) || (*(R + 13) <= 66.8664)) 665 | && ((*(R + 51) >= 39.3543 && *(R + 51) <= 39.4115) || (*(R + 51) <= 39.3543)) 666 | ) { 667 | cout << "Emotions = Anger(CF = 0.92)" << endl; 668 | } 669 | //Neutral 670 | //Rule 31 671 | if ( 672 | ((*(R + 34) >= 26.5651 && *(R + 34) <= 26.7055) || (*(R + 34) <= 26.5651)) 673 | && ((*(R + 20) >= 39.2894 && *(R + 20) <= 39.6233) || (*(R + 20) >= 39.6233)) 674 | && ((*(R + 45) >= 78.9618 && *(R + 45) <= 789745) || (*(R + 45) <= 78.9618)) 675 | && ((*(R + 38) >= 19.9831 && *(R + 38) <= 20.0674) || (*(R + 38) >= 20.0674)) 676 | && ((*(R + 8) >= 35.4327 && *(R + 8) <= 36.92) || (*(R + 8) <= 35.4327)) 677 | && ((*(R + 30) >= 156.633 && *(R + 30) <= 157.079) || (*(R + 30) <= 156.633)) 678 | && ((*(R + 44) >= 38.5527 && *(R + 44) <= 38.6598) || (*(R + 44) >= 38.6598)) 679 | ) { 680 | cout << "Emotions = Neutral(CF = 0.98)" << endl; 681 | } 682 | //Rule 32 683 | if ( 684 | ((*(R + 35) >= 27.2363 && *(R + 35) <= 27.3464) || (*(R + 35) <= 27.2363)) 685 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.6598) || (*(R + 28) >= 38.6598)) 686 | && ((*(R + 6) >= 38.9806 && *(R + 6) <= 39.1219) || (*(R + 6) >= 39.1219)) 687 | && ((*(R + 50) >= 3.61388 && *(R + 50) <= 3.64164) || (*(R + 50) <= 3.61388)) 688 | && ((*(R + 45) >= 79.5199 && *(R + 45) <= 79.6952) || (*(R + 45) <= 79.5199)) 689 | ) { 690 | cout << "Emotions = Neutral(CF = 0.95)" << endl; 691 | } 692 | //Rule 33 693 | if ( 694 | ((*(R + 34) >= 28.1313 && *(R + 34) <= 28.9551) || (*(R + 34) <= 28.1313)) 695 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.4537) || (*(R + 28) >= 38.4537)) 696 | && ((*(R + 9) >= 39.7376 && *(R + 9) <= 39.8419) || (*(R + 9) >= 39.8419)) 697 | && ((*(R + 19) >= 86.6335 && *(R + 19) <= 87.0364) || (*(R + 19) <= 86.6335)) 698 | && ((*(R + 50) >= 3.61207 && *(R + 50) <= 3.62575) || (*(R + 50) <= 3.61207)) 699 | ) { 700 | cout << "Emotions = Neutral(CF = 0.93)" << endl; 701 | } 702 | //Rule 34 703 | if ( 704 | ((*(R + 34) >= 26.8913 && *(R + 34) <= 26.9486) || (*(R + 34) <= 26.8913)) 705 | && ((*(R + 20) >= 33.6901 && *(R + 20) <= 35.8195) || (*(R + 20) >= 35.8195)) 706 | && ((*(R + 12) >= 58.3317 && *(R + 12) <= 58.6666) || (*(R + 12) <= 58.3317)) 707 | && ((*(R + 22) >= 38.7933 && *(R + 22) <= 39.0939) || (*(R + 22) <= 38.7933)) 708 | && ((*(R + 33) >= 152.969 && *(R + 33) <= 152.971) || (*(R + 33) <= 152.969)) 709 | && ((*(R + 43) >= 50.7021 && *(R + 43) <= 50.8786) || (*(R + 43) >= 50.8786)) 710 | ) { 711 | cout << "Emotions = Neutral(CF = 0.94)" << endl; 712 | } 713 | //Rule 35 714 | if ( 715 | ((*(R + 33) >= 88.1516 && *(R + 33) <= 121.909) || (*(R + 33) >= 121.909)) 716 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.6238) || (*(R + 28) >= 38.6238)) 717 | && ((*(R + 51) >= 35.422 && *(R + 51) <= 36.0181) || (*(R + 51) <= 35.422)) 718 | && ((*(R + 43) >= 51.481 && *(R + 43) <= 51.6839) || (*(R + 43) <= 51.481)) 719 | && ((*(R + 32) >= 13.4486 && *(R + 32) <= 13.6831) || (*(R + 32) >= 13.6831)) 720 | && ((*(R + 26) >= 43.2643 && *(R + 26) <= 43.3844) || (*(R + 26) <= 43.2643)) 721 | && ((*(R + 36) >= 146.691 && *(R + 36) <= 146.723) || (*(R + 36) <= 146.691)) 722 | ) { 723 | cout << "Emotions = Neutral(CF = 0.97)" << endl; 724 | } 725 | //Rule 36 726 | if ( 727 | ((*(R + 35) >= 29.0332 && *(R + 35) <= 32.685) || (*(R + 35) <= 29.0332)) 728 | && ((*(R + 8) >= 26.5308 && *(R + 8) <= 26.5651) || (*(R + 8) >= 26.5651)) 729 | && ((*(R + 29) >= 85.6013 && *(R + 29) <= 85.9144) || (*(R + 29) <= 85.6013)) 730 | && ((*(R + 44) >= 51.953 && *(R + 44) <= 52.0023) || (*(R + 44) <= 51.953)) 731 | && ((*(R + 5) >= 75.7986 && *(R + 5) <= 76.0875) || (*(R + 5) <= 75.7986)) 732 | && ((*(R + 18) >= 61.0736 && *(R + 18) <= 64.9831) || (*(R + 18) <= 61.0736)) 733 | ) { 734 | cout << "Emotions = Neutral(CF = 0.95)" << endl; 735 | } 736 | //Rule 37 737 | if ( 738 | ((*(R + 33) >= 118.764 && *(R + 33) <= 120.426) || (*(R + 33) >= 120.426)) 739 | && ((*(R + 27) >= 57.0948 && *(R + 27) <= 64.7327) || (*(R + 27) <= 57.0948)) 740 | && ((*(R + 49) >= 104.517 && *(R + 49) <= 104.534) || (*(R + 49) >= 104.534)) 741 | && ((*(R + 51) >= 33.918 && *(R + 51) <= 34.2595) || (*(R + 51) <= 33.918)) 742 | && ((*(R + 5) >= 73.3444 && *(R + 5) <= 73.7261) || (*(R + 5) >= 73.7261)) 743 | && ((*(R + 33) >= 136.4 && *(R + 33) <= 149.673) || (*(R + 33) <= 136.4)) 744 | ) { 745 | cout << "Emotions = Neutral(CF = 0.96)" << endl; 746 | } 747 | else { 748 | cout << "No emotions detected" << endl; 749 | } 750 | 751 | //////////////////////////////////////////////////////////////// 752 | //////////////////////////////////////////////////////////////// 753 | //////////////////////////////////////////////////////////////// 754 | // a pointer to an int. 755 | // double *EuclideanDistanceArrayPointer; 756 | // EuclideanDistanceArrayPointer = setPointsToCalculateEuclideanDistance(shape); 757 | // for (int i = 0; i < 54; i++) 758 | // std::cout << "*(Pointer + " << i << ") : " << *(EuclideanDistanceArrayPointer + i) << endl; 759 | 760 | // You get the idea, you can get all the face part locations if 761 | // you want them. Here we just store them in shapes so we can 762 | // put them on the screen. 763 | shapes.push_back(shape); 764 | } 765 | } 766 | 767 | // Now let's view our face poses on the screen. 768 | win.clear_overlay(); 769 | win.set_image(img); 770 | win.add_overlay(render_face_detections(shapes)); 771 | win.add_overlay(render_face_detections_lines(shapes)); 772 | 773 | //win.set_title("Emotions = Happy(CF = 0.97)"); 774 | 775 | // We can also extract copies of each face that are cropped, rotated upright, 776 | // and scaled to a standard size as shown here: 777 | // dlib::array > face_chips; 778 | // dlib::extract_image_chips(img, get_face_chip_details(shapes), face_chips); 779 | // win_faces.set_image(tile_images(face_chips)); 780 | 781 | std::cout << "Hit enter to process the next image..." << endl; 782 | //sleep(1000); 783 | std::cin.get(); 784 | } 785 | } 786 | } 787 | catch (exception& e) 788 | { 789 | std::cout << "\nexception thrown!" << endl; 790 | std::cout << e.what() << endl; 791 | } 792 | getchar(); 793 | } 794 | 795 | // ---------------------------------------------------------------------------------------- 796 | 797 | // ------------------------- 798 | int webcam() 799 | { 800 | 801 | try 802 | { 803 | cv::VideoCapture webcam(0); 804 | if (!webcam.isOpened()) 805 | { 806 | cerr << "Unable to connect to camera" << endl; 807 | return 1; 808 | } 809 | image_window win; 810 | 811 | // Load face detection and pose estimation models. 812 | frontal_face_detector detector = get_frontal_face_detector(); 813 | shape_predictor pose_model; 814 | deserialize("C:\\Users\\kbh\\Desktop\\dlib-master\\examples\\build\\Debug\\shape_predictor_68_face_landmarks.dat") >> pose_model; 815 | 816 | // Grab and process frames until the main window is closed by the user. 817 | while (!win.is_closed()) 818 | { 819 | // Grab a frame 820 | cv::Mat temp; 821 | webcam >> temp; 822 | // Turn OpenCV's Mat into something dlib can deal with. Note that this just 823 | // wraps the Mat object, it doesn't copy anything. So cimg is only valid as 824 | // long as temp is valid. Also don't do anything to temp that would cause it 825 | // to reallocate the memory which stores the image as that will make cimg 826 | // contain dangling pointers. This basically means you shouldn't modify temp 827 | // while using cimg. 828 | cv_image cimg(temp); 829 | 830 | //Rotate cimg to img 831 | array2d img; 832 | assign_image(img, cimg); 833 | flip_image_left_right(cimg, img); //You can use img insted of cimg to rotate the image 834 | 835 | 836 | 837 | full_object_detection shape; 838 | 839 | // Detect faces 840 | std::vector faces = detector(img); 841 | 842 | // Find the pose of each face. 843 | std::vector shapes; 844 | for (unsigned long i = 0; i < faces.size(); ++i) { 845 | shapes.push_back(pose_model(img, faces[i])); 846 | shape = pose_model(img, faces[i]); 847 | } 848 | 849 | // Display it all on the screen 850 | win.clear_overlay(); 851 | win.set_image(img); 852 | // Array of the emotions to display 853 | string emotions[7] = {"Happy", "Sad", "Surprise", "Fear", "Disgust", "Anger", "Neutral"}; 854 | //To display the timestamp of each emotion 855 | time_t timev; 856 | 857 | // A pointer to a long double to calculate the euclidean distance between the landmark points. 858 | const long double *EuclideanDistanceArrayPointer; 859 | EuclideanDistanceArrayPointer = setPointsToCalculateEuclideanDistance(shape); 860 | 861 | // A pointer to a long double to calculate the cosines between the three sides of the triangle. 862 | const long double *CosinesArrayPointer; 863 | CosinesArrayPointer = callCalculateCosines(EuclideanDistanceArrayPointer); 864 | 865 | // A pointer to a long double to calculate the arc cosines of the angles. 866 | const long double *ArcCosinesArrayPointer; 867 | ArcCosinesArrayPointer = callCalculateArcCosines(CosinesArrayPointer); 868 | 869 | //////////////////////////////////////////////////////////////// 870 | //*(ArcCosinesArrayPointer + i) 871 | const long double *R = ArcCosinesArrayPointer; 872 | //Happy 873 | //Rule 1 874 | if ( 875 | ((*(R + 30) >= 159.608 && *(R + 30) <= 160.424) || (*(R + 30) >= 160.424)) 876 | && (!(*(R + 30) >= 160.168 && *(R + 30) <= 160.675) || (!*(R + 30) <= 160.168)) 877 | && ((*(R + 35) >= 30.0655 && *(R + 35) <= 30.2536) || (*(R + 35) >= 30.2536 878 | && (!(*(R + 35) > 30.2536 && *(R + 35) <= 32.685)))) 879 | ) { 880 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Happy(CF = 0.97)" << endl; 881 | dlib::rectangle rr(long(0), long(0), long(0), long(0)); 882 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[0].append(" 0.97"))); 883 | 884 | } 885 | //Rule 2 886 | if ( 887 | ((*(R + 31) >= 9.85016 && *(R + 31) <= 9.96286) || (*(R + 31) <= 9.85016)) 888 | && ((*(R + 51) >= 35.5078 && *(R + 51) <= 35.5856) || (*(R + 31) >= 35.5856)) 889 | && ((*(R + 10) >= 22.9748 && *(R + 10) <= 23.0757) || (*(R + 10) <= 23.0757)) 890 | && ((*(R + 0) >= 24.8358 && *(R + 0) <= 24.9599) || (*(R + 0) <= 24.8358)) 891 | ) { 892 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Happy(CF = 0.98)" << endl; 893 | dlib::rectangle rr(long(0), long(0), long(0), long(0)); 894 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[0].append(" 0.98"))); 895 | } 896 | //Rule 3 897 | if ( 898 | ((*(R + 32) >= 13.8022 && *(R + 32) <= 14.6793) || (*(R + 32) <= 13.8022)) 899 | && ((*(R + 34) >= 25.1647 && *(R + 34) <= 25.4542) || (*(R + 34) >= 25.4542)) 900 | && ((*(R + 50) >= 3.7724 && *(R + 50) <= 3.79234) || (*(R + 50) >= 3.79234)) 901 | && ((*(R + 48) >= 64.551 && *(R + 48) <= 66.8476) || (*(R + 48) >= 66.8476)) 902 | ) { 903 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Happy(CF = 0.90)" << endl; 904 | dlib::rectangle rr(long(0), long(0), long(0), long(0)); 905 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[0].append(" 0.90"))); 906 | 907 | } 908 | //Rule 4 909 | if ( 910 | ((*(R + 31) >= 12.4074 && *(R + 31) <= 16.2636) || (*(R + 31) <= 12.4074)) 911 | && ((*(R + 35) >= 25.6426 && *(R + 35) <= 27.0878) || (*(R + 35) >= 25.0878)) 912 | && ((*(R + 37) >= 21.4168 && *(R + 37) <= 21.5797) || (*(R + 37) >= 21.5797)) 913 | && ((*(R + 0) >= 21.1748 && *(R + 0) <= 21.9187) || (*(R + 0) <= 21.1748)) 914 | ) { 915 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Happy(CF = 0.95)" << endl; 916 | dlib::rectangle rr(long(0), long(0), long(0), long(0)); 917 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[0].append(" 0.95"))); 918 | 919 | } 920 | //Rule 5 921 | if ( 922 | ((*(R + 32) >= 5.15255 && *(R + 32) <= 5.16574) || (*(R + 32) <= 5.15255)) 923 | && ((*(R + 32) >= 4.97626 && *(R + 32) <= 5.05265) || (*(R + 32) >= 5.05265)) 924 | ) { 925 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Happy(CF = 0.66)" << endl; 926 | dlib::rectangle rr(long(0), long(0), long(0), long(0)); 927 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[0].append(" 0.66"))); 928 | 929 | } 930 | //Sad 931 | //Rule 6 932 | if ( 933 | ((*(R + 34) >= 15.1591 && *(R + 34) <= 15.3646) || (*(R + 34) >= 15.1591)) 934 | && ((*(R + 42) >= 73.6283 && *(R + 42) <= 74.5163) || (*(R + 42) <= 73.6283)) 935 | && ((*(R + 32) >= 17.9646 && *(R + 32) <= 17.9917) || (*(R + 32) >= 17.9917)) 936 | && ((*(R + 13) >= 68.61 && *(R + 13) <= 70.3929) || (*(R + 13) >= 70.3929)) 937 | && ((*(R + 37) >= 22.5483 && *(R + 37) <= 22.8643) || (*(R + 37) <= 22.5483)) 938 | ) { 939 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Sad(CF = 0.94)" << endl; 940 | dlib::rectangle rr(long(0), long(50), long(0), long(50)); 941 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[1].append(" 0.94"))); 942 | 943 | } 944 | //Rule 7 945 | if ( 946 | ((*(R + 33) >= 142.341 && *(R + 33) <= 142.606) || (*(R + 33) >= 142.606)) 947 | && ((*(R + 44) >= 51.9081 && *(R + 44) <= 52.9607) || (*(R + 44) >= 52.9607)) 948 | && ((*(R + 50) >= 3.15842 && *(R + 50) <= 3.18719) || (*(R + 50) <= 3.15842)) 949 | && ((*(R + 31) >= 14.1431 && *(R + 31) <= 14.4425) || (*(R + 31) >= 14.4425)) 950 | ) { 951 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Sad(CF = 0.82)" << endl; 952 | dlib::rectangle rr(long(0), long(20), long(0), long(20)); 953 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[1].append(" 0.82"))); 954 | 955 | } 956 | //Rule 8 957 | if ( 958 | ((*(R + 46) >= 84.9609 && *(R + 46) <= 85.074) || (*(R + 46) <= 84.9609)) 959 | && ((*(R + 51) >= 36.248 && *(R + 51) <= 36.6846) || (*(R + 51) >= 36.6846)) 960 | ) { 961 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Sad(CF = 0.81)" << endl; 962 | dlib::rectangle rr(long(0), long(20), long(0), long(20)); 963 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[1].append(" 0.81"))); 964 | 965 | } 966 | //Rule 9 967 | if ( 968 | ((*(R + 42) >= 54.362 && *(R + 42) <= 54.4623) || (*(R + 42) <= 54.362)) 969 | && ((*(R + 3) >= 49.4672 && *(R + 3) <= 53.9726) || (*(R + 3) >= 53.9726)) 970 | && ((*(R + 18) >= 48.7314 && *(R + 18) <= 48.7806) || (*(R + 18) >= 48.7806)) 971 | ) { 972 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Sad(CF = 0.84)" << endl; 973 | dlib::rectangle rr(long(0), long(20), long(0), long(20)); 974 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[1].append(" 0.84"))); 975 | 976 | } 977 | //Rule 10 978 | if ( 979 | ((*(R + 1) >= 6.82602 && *(R + 1) <= 7.03498) || (*(R + 1) <= 6.82602)) 980 | && ((*(R + 15) >= 14.5889 && *(R + 15) <= 15.0512) || (*(R + 15) >= 15.0512)) 981 | ) { 982 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Sad(CF = 0.53)" << endl; 983 | dlib::rectangle rr(long(0), long(20), long(0), long(20)); 984 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[1].append(" 0.53"))); 985 | 986 | } 987 | //Surprise 988 | //Rule 11 989 | if ( 990 | ((*(R + 30) >= 126.304 && *(R + 30) <= 149.554) || (*(R + 30) <= 126.304)) 991 | && ((*(R + 34) >= 33.9611 && *(R + 34) <= 34.0477) || (*(R + 34) >= 34.0477)) 992 | ) { 993 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Surprise(CF = 0.99)" << endl; 994 | dlib::rectangle rr(long(0), long(40), long(0), long(40)); 995 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[2].append(" 0.99"))); 996 | } 997 | //Rule 12 998 | if ( 999 | ((*(R + 8) >= 40.2461 && *(R + 8) <= 40.3331) || (*(R + 8) >= 40.3331)) 1000 | && ((*(R + 51) >= 45.1865 && *(R + 51) <= 45.2721) || (*(R + 30) <= 45.1865)) 1001 | ) { 1002 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Surprise(CF = 0.98)" << endl; 1003 | dlib::rectangle rr(long(0), long(40), long(0), long(40)); 1004 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[2].append(" 0.98"))); 1005 | 1006 | } 1007 | //Rule 13 1008 | if ( 1009 | ((*(R + 17) >= 17.0409 && *(R + 17) <= 17.0477) || (*(R + 17) >= 17.0477)) 1010 | && ((*(R + 17) >= 17.1027 && *(R + 17) <= 17.1054) || (*(R + 17) <= 17.1027)) 1011 | ) { 1012 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Surprise(CF = 0.68)" << endl; 1013 | dlib::rectangle rr(long(0), long(40), long(0), long(40)); 1014 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[2].append(" 0.68"))); 1015 | } 1016 | //Rule 14 1017 | if ( 1018 | ((*(R + 48) >= 42.3974 && *(R + 48) <= 43.2472) || (*(R + 48) <= 42.3974)) 1019 | ) { 1020 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Surprise(CF = 0.60)" << endl; 1021 | dlib::rectangle rr(long(0), long(40), long(0), long(40)); 1022 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[2].append(" 0.60"))); 1023 | } 1024 | //Fear 1025 | //Rule 15 1026 | if ( 1027 | ((*(R + 26) >= 38.6598 && *(R + 26) <= 40.2364) || (*(R + 26) >= 40.2364)) 1028 | && ((*(R + 50) >= 3.61388 && *(R + 50) <= 3.62035) || (*(R + 50) >= 3.62035)) 1029 | && ((*(R + 19) >= 86.8202 && *(R + 19) <= 87.1376) || (*(R + 19) >= 87.1376)) 1030 | && ((*(R + 32) >= 22.3228 && *(R + 32) <= 22.4199) || (*(R + 32) <= 22.3228)) 1031 | && ((*(R + 44) >= 48.7314 && *(R + 44) <= 48.8141) || (*(R + 44) >= 48.8141)) 1032 | ) { 1033 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Fear(CF = 0.90)" << endl; 1034 | dlib::rectangle rr(long(0), long(60), long(0), long(60)); 1035 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[3].append(" 0.90"))); 1036 | 1037 | } 1038 | //Rule 16 1039 | if ( 1040 | ((*(R + 49) >= 95.8395 && *(R + 49) <= 96.2791) || (*(R + 49) <= 95.8395)) 1041 | && ((*(R + 49) >= 93.3419 && *(R + 49) <= 94.0108) || (*(R + 49) >= 94.0108)) 1042 | && ((*(R + 8) >= 35.0195 && *(R + 8) <= 35.6748) || (*(R + 8) >= 35.6748)) 1043 | && ((*(R + 30) >= 112.548 && *(R + 30) <= 127.911) || (*(R + 30) >= 127.911)) 1044 | ) { 1045 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Fear(CF = 0.84)" << endl; 1046 | dlib::rectangle rr(long(0), long(60), long(0), long(60)); 1047 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[3].append(" 0.84"))); 1048 | } 1049 | //Rule 17 1050 | if ( 1051 | ((*(R + 33) >= 113.647 && *(R + 33) <= 120.77) || (*(R + 33) >= 120.77)) 1052 | && ((*(R + 35) >= 19.8265 && *(R + 35) <= 20.2393) || (*(R + 35) >= 20.2393)) 1053 | && ((*(R + 22) >= 41.6335 && *(R + 22) <= 41.8665) || (*(R + 22) >= 41.8665)) 1054 | && ((*(R + 51) >= 34.8844 && *(R + 51) <= 35.0913) || (*(R + 51) >= 35.0913)) 1055 | && ((*(R + 12) >= 56.658 && *(R + 12) <= 56.7193) || (*(R + 12) <= 56.658)) 1056 | ) { 1057 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Fear(CF = 0.87)" << endl; 1058 | dlib::rectangle rr(long(0), long(60), long(0), long(60)); 1059 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[3].append(" 0.87"))); 1060 | } 1061 | //Disgust 1062 | //Rule 18 1063 | if ( 1064 | ((*(R + 26) >= 26.9489 && *(R + 26) <= 27.5973) || (*(R + 26) <= 26.9489)) 1065 | && ((*(R + 8) >= 25.3267 && *(R + 8) <= 26.1046) || (*(R + 8) <= 25.3267)) 1066 | && ((*(R + 21) >= 59.7436 && *(R + 21) <= 60.0864) || (*(R + 21) >= 60.0864)) 1067 | ) { 1068 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.96)" << endl; 1069 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1070 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.96"))); 1071 | 1072 | } 1073 | //Rule 19 1074 | if ( 1075 | ((*(R + 26) >= 35.8377 && *(R + 26) <= 36.2538) || (*(R + 26) <= 35.8377)) 1076 | && ((*(R + 30) >= 151.318 && *(R + 30) <= 151.76) || (*(R + 30) <= 151.76)) 1077 | && ((*(R + 35) >= 18.6981 && *(R + 35) <= 18.7149) || (*(R + 35) >= 18.7149)) 1078 | && ((*(R + 8) >= 25.9913 && *(R + 8) <= 26.0754) || (*(R + 8) <= 25.9913)) 1079 | && ((*(R + 50) >= 3.1012 && *(R + 50) <= 3.21448) || (*(R + 50) >= 3.21448)) 1080 | && ((*(R + 51) >= 40.4826 && *(R + 51) <= 40.6054) || (*(R + 51) <= 40.4826)) 1081 | ) { 1082 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.96)" << endl; 1083 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1084 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.96"))); 1085 | } 1086 | //Rule 20 1087 | if ( 1088 | ((*(R + 26) >= 35.4509 && *(R + 26) <= 35.8195) || (*(R + 26) <= 35.4509)) 1089 | && ((*(R + 30) >= 160.168 && *(R + 30) <= 160.675) || (*(R + 30) <= 160.168)) 1090 | && ((*(R + 42) >= 91.4652 && *(R + 42) <= 91.8476) || (*(R + 42) >= 91.8476)) 1091 | && ((*(R + 9) >= 28.8713 && *(R + 9) <= 31.4661) || (*(R + 9) >= 31.4661)) 1092 | && ((*(R + 16) >= 151.557 && *(R + 16) <= 151.794) || (*(R + 16) <= 151.557)) 1093 | ) { 1094 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.94)" << endl; 1095 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1096 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.94"))); 1097 | } 1098 | //Rule 21 1099 | if ( 1100 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.3107) || (*(R + 28) <= 38.1572)) 1101 | && ((*(R + 31) >= 7.43669 && *(R + 31) <= 10.1433) || (*(R + 31) >= 10.1433)) 1102 | && ((*(R + 26) >= 30.9638 && *(R + 26) <= 31.4521) || (*(R + 26) <= 30.9638)) 1103 | && ((*(R + 4) >= 46.4321 && *(R + 4) <= 46.5831) || (*(R + 4) <= 46.4321)) 1104 | && ((*(R + 45) >= 74.4759 && *(R + 45) <= 75.0686) || (*(R + 45) >= 75.0686)) 1105 | ) { 1106 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.94)" << endl; 1107 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1108 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.94"))); 1109 | } 1110 | //Rule 22 1111 | if ( 1112 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.3782) || (*(R + 28) <= 38.1572)) 1113 | && ((*(R + 32) >= 8.70181 && *(R + 32) <= 8.71473) || (*(R + 32) >= 8.71473)) 1114 | && ((*(R + 9) >= 35.9909 && *(R + 9) <= 36.1861) || (*(R + 9) >= 36.1861)) 1115 | && ((*(R + 8) >= 27.817 && *(R + 8) <= 27.929) || (*(R + 8) <= 27.817)) 1116 | && ((*(R + 14) >= 46.8177 && *(R + 14) <= 47.5595) || (*(R + 14) <= 46.8177)) 1117 | && ((*(R + 8) >= 17.2892 && *(R + 8) <= 18.9069) || (*(R + 8) >= 18.9069)) 1118 | ) { 1119 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.93)" << endl; 1120 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1121 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.93"))); 1122 | } 1123 | //Rule 23 1124 | if ( 1125 | ((*(R + 28) >= 38.1572 && *(R + 28) <= 39.6233) || (*(R + 28) <= 38.1572)) 1126 | && ((*(R + 32) >= 15.3773 && *(R + 32) <= 15.6442) || (*(R + 32) >= 15.6442)) 1127 | && ((*(R + 23) >= 90 && *(R + 23) <= 92.4002) || (*(R + 23) <= 90)) 1128 | && ((*(R + 6) >= 34.6599 && *(R + 6) <= 35.2154) || (*(R + 6) >= 35.2154)) 1129 | && ((*(R + 2) >= 144.482 && *(R + 2) <= 144.492) || (*(R + 2) >= 144.492)) 1130 | ) { 1131 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.90)" << endl; 1132 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1133 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.90"))); 1134 | } 1135 | //Rule 24 1136 | if ( 1137 | ((*(R + 10) >= 26.4547 && *(R + 10) <= 27.2133) || (*(R + 10) <= 26.4547)) 1138 | && ((*(R + 17) >= 35.5078 && *(R + 17) <= 35.5856) || (*(R + 17) >= 35.5856)) 1139 | && ((*(R + 11) >= 22.9748 && *(R + 11) <= 23.0757) || (*(R + 11) <= 22.9748)) 1140 | && ((*(R + 7) >= 24.8358 && *(R + 7) <= 24.9599) || (*(R + 7) >= 24.9599)) 1141 | && ((*(R + 0) >= 24.8358 && *(R + 0) <= 24.9599) || (*(R + 0) <= 24.8358)) 1142 | ) { 1143 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Disgust(CF = 0.86)" << endl; 1144 | dlib::rectangle rr(long(0), long(80), long(0), long(80)); 1145 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[4].append(" 0.86"))); 1146 | } 1147 | //Anger 1148 | //Rule 25 1149 | if ( 1150 | ((*(R + 7) >= 115.258 && *(R + 7) <= 117.446) || (*(R + 7) >= 117.446)) 1151 | && ((*(R + 34) >= 17.2653 && *(R + 34) <= 19.2307) || (*(R + 34) <= 17.2653)) 1152 | && ((*(R + 30) >= 152.184 && *(R + 30) <= 152.257) || (*(R + 30) >= 152.257)) 1153 | && ((*(R + 36) >= 141.526 && *(R + 36) <= 141.77) || (*(R + 36) >= 141.77)) 1154 | ) { 1155 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.93)" << endl; 1156 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1157 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.93"))); 1158 | } 1159 | //Rule 26 1160 | if ( 1161 | ((*(R + 11) >= 122.859 && *(R + 11) <= 124.442) || (*(R + 11) >= 124.442)) 1162 | && ((*(R + 22) >= 33.0558 && *(R + 22) <= 33.6901) || (*(R + 22) >= 33.6901)) 1163 | && ((*(R + 8) >= 21.139 && *(R + 8) <= 21.5363) || (*(R + 8) <= 21.139)) 1164 | ) { 1165 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.90)" << endl; 1166 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1167 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.90"))); 1168 | } 1169 | //Rule 27 1170 | if ( 1171 | ((*(R + 11) >= 114.76 && *(R + 11) <= 115.918) || (*(R + 11) >= 115.918)) 1172 | && ((*(R + 34) >= 17.0449 && *(R + 34) <= 17.049) || (*(R + 34) <= 17.0449)) 1173 | && ((*(R + 39) >= 137.883 && *(R + 39) <= 138.125) || (*(R + 39) <= 137.883)) 1174 | && ((*(R + 19) >= 86.0353 && *(R + 19) <= 86.1859) || (*(R + 19) >= 86.1859)) 1175 | ) { 1176 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.82)" << endl; 1177 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1178 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.82"))); 1179 | } 1180 | //Rule 28 1181 | if ( 1182 | ((*(R + 11) >= 123.048 && *(R + 11) <= 124.509) || (*(R + 11) >= 124.509)) 1183 | && ((*(R + 51) >= 33.6707 && *(R + 51) <= 33.6995) || (*(R + 51) <= 33.6707)) 1184 | && ((*(R + 18) >= 52.6819 && *(R + 18) <= 53.231) || (*(R + 18) >= 53.231)) 1185 | ) { 1186 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.83)" << endl; 1187 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1188 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.83"))); 1189 | } 1190 | //Rule 29 1191 | if ( 1192 | ((*(R + 34) >= 22.8636 && *(R + 34) <= 23.1986) || (*(R + 34) <= 22.8636)) 1193 | && ((*(R + 31) >= 10.1964 && *(R + 31) <= 10.3628) || (*(R + 31) <= 10.1964)) 1194 | && ((*(R + 46) >= 107.21 && *(R + 46) <= 107.447) || (*(R + 46) <= 107.21)) 1195 | && ((*(R + 47) >= 3.29176 && *(R + 47) <= 3.4244) || (*(R + 47) <= 3.29176)) 1196 | ) { 1197 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.82)" << endl; 1198 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1199 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.82"))); 1200 | } 1201 | //Rule 30 1202 | if ( 1203 | ((*(R + 5) >= 68.4986 && *(R + 5) <= 68.8774) || (*(R + 5) <= 68.4986)) 1204 | && ((*(R + 35) >= 18.6981 && *(R + 35) <= 18.7149) || (*(R + 35) <= 18.6981)) 1205 | && ((*(R + 13) >= 66.8664 && *(R + 13) <= 67.7345) || (*(R + 13) <= 66.8664)) 1206 | && ((*(R + 51) >= 39.3543 && *(R + 51) <= 39.4115) || (*(R + 51) <= 39.3543)) 1207 | ) { 1208 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Anger(CF = 0.92)" << endl; 1209 | dlib::rectangle rr(long(0), long(100), long(0), long(100)); 1210 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[5].append(" 0.92"))); 1211 | } 1212 | //Neutral 1213 | //Rule 31 1214 | if ( 1215 | ((*(R + 34) >= 26.5651 && *(R + 34) <= 26.7055) || (*(R + 34) <= 26.5651)) 1216 | && ((*(R + 20) >= 39.2894 && *(R + 20) <= 39.6233) || (*(R + 20) >= 39.6233)) 1217 | && ((*(R + 45) >= 78.9618 && *(R + 45) <= 789745) || (*(R + 45) <= 78.9618)) 1218 | && ((*(R + 38) >= 19.9831 && *(R + 38) <= 20.0674) || (*(R + 38) >= 20.0674)) 1219 | && ((*(R + 8) >= 35.4327 && *(R + 8) <= 36.92) || (*(R + 8) <= 35.4327)) 1220 | && ((*(R + 30) >= 156.633 && *(R + 30) <= 157.079) || (*(R + 30) <= 156.633)) 1221 | && ((*(R + 44) >= 38.5527 && *(R + 44) <= 38.6598) || (*(R + 44) >= 38.6598)) 1222 | ) { 1223 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.98)" << endl; 1224 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1225 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.98"))); 1226 | } 1227 | //Rule 32 1228 | if ( 1229 | ((*(R + 35) >= 27.2363 && *(R + 35) <= 27.3464) || (*(R + 35) <= 27.2363)) 1230 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.6598) || (*(R + 28) >= 38.6598)) 1231 | && ((*(R + 6) >= 38.9806 && *(R + 6) <= 39.1219) || (*(R + 6) >= 39.1219)) 1232 | && ((*(R + 50) >= 3.61388 && *(R + 50) <= 3.64164) || (*(R + 50) <= 3.61388)) 1233 | && ((*(R + 45) >= 79.5199 && *(R + 45) <= 79.6952) || (*(R + 45) <= 79.5199)) 1234 | ) { 1235 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.95)" << endl; 1236 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1237 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.95"))); 1238 | } 1239 | //Rule 33 1240 | if ( 1241 | ((*(R + 34) >= 28.1313 && *(R + 34) <= 28.9551) || (*(R + 34) <= 28.1313)) 1242 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.4537) || (*(R + 28) >= 38.4537)) 1243 | && ((*(R + 9) >= 39.7376 && *(R + 9) <= 39.8419) || (*(R + 9) >= 39.8419)) 1244 | && ((*(R + 19) >= 86.6335 && *(R + 19) <= 87.0364) || (*(R + 19) <= 86.6335)) 1245 | && ((*(R + 50) >= 3.61207 && *(R + 50) <= 3.62575) || (*(R + 50) <= 3.61207)) 1246 | ) { 1247 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.93)" << endl; 1248 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1249 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.93"))); 1250 | } 1251 | //Rule 34 1252 | if ( 1253 | ((*(R + 34) >= 26.8913 && *(R + 34) <= 26.9486) || (*(R + 34) <= 26.8913)) 1254 | && ((*(R + 20) >= 33.6901 && *(R + 20) <= 35.8195) || (*(R + 20) >= 35.8195)) 1255 | && ((*(R + 12) >= 58.3317 && *(R + 12) <= 58.6666) || (*(R + 12) <= 58.3317)) 1256 | && ((*(R + 22) >= 38.7933 && *(R + 22) <= 39.0939) || (*(R + 22) <= 38.7933)) 1257 | && ((*(R + 33) >= 152.969 && *(R + 33) <= 152.971) || (*(R + 33) <= 152.969)) 1258 | && ((*(R + 43) >= 50.7021 && *(R + 43) <= 50.8786) || (*(R + 43) >= 50.8786)) 1259 | ) { 1260 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.94)" << endl; 1261 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1262 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.94"))); 1263 | } 1264 | //Rule 35 1265 | if ( 1266 | ((*(R + 33) >= 88.1516 && *(R + 33) <= 121.909) || (*(R + 33) >= 121.909)) 1267 | && ((*(R + 28) >= 38.1572 && *(R + 28) <= 38.6238) || (*(R + 28) >= 38.6238)) 1268 | && ((*(R + 51) >= 35.422 && *(R + 51) <= 36.0181) || (*(R + 51) <= 35.422)) 1269 | && ((*(R + 43) >= 51.481 && *(R + 43) <= 51.6839) || (*(R + 43) <= 51.481)) 1270 | && ((*(R + 32) >= 13.4486 && *(R + 32) <= 13.6831) || (*(R + 32) >= 13.6831)) 1271 | && ((*(R + 26) >= 43.2643 && *(R + 26) <= 43.3844) || (*(R + 26) <= 43.2643)) 1272 | && ((*(R + 36) >= 146.691 && *(R + 36) <= 146.723) || (*(R + 36) <= 146.691)) 1273 | ) { 1274 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.97)" << endl; 1275 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1276 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.97"))); 1277 | } 1278 | //Rule 36 1279 | if ( 1280 | ((*(R + 35) >= 29.0332 && *(R + 35) <= 32.685) || (*(R + 35) <= 29.0332)) 1281 | && ((*(R + 8) >= 26.5308 && *(R + 8) <= 26.5651) || (*(R + 8) >= 26.5651)) 1282 | && ((*(R + 29) >= 85.6013 && *(R + 29) <= 85.9144) || (*(R + 29) <= 85.6013)) 1283 | && ((*(R + 44) >= 51.953 && *(R + 44) <= 52.0023) || (*(R + 44) <= 51.953)) 1284 | && ((*(R + 5) >= 75.7986 && *(R + 5) <= 76.0875) || (*(R + 5) <= 75.7986)) 1285 | && ((*(R + 18) >= 61.0736 && *(R + 18) <= 64.9831) || (*(R + 18) <= 61.0736)) 1286 | ) { 1287 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.95)" << endl; 1288 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1289 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.95"))); 1290 | } 1291 | //Rule 37 1292 | if ( 1293 | ((*(R + 33) >= 118.764 && *(R + 33) <= 120.426) || (*(R + 33) >= 120.426)) 1294 | && ((*(R + 27) >= 57.0948 && *(R + 27) <= 64.7327) || (*(R + 27) <= 57.0948)) 1295 | && ((*(R + 49) >= 104.517 && *(R + 49) <= 104.534) || (*(R + 49) >= 104.534)) 1296 | && ((*(R + 51) >= 33.918 && *(R + 51) <= 34.2595) || (*(R + 51) <= 33.918)) 1297 | && ((*(R + 5) >= 73.3444 && *(R + 5) <= 73.7261) || (*(R + 5) >= 73.7261)) 1298 | && ((*(R + 33) >= 136.4 && *(R + 33) <= 149.673) || (*(R + 33) <= 136.4)) 1299 | ) { 1300 | cout << "Timestamp = " << time(&timev) << " " << "Emotions = Neutral(CF = 0.96)" << endl; 1301 | dlib::rectangle rr(long(0), long(120), long(0), long(120)); 1302 | win.add_overlay(image_window::overlay_rect(rr, rgb_pixel(255, 0, 0), emotions[6].append(" 0.96"))); 1303 | } 1304 | else { 1305 | // cout << "No emotions detected" << endl; 1306 | } 1307 | 1308 | shapes.push_back(shape); 1309 | 1310 | // Display it all on the screen 1311 | win.add_overlay(render_face_detections(shapes)); 1312 | win.add_overlay(render_face_detections_lines(shapes)); 1313 | } 1314 | } 1315 | catch (serialization_error& e) 1316 | { 1317 | cout << "You need dlib's default face landmarking model file to run this example." << endl; 1318 | cout << "You can get it from the following URL: " << endl; 1319 | cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl; 1320 | cout << endl << e.what() << endl; 1321 | } 1322 | catch (exception& e) 1323 | { 1324 | cout << e.what() << endl; 1325 | } 1326 | } 1327 | --------------------------------------------------------------------------------