Я использую Affectiva SDK 4.0 для записи видео GoPro.Я использую программу C ++ на Ubuntu 16.04.Видео GoPro было записано с частотой 60 кадров в секунду.Проблема в том, что Affectiva предоставляет результаты только для примерно половины кадров (т.е. 30 кадров в секунду).Если я посмотрю на временные метки, предоставленные Affectiva, последняя метка времени соответствует продолжительности видео, это означает, что Affectiva каким-то образом пропускает каждый второй кадр.
Перед запуском Affectiva я запустил ffmpeg со следующей командой, чтобы убедиться, чтовидео имеет постоянную частоту кадров 60 кадров в секунду:
ffmpeg -i in.MP4 -vf -y -vcodec libx264 -preset medium -r 60 -map_metadata 0:g -strict -2 out.MP4 </dev/null 2>&1
Когда я проверяю метку времени презентации, используя ffprobe -show_entries frame=pict_type,pkt_pts_time -of csv -select_streams v in.MP4
, я получаю для необработанного видео следующие значения:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/media/GoPro_concat/GoPro_concat.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 01:14:46.75, start: 0.000000, bitrate: 15123 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1280x720 [SAR 1:1 DAR 16:9], 14983 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
Metadata:
handler_name : GoPro AVC
timecode : 13:17:26:44
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
handler_name : GoPro AAC
Stream #0:2(eng): Data: none (tmcd / 0x64636D74)
Metadata:
handler_name : GoPro AVC
timecode : 13:17:26:44
Unsupported codec with id 0 for input stream 2
frame,0.000000,I
frame,0.016683,P
frame,0.033367,P
frame,0.050050,P
frame,0.066733,P
frame,0.083417,P
frame,0.100100,P
frame,0.116783,P
frame,0.133467,I
frame,0.150150,P
frame,0.166833,P
frame,0.183517,P
frame,0.200200,P
frame,0.216883,P
frame,0.233567,P
frame,0.250250,P
frame,0.266933,I
frame,0.283617,P
frame,0.300300,P
frame,0.316983,P
frame,0.333667,P
frame,0.350350,P
frame,0.367033,P
frame,0.383717,P
frame,0.400400,I
frame,0.417083,P
frame,0.433767,P
frame,0.450450,P
frame,0.467133,P
frame,0.483817,P
frame,0.500500,P
frame,0.517183,P
frame,0.533867,I
frame,0.550550,P
frame,0.567233,P
frame,0.583917,P
frame,0.600600,P
frame,0.617283,P
frame,0.633967,P
frame,0.650650,P
frame,0.667333,I
frame,0.684017,P
frame,0.700700,P
frame,0.717383,P
frame,0.734067,P
frame,0.750750,P
frame,0.767433,P
frame,0.784117,P
frame,0.800800,I
frame,0.817483,P
frame,0.834167,P
frame,0.850850,P
frame,0.867533,P
frame,0.884217,P
frame,0.900900,P
frame,0.917583,P
frame,0.934267,I
frame,0.950950,P
frame,0.967633,P
frame,0.984317,P
frame,1.001000,P
frame,1.017683,P
frame,1.034367,P
frame,1.051050,P
frame,1.067733,I
...
Я загрузил полный вывод на OneDrive .
Если я запускаю Affectiva для необработанного видео (не обработанного ffmpeg), я сталкиваюсь с той же проблемой пропущенных кадров.Я использовал Affectiva с affdex::VideoDetector detector(60);
Есть ли проблема с командой ffmpeg или с Affectiva?
Редактировать : Мне кажется, я выяснил, где проблема моглабыть.Кажется, что Affectiva не обрабатывает все видео, а просто останавливается после определенного количества обработанных кадров без какого-либо сообщения об ошибке.Ниже я разместил код C ++, который я использую.В методе onProcessingFinished()
я печатаю что-то на консоль, когда обработка закончена.Но это сообщение никогда не печатается, поэтому Affectiva никогда не заканчивается.
Что-то не так с моим кодом или я должен закодировать видео в формат, отличный от MP4?
#include "VideoDetector.h"
#include "FrameDetector.h"
#include <iostream>
#include <fstream>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable conditional_variable;
bool processed = false;
class Listener : public affdex::ImageListener {
public:
Listener(std::ofstream * fout) {
this->fout = fout;
}
virtual void onImageCapture(affdex::Frame image){
//std::cout << "called";
}
virtual void onImageResults(std::map<affdex::FaceId, affdex::Face> faces, affdex::Frame image){
//std::cout << faces.size() << " faces detected:" << std::endl;
for(auto& kv : faces){
(*this->fout) << image.getTimestamp() << ",";
(*this->fout) << kv.first << ",";
(*this->fout) << kv.second.emotions.joy << ",";
(*this->fout) << kv.second.emotions.fear << ",";
(*this->fout) << kv.second.emotions.disgust << ",";
(*this->fout) << kv.second.emotions.sadness << ",";
(*this->fout) << kv.second.emotions.anger << ",";
(*this->fout) << kv.second.emotions.surprise << ",";
(*this->fout) << kv.second.emotions.contempt << ",";
(*this->fout) << kv.second.emotions.valence << ",";
(*this->fout) << kv.second.emotions.engagement << ",";
(*this->fout) << kv.second.measurements.orientation.pitch << ",";
(*this->fout) << kv.second.measurements.orientation.yaw << ",";
(*this->fout) << kv.second.measurements.orientation.roll << ",";
(*this->fout) << kv.second.faceQuality.brightness << std::endl;
//std::cout << kv.second.emotions.fear << std::endl;
//std::cout << kv.second.emotions.surprise << std::endl;
//std::cout << (int) kv.second.emojis.dominantEmoji;
}
}
private:
std::ofstream * fout;
};
class ProcessListener : public affdex::ProcessStatusListener{
public:
virtual void onProcessingException (affdex::AffdexException ex){
std::cerr << "[Error] " << ex.getExceptionMessage();
}
virtual void onProcessingFinished (){
{
std::lock_guard<std::mutex> lk(m);
processed = true;
std::cout << "[Affectiva] Video processing finised." << std::endl;
}
conditional_variable.notify_one();
}
};
int main(int argc, char ** argsv)
{
affdex::VideoDetector detector(60, 1, affdex::FaceDetectorMode::SMALL_FACES);
//affdex::VideoDetector detector(60, 1, affdex::FaceDetectorMode::LARGE_FACES);
std::string classifierPath="/home/wrafael/affdex-sdk/data";
detector.setClassifierPath(classifierPath);
detector.setDetectAllEmotions(true);
// Output
std::ofstream fout(argsv[2]);
fout << "timestamp" << ",";
fout << "faceId" << ",";
fout << "joy" << ",";
fout << "fear" << ",";
fout << "disgust" << ",";
fout << "sadness" << ",";
fout << "anger" << ",";
fout << "surprise" << ",";
fout << "contempt" << ",";
fout << "valence" << ",";
fout << "engagement" << ",";
fout << "pitch" << ",";
fout << "yaw" << ",";
fout << "roll" << ",";
fout << "brightness" << std::endl;
Listener l(&fout);
ProcessListener pl;
detector.setImageListener(&l);
detector.setProcessStatusListener(&pl);
detector.start();
detector.process(argsv[1]);
// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
conditional_variable.wait(lk, []{return processed;});
}
fout.flush();
fout.close();
}
Edit 2 : Теперь я углубился в проблему и посмотрел только один файл GoPro с длительностью 19 минут 53 с (GoPro разбивает записи).Когда я запускаю Affectiva с affdex::VideoDetector detector(60, 1, affdex::FaceDetectorMode::SMALL_FACES);
для этого необработанного видео, создается следующий файл .Affectiva останавливается через 906 с без сообщения об ошибке и без печати «[Affectiva] Обработка видео завершена».
Когда я теперь преобразовываю видео с помощью ffmpeg -i raw.MP4 -y -vcodec libx264 -preset medium -r 60 -map_metadata 0:g -strict -2 out.MP4
, а затем запускаю Affectiva с affdex::VideoDetector detector(60, 1, affdex::FaceDetectorMode::SMALL_FACES);
, Affectiva работает до концаи печатает «[Affectiva] Обработка видео завершена», но частота кадров составляет всего 23 кадра в секунду. Здесь - это файл.
Когда я теперь запускаю Affectiva с affdex::VideoDetector detector(62, 1, affdex::FaceDetectorMode::SMALL_FACES);
для этого преобразованного файла, Affectiva останавливается через 509 секунд, и «[Affectiva] Обработка видео завершена» не печатается. Здесь - файл.