Введение в естественно-интуитивное взаимодействие с компьютером

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

Разбить на страницы
Показывать лекцию целиком

Дополнительный материал к лабораторной работе можно скачать здесь.

The Intel Perceptual Computing SDK представляет собой библиотеку, содержащую алгоритмы распознавания и обнаружения, реализованные через стандартные интерфейсы. SDK предоставляет набор алгоритмов анализа лица, включающий определения местоположения лица и его контрольных точек, распознавания лица и его атрибуты.

В этой лабораторн6ой работе мы рассмотрим, как использовать SDK для определения местоположения лица и обнаружения его контрольных точек, и как написать объявление для этих модулей анализа лица.

1. Для начала создайте новый пустой проект и настройте его для работы с Intel SDK, так это делали на практическом занятии №1.

2. Для упрощения работы воспользуемся уже готовыми приложениям face_render. Скопируйте и добавьте файлы landmark_detection.cpp и face_render.cpp из архива решения к проекту, как показано на рис 9.1.

(рис 9.1) Подключение файлов к проекту

Если в вашем проекте используются предварительно откомпилированные заголовки, то компиляция любого файла, не содержащего #include "stdafx.h", будет остановлена с ошибкой. Чтобы этого не случилось, в нашем случае необходимо сделать следующее: добавить в начало файлов landmark_detection.cpp и face_render.cpp строчку #include "stdafx.h"

