Северный (Арктический) федеральный университет им. М.В. Ломоносова
Опубликован: 23.10.2013 | Доступ: свободный | Студентов: 1765 / 617 | Длительность: 09:26:00
Специальности: Программист
Самостоятельная работа 4:

Разработка приложения, используя SDK Анализ лица (мимики)

< Лекция 5 || Самостоятельная работа 4: 12 || Лекция 6 >

Шаг 2

На втором шаге конфигурируется интерфейс PXCFaceAnalysis. Приложение перечисляет поддерживаемые конфигурации, используя функцию QueryProfile. Каждый профиль описывает поддерживаемые конфигурации. Приложение устанавливает желаемые конфигурационные параметры используя функцию SetProfile.

// Configure the face analysis interface
PXCFaceAnalysis::ProfileInfo faInfo;
faceAnalyzer->QueryProfile(0, &faInfo);
faceAnalyzer->SetProfile(&faInfo);
5. Конфигурация интерфейса анализа лица

Профиль "0" - это первый профиль и обычно профиль интерфейса по умолчанию. PXCFaceAnalysis::ProfileInfo представляет информацию с видео потока и основных параметров, которые являются общими для различных модулей анализа лица (обнаружения, контрольных точек и т.д.). Так после QueryProfile устройство захвата и видео поток могут быть сконфигурированы для процедур анализа лица согласно перечисленным PXCFaceAnalysis::ProfileInfo. Следовательно, конфигурации интерфейса PXCFaceAnalysis и устройства захвата должны быть установлены совместно, как следующие:

// Configure the face analysis interface PXCFaceAnalysis::ProfileInfo faInfo; faceAnalyzer->QueryProfile(0, &faInfo); 
// Find capture device UtilCaptureFile capture(session,0,0); capture.LocateStreams(&faInfo.inputs); 
// Set the face analysis interface faceAnalyzer->SetProfile(&faInfo);
6. Установка конфигураций интерфейса PXCFaceAnalysis и устройства захвата

Здесь инструмент UtilCaptureFile используется для упрощенного подхода применения устройства захвата и установки соответствующего захватываемого потока.

Шаг 3

Теперь в приложении необходимо отдельно сконфигурировать несколько или все модули анализа, например, такие как обнаружение лица и его контрольных точек, или другие применяемые модули анализа лица. Процедуры конфигурации этих модулей похожи. Так например, для конфигурирования обнаружения лица приложение получает определяющий интерфейс от интерфейса PXCFaceAnalysis используя функцию DynamicCast и затем вызывает функции QueryProfile и SetProfile.

// Configure the face detector interface
 PXCFaceAnalysis::Detection *faceDetector;
 faceDetector=faceAnalyzer->DynamicCast<PXCFaceAnalysis::Detection>(); 
// Set the face detector profile 
PXCFaceAnalysis::Detection::ProfileInfo dInfo={0}; 
faceDetector->QueryProfile(0, &dInfo); 
faceDetector->SetProfile(&dInfo);
7. Конфигурация интерфейса и установка профиля определения

The PXCFaceAnalysis::Detection::ProfileInfo описывает поддерживаемые углы обзора алгоритма обнаружения. По умолчанию ViewAngle установлен как VIEW_ANGLE_MULTI, что эквивалентно углам обзора 0, 45, 135 и 180 градусов и фронтальному положению камеры. Похожие шаги используются для конфигурации модуля обнаружения контрольных точек лица.

// Configure the face detector interface 
PXCFaceAnalysis::Landmark *landmarkDetector; 
landmarkDetector=faceAnalyzer->DynamicCast<PXCFaceAnalysis::Landmark>(); 
// Set the face landmark detector profile 
PXCFaceAnalysis::Landmark::ProfileInfo lInfo={0};
landmarkDetector->QueryProfile(1, &lInfo); 
landmarkDetector->SetProfile(&lInfo);
8. Конфигурация интерфейса и установка профиля определения контрольных точек лица

Установка количества контрольных точек (7 или 8) определяется в QueryProfile как 0 или 1 соответственно.

Шаг 4

Приложение выполняет анализа лица, вызывая функцию ProcessImageAsync. Если анализируемое лицо находится на неподвижном изображении, приложение предоставляет изображение на входе. Если анализируемое лицо находится на видеоряде, приложение передает один видео кадр за раз в основной цикл. ProcessImageAsync функция возвращает SP, которое приложение может синхронизировать перед получением результатов анализа.

PXCSmartArray<PXCImage> images; // declare image interface 
PXCSmartSPArray sps(2); //declare Sync points for asynchronous execution 
// Read frame 
pxcStatus sts = capture.ReadStreamAsync(images,&sps[0]); 
// Process frame using face detection 
sts = faceAnalyzer->ProcessImageAsync(images, &sps[1]);
if (sts<PXC_STATUS_NO_ERROR) break; 
// Synchronize both sync points
 sts = sps.SynchronizeEx();
 if (sps[0]->Synchronize(0)<PXC_STATUS_NO_ERROR) break; // test for EOF
9. Анализ лица

Для каждого полученного фрейма выполняется асинхронный конвейер, который состоит из чтения фреймов и затем обрабатывается текущий фрейм используя любой из конфигурируемых алгоритмов анализа лица. Следует отметить, что ничего не обрабатывается в асинхронном конвейер пока Sync Points синхронизируется вызывая функцию SynchronizeEx.

Шаг 5

Для нахождения результатов обнаружения лица приложению необходимо использовать функцию QueryData в интерфейсе обнаружения. QueryFace вызывается в первую очередь для перечисления всех определенных лиц в течении обработки анализа лица.

