Local Compute Avatar SDK  2.0.9
To generate Head 2.0 avatars
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Pages
avatar_sdk_sample.cpp
1 #include <avatar_sdk_sample.hpp>
2 
3 #include <vector>
4 
5 #if ANDROID
6 #include <android/log.h>
7 #define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "AVATAR_SDK_SAMPLE", __VA_ARGS__)
8 #endif
9 
10 std::vector<std::string> splitString(std::string& str, std::string separator)
11 {
12  std::vector<std::string> result;
13  size_t prevPos = 0, pos = 0;
14  while ((pos = str.find(separator, pos)) != std::string::npos)
15  {
16  result.push_back(str.substr(prevPos, pos - prevPos));
17  prevPos = ++pos;
18  }
19  result.push_back(str.substr(prevPos, pos - prevPos));
20  return result;
21 }
22 
23 std::string findGeneratedHaircutName(AvatarSdkPipelineSubtype pipelineSubtype)
24 {
25  unsigned int haircutsStrSize = 0;
26  const char* availableHaircuts = getAvailableHaircuts(pipelineSubtype, haircutsStrSize);
27  std::string haircutsStr(availableHaircuts, haircutsStrSize);
28 
29  std::vector<std::string> haircuts = splitString(haircutsStr, ";");
30  for (int i = 0; i < haircuts.size(); i++)
31  {
32  if (haircuts[i].find("generated") != std::string::npos)
33  return haircuts[i];
34  }
35  return "";
36 }
37 
38 int generateAvatarInStorage(AvatarSdkPipelineSubtype pipelineSubtype, std::string inputImagePath, std::string outputDirPath, std::string resourcesPath, ReportProgress progressCallback)
39 {
40  // Initialize Avatar SDK
41  int code = initAvatarSdk("Avatar SDK Sample", resourcesPath.c_str());
42  if (code != 0)
43  {
44  printf("Unable to initialize Avatar SDK! \n");
45  return code;
46  }
47 
48  //Configure parameters
49  AvatarSdkParams params;
50  params.pipelineSubtype = pipelineSubtype;
51  params.inputImagePath = (char*)inputImagePath.c_str();
52  params.outputDirPath = (char*)outputDirPath.c_str();
53 
54  // Add one "generated" haircut
55  std::string generatedHaircutName = findGeneratedHaircutName(pipelineSubtype);
56  params.addHaircuts(generatedHaircutName.c_str(), generatedHaircutName.size());
57 
58  // Generate avatar
59  code = generateAvatar(params, progressCallback);
60  if (code != 0)
61  printf("Error occured during avatar generation!\n");
62  else
63  printf("Avatar was generated!\n");
64 
65  // Release Avatar SDK. Should be called after all avatars are generated.
67  return code;
68 }
69 
70 
71 int generateAvatarInMemory(AvatarSdkPipelineSubtype pipelineSubtype, std::string inputImagePath, std::string resourcesPath, ReportProgress progressCallback)
72 {
73  // Initialize Avatar SDK
74  int code = initAvatarSdk("Avatar SDK Sample", resourcesPath.c_str());
75  if (code != 0)
76  {
77  printf("Unable to initialize Avatar SDK! \n");
78  return code;
79  }
80 
81  //Configure parameters
82  AvatarSdkParams params;
83  params.pipelineSubtype = pipelineSubtype;
84  params.inputImagePath = (char*)inputImagePath.c_str();
85  params.outputDirPath = NULL; // Set to NULL to store generated avatar in memory
86 
87  params.modelInfo = new AvatarSdkModelInfo();
88  params.modelInfo->age = true;
89  params.modelInfo->race = true;
90 
91  // Add one "generated" haircut
92  std::string haircutName = findGeneratedHaircutName(pipelineSubtype);
93  params.addHaircuts(haircutName.c_str(), haircutName.size());
94 
95  //Generate all available blendshapes
96  unsigned int blendshapesStrSize = 0;
97  const char* availableBlendshapes = getAvailableBlendshapes(pipelineSubtype, blendshapesStrSize);
98  params.addBlendshapes(availableBlendshapes, blendshapesStrSize);
99 
100  // Generate avatar
101  code = generateAvatar(params, progressCallback);
102  if (code == 0)
103  {
104  printf("Avatar was generated!\n");
105 
106  //Get vertices
107  int verticesCount = 0;
108  const float* vertices = getAvatarVertices(verticesCount, NULL);
109 
110  //Get faces
111  int facesCount = 0;
112  const int* faces = getAvatarFaces(facesCount, NULL);
113  const double* uvMapping = getAvatarUVMapping(facesCount, NULL);
114 
115  //Get texture
116  int textureWidth, textureHeight;
117  const unsigned char* texture = getAvatarTexture(textureWidth, textureHeight, NULL);
118 
119  //Get haircut vertices
120  int haircutVerticesCount = 0;
121  const float* haircutVertices = getHaircutVertices(haircutVerticesCount, haircutName.c_str(), nullptr); //nullptr for reading data from memory
122  printf("There are %d vertices for haircut %s stored in memory \n", haircutVerticesCount, haircutName.c_str());
123 
124  //Get haircut faces
125  int haircutFacesCount = 0;
126  const int* haircutFaces = getHaircutFaces(haircutFacesCount, haircutName.c_str(), nullptr); //nullptr for reading data from memory
127  printf("There are %d faces for haircut %s stored in memory \n", haircutFacesCount, haircutName.c_str());
128 
129  //Get haircut texture
130  int haircutTextureWidth, haircutTextureHeight;
131  const unsigned char* haircutTexture = getHaircutTexture(haircutTextureWidth, haircutTextureHeight, haircutName.c_str(), nullptr);
132 
133  //Get "jawOpen" blendshape deltas
134  std::string blendshapeName = "jawOpen";
135  int blendshapeVerticesCount = 0;
136  const float* verticesDeltas = getAvatarBlendshapeDeltas(blendshapeName.c_str(), blendshapeVerticesCount, nullptr);
137 
138  //Get model info
139  AvatarSdkModelInfoEntry modelInfoEntry;
140  getAvatarModelInfo(nullptr, modelInfoEntry); //nullptr for reading data from memory
141  if (modelInfoEntry.age == AgePredicted::CHILD)
142  {
143  printf("Age: Child \n");
144  }
145  else if (modelInfoEntry.age == AgePredicted::NOT_CHILD)
146  {
147  printf("Age: Not child \n");
148  }
149  printf("Age confidence: %f \n", modelInfoEntry.ageConfidence);
150 
151  printf("Predicted race: %d\n", modelInfoEntry.race->predicted);
152  }
153  else
154  printf("Error occured during avatar generation!\n");
155 
156  // Release Avatar SDK. Should be called after all avatars are generated.
158  return code;
159 }
160 
161 void printResources(AvatarSdkResourcesList &resourcesList)
162 {
163  for (unsigned int i = 0; i < resourcesList.length; i++)
164  {
165  printf("%d - %s : %s \n", i, resourcesList.resources[i].name, resourcesList.resources[i].path);
166  }
167 }
168 
169 int generateAvatarWithParameters(AvatarSdkPipelineSubtype subtype, std::string inputImagePath, std::string outputDirPath, std::string resourcesPath, ReportProgress progressCallback)
170 {
171  //Initialize Avatar SDK with any application name
172  int code = initAvatarSdk("Avatar SDK Sample", resourcesPath.c_str());
173  if (code != 0)
174  {
175  printf("Unable to initialize Avatar SDK! \n");
176  return code;
177  }
178 
179  //Set parameters
180  AvatarSdkParams avatarParams;
181  avatarParams.pipelineSubtype = subtype;
182  avatarParams.inputImagePath = (char*)inputImagePath.c_str();
183  avatarParams.outputDirPath = (char*)outputDirPath.c_str();
184  avatarParams.outputMeshFormat = AvatarSdkMeshFormat::AVATAR_SDK_MESH_FORMAT_OBJ;
185  if (subtype == AvatarSdkPipelineSubtype::HEAD_MOBILE)
186  avatarParams.lodNumber = 7;
187 
188  //configure data that should be generated for this avatar
189  avatarParams.modelInfo = new AvatarSdkModelInfo();
190  avatarParams.modelInfo->gender = true;
191  avatarParams.modelInfo->eyeScleraColor = true;
192  avatarParams.modelInfo->eyeIrisColor = true;
193  avatarParams.modelInfo->skinColor = true;
194  avatarParams.modelInfo->age = true;
195  avatarParams.modelInfo->hairColor = true;
196  avatarParams.modelInfo->race = true;
197  avatarParams.modelInfo->predictHaircut = true;
198  if (subtype == AvatarSdkPipelineSubtype::HEAD_MOBILE)
199  avatarParams.modelInfo->facialLandmarks68 = true;
200 
201  //avatar modifications
202  avatarParams.avatarModifications = new AvatarModifications();
203  if (subtype == AvatarSdkPipelineSubtype::BUST_MOBILE)
204  avatarParams.avatarModifications->curvedBottom = true;
205  avatarParams.avatarModifications->removeSmile = true;
206  avatarParams.avatarModifications->removeGlasses = true;
207  avatarParams.avatarModifications->enhanceLighting = true;
208  avatarParams.avatarModifications->setEyeIrisColor(0, 255, 0);
209  avatarParams.avatarModifications->setEyeScleraColor(0, 0, 255);
210  avatarParams.avatarModifications->setHairColor(0, 187, 255);
211 
212  unsigned int haircutsStrSize = 0;
213  const char* availableHaircuts = getAvailableHaircuts(subtype, haircutsStrSize);
214  printf("Available haircuts: %s\n", availableHaircuts);
215 
216  unsigned int blendshapesStrSize = 0;
217  const char* availableBlendshapes = getAvailableBlendshapes(subtype, blendshapesStrSize);
218  printf("Available blendshapes: %s\n", availableBlendshapes);
219 
220  avatarParams.addBlendshapes(availableBlendshapes, blendshapesStrSize);
221  avatarParams.addHaircuts(availableHaircuts, haircutsStrSize);
222 
223  code = generateAvatar(avatarParams, progressCallback);
224  if (code == 0)
225  {
226  printf("Avatar was generated!\n");
228 
229  code = getAvatarModelInfo(avatarParams.outputDirPath, entry);
230  if (!code)
231  {
232  if (entry.age == AgePredicted::CHILD)
233  {
234  printf("Age: Child \n");
235  }
236  else if (entry.age == AgePredicted::NOT_CHILD)
237  {
238  printf("Age: Not child \n");
239  }
240  printf("Age confidence: %f \n", entry.ageConfidence);
241  if (entry.skinColor)
242  {
243  printf("Skin color (RGB): %d %d %d \n", entry.skinColor->red, entry.skinColor->green, entry.skinColor->blue);
244  }
245 
246  printf("Predicted race: %d\n", entry.race->predicted);
247  printf("Predicted haircut: %s\n", entry.predictedHaircut);
248 
249  AvatarSdkResourcesList modelHaircuts = getAvatarHaircutsList(avatarParams.outputDirPath);
250  AvatarSdkResourcesList modelBlendshapes = getAvatarBlendshapesList(avatarParams.outputDirPath);
251 
252  printf("Model's haircuts: \n");
253  printResources(modelHaircuts);
254  printf("Model's blendshapes: \n");
255  printResources(modelBlendshapes);
256  }
257  else
258  {
259  printf("Error occured getting of model info!\n");
260  }
261  }
262  else
263  {
264  printf("Unable to generate avatar. Error code: %d", code);
265  }
266 
267  delete avatarParams.modelInfo;
268  delete avatarParams.avatarModifications;
269 
270  // Release Avatar SDK. Should be called after all avatars are generated.
272  return code;
273 }
274 
275 int generateCartoonishAvatar(AvatarSdkPipelineSubtype subtype, std::string inputImagePath, std::string outputDirPath, std::string resourcesPath, ReportProgress progressCallback)
276 {
277  //Initialize Avatar SDK with any application name
278  int code = initAvatarSdk("Avatar SDK Sample", resourcesPath.c_str());
279  if (code != 0)
280  {
281  printf("Unable to initialize Avatar SDK! \n");
282  return code;
283  }
284 
285  //Set parameters
286  AvatarSdkParams avatarParams;
287  avatarParams.pipelineSubtype = subtype;
288  avatarParams.inputImagePath = (char*)inputImagePath.c_str();
289  avatarParams.outputDirPath = (char*)outputDirPath.c_str();
290  avatarParams.outputMeshFormat = AvatarSdkMeshFormat::AVATAR_SDK_MESH_FORMAT_OBJ;
291 
292  // cartoonishLevel impacts on how much the geometry will be modified. It is applicable only to the head/mobile subtype
293  if (subtype == AvatarSdkPipelineSubtype::HEAD_MOBILE)
294  avatarParams.cartoonishLevel = 1.0f;
295 
296  //avatar modifications
297  avatarParams.avatarModifications = new AvatarModifications();
298  avatarParams.avatarModifications->slightlyCartoonishTexture = true;
299  avatarParams.avatarModifications->parametricEyesTexture = true;
300  avatarParams.avatarModifications->addGlare = true;
301  avatarParams.avatarModifications->addEyelidShadow = true;
302 
303  // Add one "generated" haircut
304  std::string haircutName = findGeneratedHaircutName(subtype);
305  avatarParams.addHaircuts(haircutName.c_str(), haircutName.size());
306 
307  code = generateAvatar(avatarParams, progressCallback);
308  if (code == 0)
309  {
310  printf("Cartoonsih avatar was generated!\n");
311  }
312  else
313  {
314  printf("Unable to generate cartoonish avatar. Error code: %d", code);
315  }
316 
317  delete avatarParams.avatarModifications;
318 
319  // Release Avatar SDK. Should be called after all avatars are generated.
321  return code;
322 }
bool parametricEyesTexture
Replace eye texture from submitted photo to generated one with sclera and iris colors match the photo...
float ageConfidence
Represents the confidence of age classification with value in the range [0.5, 1] inclusive.
DllExport AvatarSdkResourcesList getAvatarHaircutsList(const char *pathToModelDir)
bool race
Predict person&#39;s race from a submitted photo.
bool gender
Predict person&#39;s gender from a submitted photo.
bool enhanceLighting
Attempt to make lighting more uniform.
DllExport const float * getAvatarBlendshapeDeltas(const char *blendshapeName, int &verticesCount, const char *pathToModelDir)
DllExport int getAvatarModelInfo(const char *pathToModelDir, AvatarSdkModelInfoEntry &entry)
char * predictedHaircut
A name of the predicted haircut.
DllExport void setEyeScleraColor(unsigned char r, unsigned char g, unsigned char b)
Set eye sclera color.
AvatarSdkPipelineSubtype pipelineSubtype
Type of the avatar.
AvatarSdkMeshFormat outputMeshFormat
Format in which output meshes will be saved.
bool removeSmile
Remove smile in case it is detected on the source photo.
char * outputDirPath
Directory to which the result will be written.
AvatarSdkModelInfo * modelInfo
Computation parameters. The generated data is stored in the model.json file in the output directory...
bool addGlare
Add a glare directly into parametric eye texture Works only when parametricEyesTexture is set...
int lodNumber
Level of Details from 0 to 7 available for the head/mobile subtype.
bool hairColor
Compute average haircut color from a submitted photo.
bool addEyelidShadow
Add an eyelid shadow on top of eye texture. Works only when parametricEyesTexture is set...
bool slightlyCartoonishTexture
Make the model texture looking with a slightly cartoonish effect.
AgePredicted age
Classify a person&#39;s age from a submitted photo. Currently possible values are CHILD and NOT_CHILD...
float cartoonishLevel
Level of the cartoon-like stylization in range [0, 1]. Applied only to the "Head 2.0 | head/mobile" pipeline.
bool facialLandmarks68
Compute facial landmarks. Available only for the "head/mobile" subtype.
DllExport const char * getAvailableHaircuts(AvatarSdkPipelineSubtype pipelineSubtype, unsigned int &size)
DllExport void setEyeIrisColor(unsigned char r, unsigned char g, unsigned char b)
Set eye iris color.
DllExport const float * getAvatarVertices(int &verticesCount, const char *pathToModelDir)
char * inputImagePath
Path to the photo in the PNG or JPEG format.
AvatarModifications * avatarModifications
Requested avatar modifications.
bool eyeScleraColor
Compute average eye sclera color from a submitted photo.
DllExport void addBlendshapes(const char *blendshapesList, int size)
Add a list of blendshapes.
DllExport const unsigned char * getAvatarTexture(int &textureWidth, int &textureHeight, const char *pathToModelDir)
bool age
Classify a person&#39;s age from a submitted photo.
DllExport int releaseAvatarSdk()
DllExport int generateAvatar(const AvatarSdkParams &avatarParams, ReportProgress reportProgress)
bool eyeIrisColor
Compute average eye iris color from a submitted photo.
DllExport const char * getAvailableBlendshapes(AvatarSdkPipelineSubtype pipelineSubtype, unsigned int &size)
DllExport const double * getAvatarUVMapping(int &facesCount, const char *pathToModelDir)
AvatarSdkColorRgb * skinColor
Average skin color computed from a submitted photo.
DllExport AvatarSdkResourcesList getAvatarBlendshapesList(const char *pathToModelDir)
DllExport const int * getAvatarFaces(int &facesCount, const char *pathToModelDir)
DllExport void setHairColor(unsigned char r, unsigned char g, unsigned char b)
Set hair color.
DllExport void addHaircuts(const char *haircutsList, int size)
Add a list of haircuts.
DllExport const float * getHaircutVertices(int &verticesCount, const char *haircutName, const char *pathToModelDir)
bool curvedBottom
Make the bottom of model bust slightly curved. (Parameter is applicable to bust/mobile models only)...
bool removeGlasses
Attempt to remove glasses on the submitted photo before the actual avatar computation start...
bool skinColor
Compute average skin color from a submitted photo.
RacePredicted * race
Represents a person&#39;s race prediction result.
DllExport const int * getHaircutFaces(int &facesCount, const char *haircutName, const char *pathToModelDir)
bool predictHaircut
Predict which haircut from the base and the facegen sets matches best to the submitted photo...
DllExport const unsigned char * getHaircutTexture(int &textureWidth, int &textureHeight, const char *haircutName, const char *pathToModelDir)
DllExport int initAvatarSdk(const char *programName, const char *resourcesPath)