Что бы было легче понять код, проанализируем по следующим этапам.

  • Первый шаг – это использование класса UtilPipeline для создания очень простого приложения и определение нового класса "FacePipeline", который является наследником утилитного класса. Класс FacePipeline необходим для генерации контрольных точек лица, в связи с тем, что эта функция не является частью утилитного класса UtilPipeline. Поэтому конструктор объявляет новый FaceRender и деконструктор чистит его.
  • class FacePipeline: public UtilPipeline {
    public:
        FacePipeline(void):UtilPipeline() {
            m_face_render = NULL; 
    
            m_face_render = new  FaceRender(L"Face Viewer");
            EnableFaceLandmark();
        }
    
    	~FacePipeline() {
    		if (m_face_render != NULL) delete m_face_render;
    	}
    ...
    protected:
    	FaceRender* m_face_render;
    };
    
  • Для генерации контрольных точек, приложению необходимо применить функцию UtilPipeline::OnNewFrame, которая генерирует данные анализа лица, используя утилиту FaceRender. Функция OnNewFrame использует UtilPipeline::QueryFace() для запроса класса анализирующего лицо. Затем анализатор лица использует функцию PXCFaceAnalysis:: QueryFace() для запроса обнаруженного лица. Если лицо было обнаружено, тогда приложение должно запросить данные обнаружения или контрольных точек после динамического приведения к соответствующему модулю PXCFaceAnalysis::Landmark. В завершении обращение к FaceRender::SetLandmarkData используется для установки данных анализа лица, которые будут генерироваться, когда вызывается FaceRender::RenderFrame.
  • virtual bool OnNewFrame(void) { 
    /* face */ 
    PXCFaceAnalysis *faceAnalyzer = QueryFace(); 
    PXCFaceAnalysis::Landmark *landmark = 
    faceAnalyzer->DynamicCast<PXCFaceAnalysis::Landmark>(); 
    // loop all faces 
    m_face_render->ClearData(); 
    for (int fidx = 0; ; fidx++) { 
    pxcUID fid = 0; 
    pxcU64 timeStamp = 0; 
    pxcStatus sts = faceAnalyzer->QueryFace(fidx, fid, timeStamp); 
    if (sts < PXC_STATUS_NO_ERROR) break; // no more faces 
    m_face_render->SetLandmarkData (landmark, fid); 
    } 
    return(m_face_render->RenderFrame( 
    QueryImage(PXCImage::IMAGE_TYPE_COLOR)) ); }
    
  • Для обработки каждого фрейма захватываемого с видеопотока, вызывается в главной функции вызывается функция LoopFrames() для захвата и обработки каждого фрейма. Функция LoopFrames также вызывает функцию OnNewFrame для нахождения и генерации определенных данных.
  • FacePipeline* pipeline = new FacePipeline(); 
    pipeline->LoopFrames(); 
    delete pipeline;
    

    3. Теперь создадим приложение, которое будет использовать функцию по определению лица.

    1 шаг

    Сессия SDK – это самый первый объект приложения по определению лица, который должен быть создан для поддержания всех входов/выходов или алгоритмов модулей. Это создается вызовом функции PXCSession_Create. Приложение использует функции сессии для создания экземпляра модуля алгоритма определения лица, который являются частью интерфейса PXCFaceAnalysis. В начале приложение создает экземпляр интерфейса анализа лица PXCFaceAnalysis вызовом функции PXCSession::CreateImpl с идентификатором интерфейса PXCFaceAnalysis::CUID.

    // Create a session PXCSession 
    *session; PXCSession_Create(session); 
    // Create Face analyzer interface PXCFaceAnalysis 
    *faceAnalyzer; session->CreateImpl(PXCFaceAnalysis::CUID, 
    (void**)faceAnalyzer);
    

    Шаг 2

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

    // Configure the face analysis interface
    PXCFaceAnalysis::ProfileInfo faInfo;
    faceAnalyzer->QueryProfile(0, faInfo);
    faceAnalyzer->SetProfile(faInfo);
    

    Профиль "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);
    

    Здесь инструмент 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);
    

    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);
    

    Установка количества контрольных точек (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
    

    Для каждого полученного фрейма выполняется асинхронный конвейер, который состоит из чтения фреймов и затем обрабатывается текущий фрейм используя любой из конфигурируемых алгоритмов анализа лица. Следует отметить, что ничего не обрабатывается в асинхронном конвейер пока 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); }
    

    Для нахождения результатов определения контрольных точек лица приложению необходимо передать 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]); }
    

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

    #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; 
    }
    
    Страницы:

    Дополнительный материал к лабораторной работе можно скачать здесь.

    The Intel Perceptual Computing SDK представляет собой библиотеку, содержащую алгоритмы распознавания и обнаружения, реализованные через стандартные интерфейсы. SDK предоставляет набор алгоритмов анализа лица, включающий определения местоположения лица и его контрольных точек, распознавания лица и его атрибуты.

    В этой лабораторн6ой работе мы рассмотрим, как использовать SDK для определения местоположения лица и обнаружения его контрольных точек, и как написать объявление для этих модулей анализа лица.

    1. Для начала создайте новый пустой проект и настройте его для работы с Intel SDK, так это делали на практическом занятии №1.

    2. Для упрощения работы воспользуемся уже готовыми приложениям face_render. Скопируйте и добавьте файлы landmark_detection.cpp и face_render.cpp из архива решения к проекту, как показано на рис 9.1.

    (рис 9.1) Подключение файлов к проекту

    Если в вашем проекте используются предварительно откомпилированные заголовки, то компиляция любого файла, не содержащего #include "stdafx.h", будет остановлена с ошибкой. Чтобы этого не случилось, в нашем случае необходимо сделать следующее: добавить в начало файлов landmark_detection.cpp и face_render.cpp строчку #include "stdafx.h"

    Что бы было легче понять код, проанализируем по следующим этапам.

  • Первый шаг – это использование класса UtilPipeline для создания очень простого приложения и определение нового класса "FacePipeline", который является наследником утилитного класса. Класс FacePipeline необходим для генерации контрольных точек лица, в связи с тем, что эта функция не является частью утилитного класса UtilPipeline. Поэтому конструктор объявляет новый FaceRender и деконструктор чистит его.
  • class FacePipeline: public UtilPipeline {
    public:
        FacePipeline(void):UtilPipeline() {
            m_face_render = NULL; 
    
            m_face_render = new  FaceRender(L"Face Viewer");
            EnableFaceLandmark();
        }
    
    	~FacePipeline() {
    		if (m_face_render != NULL) delete m_face_render;
    	}
    ...
    protected:
    	FaceRender* m_face_render;
    };
    
  • Для генерации контрольных точек, приложению необходимо применить функцию UtilPipeline::OnNewFrame, которая генерирует данные анализа лица, используя утилиту FaceRender. Функция OnNewFrame использует UtilPipeline::QueryFace() для запроса класса анализирующего лицо. Затем анализатор лица использует функцию PXCFaceAnalysis:: QueryFace() для запроса обнаруженного лица. Если лицо было обнаружено, тогда приложение должно запросить данные обнаружения или контрольных точек после динамического приведения к соответствующему модулю PXCFaceAnalysis::Landmark. В завершении обращение к FaceRender::SetLandmarkData используется для установки данных анализа лица, которые будут генерироваться, когда вызывается FaceRender::RenderFrame.
  • virtual bool OnNewFrame(void) { 
    /* face */ 
    PXCFaceAnalysis *faceAnalyzer = QueryFace(); 
    PXCFaceAnalysis::Landmark *landmark = 
    faceAnalyzer->DynamicCast<PXCFaceAnalysis::Landmark>(); 
    // loop all faces 
    m_face_render->ClearData(); 
    for (int fidx = 0; ; fidx++) { 
    pxcUID fid = 0; 
    pxcU64 timeStamp = 0; 
    pxcStatus sts = faceAnalyzer->QueryFace(fidx, fid, timeStamp); 
    if (sts < PXC_STATUS_NO_ERROR) break; // no more faces 
    m_face_render->SetLandmarkData (landmark, fid); 
    } 
    return(m_face_render->RenderFrame( 
    QueryImage(PXCImage::IMAGE_TYPE_COLOR)) ); }
    
  • Для обработки каждого фрейма захватываемого с видеопотока, вызывается в главной функции вызывается функция LoopFrames() для захвата и обработки каждого фрейма. Функция LoopFrames также вызывает функцию OnNewFrame для нахождения и генерации определенных данных.
  • FacePipeline* pipeline = new FacePipeline(); 
    pipeline->LoopFrames(); 
    delete pipeline;
    

    3. Теперь создадим приложение, которое будет использовать функцию по определению лица.

    1 шаг

    Сессия SDK – это самый первый объект приложения по определению лица, который должен быть создан для поддержания всех входов/выходов или алгоритмов модулей. Это создается вызовом функции PXCSession_Create. Приложение использует функции сессии для создания экземпляра модуля алгоритма определения лица, который являются частью интерфейса PXCFaceAnalysis. В начале приложение создает экземпляр интерфейса анализа лица PXCFaceAnalysis вызовом функции PXCSession::CreateImpl с идентификатором интерфейса PXCFaceAnalysis::CUID.

    // Create a session PXCSession 
    *session; PXCSession_Create(session); 
    // Create Face analyzer interface PXCFaceAnalysis 
    *faceAnalyzer; session->CreateImpl(PXCFaceAnalysis::CUID, 
    (void**)faceAnalyzer);
    

    Шаг 2

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

    // Configure the face analysis interface
    PXCFaceAnalysis::ProfileInfo faInfo;
    faceAnalyzer->QueryProfile(0, faInfo);
    faceAnalyzer->SetProfile(faInfo);
    

    Профиль "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);
    

    Здесь инструмент 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);
    

    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);
    

    Установка количества контрольных точек (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
    

    Для каждого полученного фрейма выполняется асинхронный конвейер, который состоит из чтения фреймов и затем обрабатывается текущий фрейм используя любой из конфигурируемых алгоритмов анализа лица. Следует отметить, что ничего не обрабатывается в асинхронном конвейер пока 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); }
    

    Для нахождения результатов определения контрольных точек лица приложению необходимо передать 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]); }
    

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

    #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; 
    }
    
    Вернуться к учебному плану