for (int fidx = 0; ; fidx++) 
{ pxcUID fid = 0; 
pxcU64 timeStamp = 0; 
sts = faceAnalyzer->QueryFace(fidx, &fid, &timeStamp); 
if (sts < PXC_STATUS_NO_ERROR) break; // no more faces detected 
PXCFaceAnalysis::Detection::Data face_data; 
faceDetector->QueryData(fid, &face_data); }
10. Вывода результатов обнаружения лица

Для нахождения результатов определения контрольных точек лица приложению необходимо передать QueryData для меток в уже установленном профиле.

for (int fidx = 0; ; fidx++)
 { pxcUID fid = 0; 
pxcU64 timeStamp = 0; 
sts = faceAnalyzer->QueryFace(fidx, &fid, &timeStamp); 
if (sts < PXC_STATUS_NO_ERROR) break; // no more faces detected 
PXCFaceAnalysis::Landmark::ProfileInfo lInfo={0}; 
landmark->QueryProfile(&lInfo); 
PXCFaceAnalysis::Landmark::LandmarkData data[7]; 
pxcStatus sts=landmark->QueryLandmarkData(fid,lInfo.labels,&data[0]); }
11. Выводов результатов обнаружения контрольных точек лица

Общий код программы по обнаружению лица и его контрольных точек.

#include "pxcsession.h" 
#include "pxccapture.h" 
#include "pxcsmartptr.h" 
#include "face_render.h" 
#include "util_capture_file.h" 
#include "util_cmdline.h" 
#include "pxcface.h" 
int wmain(int argc, wchar_t* argv[]) 
{ 
// Create a session 
PXCSmartPtr<PXCSession> session; 
pxcStatus sts=PXCSession_Create(&session); 
if (sts<PXC_STATUS_NO_ERROR) { 
wprintf_s(L"Failed to create the SDK session\n"); 
return 3; 
} 
UtilCmdLine cmdl(session); 
if (!cmdl.Parse(L"-sdname-nframes-file-record",argc,argv)) return 3; 
// Init Face analyzer 
PXCSmartPtr<PXCFaceAnalysis> faceAnalyzer; 
sts=session->CreateImpl(cmdl.m_iuid, PXCFaceAnalysis::CUID, (void**)&faceAnalyzer); 
if (sts<PXC_STATUS_NO_ERROR) { 
wprintf_s(L"Failed to locate a face module"); 
return 3; 
} 
// Retrieve the input requirements 
PXCFaceAnalysis::ProfileInfo faInfo; 
faceAnalyzer->QueryProfile(0, &faInfo); 
// Find capture device 
UtilCaptureFile capture(session,cmdl.m_recordedFile,cmdl.m_bRecord); 
if (cmdl.m_sdname) capture.SetFilter(cmdl.m_sdname); /*L"Integrated Camera"*/ 
sts=capture.LocateStreams(&faInfo.inputs); 
if (sts<PXC_STATUS_NO_ERROR) { 
wprintf_s(L"Failed to locate an input device that matches input for face analysis\n"); 
return 3; 
} 
faceAnalyzer->SetProfile(&faInfo); 
// Create detector instance 
PXCFaceAnalysis::Detection *faceDetector=faceAnalyzer->DynamicCast<PXCFaceAnalysis::Detection>(); 
if (!faceDetector) { 
wprintf_s(L"Failed to locate the face detection functionality\n"); 
return 3; 
} 
// Create landmark instance 
PXCFaceAnalysis::Landmark *landmarkDetector=landmarkDetector=faceAnalyzer->DynamicCast<PXCFaceAnalysis::Landmark>(); 
if (!landmarkDetector) { 
wprintf_s(L"Failed to locate the face landmark functionality\n"); 
return 3; 
} 
// Set landmark profile 
PXCFaceAnalysis::Landmark::ProfileInfo lInfo={0}; 
landmarkDetector->QueryProfile(0, &lInfo); 
landmarkDetector->SetProfile(&lInfo); 
// Create Renderer 
PXCSmartPtr<FaceRender> faceRender(new FaceRender(L"Landmark Detection Sample")); 
int fnum; 
for (fnum=0;fnum<cmdl.m_nframes;fnum++) { 
PXCSmartArray<PXCImage> images; 
PXCSmartSPArray sps(2); 
///* read and process frame */ 
sts = capture.ReadStreamAsync(images,&sps[0]); 
if (sts<PXC_STATUS_NO_ERROR) break; // EOF 
sts = faceAnalyzer->ProcessImageAsync(images, &sps[1]); 
sts = sps.SynchronizeEx(); 
if (sps[0]->Synchronize(0)<PXC_STATUS_NO_ERROR) break; // EOF 
// loop all faces 
faceRender->ClearData(); 
for (int fidx = 0; ; fidx++) { 
pxcUID fid = 0; 
pxcU64 timeStamp = 0; 
sts = faceAnalyzer->QueryFace(fidx, &fid, &timeStamp); 
if (sts < PXC_STATUS_NO_ERROR) break; // no more faces 
// Query face detection results 
PXCFaceAnalysis::Detection::Data face_data; 
faceDetector->QueryData(fid, &face_data); 
faceRender->SetDetectionData(&face_data); 

// Query landmark points 
faceRender->SetLandmarkData(landmarkDetector, fid); 
faceRender->PrintLandmarkData(landmarkDetector, fid); 
wprintf_s(L"timestamp=%I64d, frame=%d\n", timeStamp, fnum); 
} 
if (!faceRender->RenderFrame(images[0])) break; 
} 
return 0; 
}
< Лекция 5 || Самостоятельная работа 4: 12 || Лекция 6 >
Гульзия Калымова
Гульзия Калымова
Александр Радченко
Александр Радченко