1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <vector>
17
18 #include "ffrt_inner.h"
19 #include "common.h"
20
FaceStory()21 void FaceStory()
22 {
23 PreHotFFRT();
24
25 const int FACE_NUM = 3; // 假设图像上存在多少张人脸,可修改,实际业务可以支持1-10个人脸
26
27 uint32_t inputImageInfo_ = 0; // 模拟输入图像
28 std::vector<uint32_t> faceBboxes_; // 模拟人脸检测框
29 std::vector<uint32_t> faceDegrees_; // 模拟人脸朝向
30 std::vector<uint32_t> faceLandmarks_; // 模拟人脸特征点
31 std::vector<uint32_t> faceAttrs_; // 模拟人脸属性
32 std::vector<uint32_t> faceMasks_; // 模拟人脸分割
33 std::vector<uint32_t> faceAngles_; // 模拟人脸角度
34
35 TIME_BEGIN(t);
36 for (uint32_t r = 0; r < REPEAT; r++) {
37 for (uint64_t count = 0; count < 10; ++count) {
38 // 原图的预处理,输入原始图像,输出预处理图像
39 ffrt::submit(
40 [&]() {
41 // 下采样Y通道
42 ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {}, {});
43
44 // 下采样UV通道
45 ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {}, {});
46
47 ffrt::wait(); // 同步下采样结果
48
49 // FlushCache
50 simulate_task_compute_time(COMPUTE_TIME_US);
51 },
52 {}, {&inputImageInfo_});
53
54 // 人脸检测,输入预处理图像,输出人脸检测结果
55 ffrt::submit(
56 [&]() {
57 faceBboxes_.clear();
58 simulate_task_compute_time(COMPUTE_TIME_US);
59 for (auto i = 0; i < FACE_NUM; i++) {
60 faceBboxes_.push_back(1);
61 }
62 },
63 {&inputImageInfo_}, {&faceBboxes_});
64
65 // Tracking的Init,对processImageInfo_和faceBboxes_是只读,不存在Rotation的情况下,直接丢出去并发就行,也不需要同步
66 ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {&faceBboxes_}, {});
67
68 // 人脸朝向检测,输出人脸朝向结果(省略了根据朝向做旋转)
69 faceDegrees_ = std::vector<uint32_t>(FACE_NUM, 0);
70 for (auto j = 0; j < FACE_NUM; j++) { // 图像可能存在多个人脸,loop
71 ffrt::submit(
72 [&, j]() { // FaceDirectionProcess对于processImageInfo_是只读访问,多个人脸可以并发
73 simulate_task_compute_time(COMPUTE_TIME_US);
74 faceDegrees_[j] = 1;
75 },
76 {&faceBboxes_}, {&faceDegrees_[j]});
77 }
78
79 // 人脸特征点检测,输入人脸旋转结果,输出人脸特征点结果
80 faceLandmarks_ = std::vector<uint32_t>(FACE_NUM, 0);
81 for (auto k = 0; k < FACE_NUM; k++) {
82 ffrt::submit(
83 [&, k]() {
84 simulate_task_compute_time(COMPUTE_TIME_US);
85 faceLandmarks_[k] = 1;
86 },
87 {&faceDegrees_[k]}, {&faceLandmarks_[k]});
88 }
89
90 // 人脸属性检测,输入人脸旋转结果,输出人脸属性结果
91 faceAttrs_ = std::vector<uint32_t>(FACE_NUM, 0);
92 for (auto m = 0; m < FACE_NUM; m++) {
93 ffrt::submit(
94 [&, m]() {
95 simulate_task_compute_time(COMPUTE_TIME_US);
96 faceAttrs_[m] = 1;
97 },
98 {&faceDegrees_[m]}, {&faceAttrs_[m]});
99 }
100
101 // 人脸分割,输入人脸旋转结果,输出人脸特征点结果
102 faceMasks_ = std::vector<uint32_t>(FACE_NUM, 0);
103 for (auto n = 0; n < 1; n++) { // 实际业务中分割当前只做一次
104 ffrt::submit(
105 [&, n]() {
106 simulate_task_compute_time(COMPUTE_TIME_US);
107 faceMasks_[n] = 1;
108 },
109 {&faceDegrees_[n]}, {&faceMasks_[n]});
110 }
111
112 // 人脸角度检测,输入人脸特征点结果,输出人脸角度结果
113 faceAngles_ = std::vector<uint32_t>(FACE_NUM, 0);
114 for (auto q = 0; q < FACE_NUM; q++) { // 实际业务中分割当前只做一次
115 ffrt::submit(
116 [&, q]() {
117 simulate_task_compute_time(COMPUTE_TIME_US);
118 faceAngles_[q] = 1;
119 },
120 {&faceLandmarks_[q]}, {&faceAngles_[q]});
121 }
122
123 ffrt::wait(); // 同步子任务完成
124 }
125 }
126 TIME_END_INFO(t, "face_story");
127 }
128
main()129 int main()
130 {
131 GetEnvs();
132 FaceStory();
133 }