annotationxml.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #include <QFile>
  2. #include <QDebug>
  3. #include <QApplication>
  4. #include <QDir>
  5. #include <QTime>
  6. #include <QCoreApplication>
  7. #include <QLayout>
  8. #include <QMessageBox>
  9. #include <QFileDialog>
  10. #include <QMap>
  11. #include "CSVReader.h"
  12. #include "tinyxml2.h"
  13. #include "annotationxml.h"
  14. #include "object.h"
  15. #include "newsequenz.h"
  16. // Lädt eine Bildsequenz
  17. // directory: Der Pfad zum Ordner, der die Bildsequenz enthält
  18. // status: Im Verlauf des Ladens wird der Statustext in diesem Label
  19. // gesetzt
  20. AnnotationLoader::AnnotationLoader( QString file, QLabel *status )
  21. {
  22. sequenz = 0;
  23. error = "Pfad nicht gefunden.";
  24. QDir dir( file + "/Annotations" );
  25. QFileInfoList fileInfos = dir.entryInfoList();
  26. int fileCount = fileInfos.count();
  27. QList< Kamera* > cams;
  28. QList< Object > objects;
  29. QList< QString > classes;
  30. QProgressDialog progress( "Annotation wird geladen...", "", 0, fileCount );
  31. progress.setWindowModality(Qt::WindowModal);
  32. progress.setCancelButton( 0 );
  33. for( int i = 2; i < fileCount; i++ )
  34. { // Schleife durch alle xml Dateien mit Annotationen
  35. status->setText( "frame " + QString::number( i - 1 ) + "/" + QString::number( fileCount - 2 ) + ", found cameras: " + QString::number( cams.count() ) + ", found packets: " + QString::number( objects.count() ) + " . . ." );
  36. status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
  37. status->repaint(); // Aktualisiere Status Text
  38. tinyxml2::XMLDocument doc;
  39. doc.LoadFile(fileInfos.at( i ).absoluteFilePath().toStdString().c_str() );
  40. tinyxml2::XMLElement *camera = doc.FirstChildElement()->FirstChildElement("camera_id");
  41. QString camName = camera->GetText();
  42. Kamera *c = 0;
  43. for( auto cam = cams.begin(); cam != cams.end(); cam++ )
  44. { // Suche in den Kameras, ob die Kamera des aktuellen Bildes bereits existiert
  45. if( (*cam)->getName() == camName )
  46. c = *cam;
  47. }
  48. if( !c )
  49. { // Falls die Kamera noch nicht existiert wird diese erstellt
  50. c = new Kamera( camName, file + "/SourceMasks/" + QString::number( cams.size() ) + ".jpg", cams.size() );
  51. cams.append( c );
  52. }
  53. Frame *f = new Frame( file + "/SourceImages/" + doc.FirstChildElement()->FirstChildElement("filename")->GetText(),
  54. doc.FirstChildElement()->FirstChildElement("timestamp")->GetText(), c->getChildCount(), c, doc.FirstChildElement()->FirstChildElement( "noobject" ) != 0 );
  55. c->addFrame( f );
  56. tinyxml2::XMLElement *object = doc.FirstChildElement()->FirstChildElement("object");
  57. if( object )
  58. {
  59. do
  60. { // Schleife durch alle annotierten Objekte des Bildes
  61. int truncated = 0;
  62. QString className = object->FirstChildElement("name")->GetText();
  63. int classId = classes.indexOf( className );
  64. if( classId < 0 )
  65. {
  66. classId = classes.size();
  67. classes.append( className );
  68. }
  69. object->FirstChildElement("truncated")->QueryIntText(&truncated);
  70. QList< QPolygon > polygons;
  71. tinyxml2::XMLElement *polygon = object->FirstChildElement( "polygon" );
  72. if( polygon )
  73. {
  74. do
  75. { // Schleife durch alle Polygone des Objektes
  76. QPolygon pol;
  77. tinyxml2::XMLElement *point = polygon->FirstChildElement( "point" );
  78. if( point )
  79. {
  80. do
  81. { // Schleife durch alle Punkte des Polygons
  82. int x, y;
  83. point->FirstChildElement( "x" )->QueryIntText( &x );
  84. point->FirstChildElement( "y" )->QueryIntText( &y );
  85. pol.push_back( QPoint( x, y ) );
  86. } while( (point = point->NextSiblingElement() ) != NULL );
  87. polygons.append( pol );
  88. }
  89. } while( (polygon = polygon->NextSiblingElement() ) != NULL );
  90. }
  91. QString pName = object->FirstChildElement("id")->GetText();
  92. if( objects.indexOf( Object( pName, classId ) ) < 0 )
  93. objects.append( Object( pName, classId ) );
  94. f->addObject( pName, truncated != 0, polygons );
  95. } while( ( object = object->NextSiblingElement() ) != NULL );
  96. }
  97. f->wasChangedSinceLastSave();
  98. progress.setValue( progress.value() + 1 );
  99. }
  100. sequenz = new Sequenz( file, cams, objects );
  101. if( !cams.size() )
  102. {
  103. sequenz->refRelease();
  104. sequenz = 0;
  105. }
  106. foreach( QString className, classes )
  107. {
  108. sequenz->addClass( className );
  109. }
  110. }
  111. AnnotationLoader::~AnnotationLoader()
  112. {
  113. if( sequenz )
  114. sequenz->refRelease();
  115. }
  116. // Gibt die geladene Sequenz zurück
  117. // 0 falls beim Laden ein Fehler aufgetreten ist
  118. Sequenz *AnnotationLoader::getSequenz()
  119. {
  120. if( sequenz )
  121. sequenz->refNew();
  122. return sequenz;
  123. }
  124. // Gibt eine Fehlermeldung zurück, falls beim Laden ein Fehler aufgetreten
  125. // ist
  126. QString AnnotationLoader::getErrorMessage()
  127. {
  128. return error;
  129. }
  130. // Erstellt eine neue Sequenz und Lädt diese
  131. // directory: Der Pfad zu dem Ordner, welche die Bilder der neuen Sequenz
  132. // enthält
  133. // status: Im Verlauf des Erstellens wird der Statustext in diesem Label
  134. // gesetzt
  135. AnnotationCreator::AnnotationCreator( QString directory, QLabel *status )
  136. {
  137. QDir dir( directory );
  138. QFileInfoList fileInfos = dir.entryInfoList();
  139. int fileCount = fileInfos.count();
  140. QString pathToCSV = "";
  141. for( int i = 2; i < fileCount; i++ )
  142. { // Suche nach der CSV Datei im angegebenen Ordner
  143. if( fileInfos.at( i ).suffix().toLower() == "csv" )
  144. {
  145. CSVReader reader( fileInfos.at( i ).absoluteFilePath().toStdString() );
  146. bool ok = false;
  147. while( reader.hasNext() )
  148. { // Suche nach dem Info Bild in der csv Datei
  149. std::vector< std::string > row = reader.getNextRow();
  150. if( row.size() < 3 )
  151. { // Prüfe, ob die csv Datei das passende Vormat hat
  152. ok = false;
  153. break;
  154. }
  155. if( row.at( 1 ) == "Info Bild" )
  156. ok = true;
  157. }
  158. if( ok )
  159. pathToCSV = fileInfos.at( i ).absoluteFilePath();
  160. }
  161. }
  162. QString targetDir;
  163. if( pathToCSV == "" )
  164. { // Es wurde keine csv Datei gefunden
  165. QMessageBox::StandardButton reply = QMessageBox::question(0, "Achtung", "In dem ausgewählten Ordner wurde keine CSV Datei mit Informationen über die neue Sequenz gefunden. Soll der Ordner manuell nach Bildern durchsucht werden? Die Bilder würden der Sequenz in Alphabetischer Reihenfolge hinzugefügt werden.",
  166. QMessageBox::Yes|QMessageBox::No);
  167. if (reply == QMessageBox::Yes) {
  168. do {
  169. targetDir = QFileDialog::getExistingDirectory(0,
  170. "Wo soll die neue Sequenz gespeichert werden?",
  171. "/studi-tmp/kstrohm",
  172. QFileDialog::ShowDirsOnly |
  173. QFileDialog::DontResolveSymlinks);
  174. if( !QDir( targetDir ).count() )
  175. QMessageBox::critical(0,"Fehler","Bitte wählen sie einen leeren Ordner aus.");
  176. } while( !QDir( targetDir ).count() );
  177. status->setText("Suche Nach Bildern ...");
  178. status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
  179. status->repaint(); // Aktualisiere Status Text
  180. numFrames = 0;
  181. for( int i = 2; i < fileCount; i++ )
  182. { // Zähle alle Bilder im angegebenen Ordner
  183. numFrames += getImageCount( fileInfos.at( i ) );
  184. }
  185. if( !numFrames )
  186. {
  187. QMessageBox::critical(0,"Fehler","Es wurden keine Bilder gefunden. Unterstützte Bildformate sind: jpg, png und bmp.");
  188. }
  189. else
  190. {
  191. NewSequenz nseq( numFrames );
  192. nseq.exec(); // Frage den Nutzer, welche Bilder er in die Neue Bildsequenz übernehmen möchte
  193. int offset = nseq.getOffset(); // Startindex des ersten Bildes
  194. int limit = nseq.getLimit(); // Anzahl der zu übernehmenden Bilder
  195. numFrames = limit;
  196. if( limit > 0 && offset >= 0 )
  197. { // Falls das erstellen nicht abgebrochen wurde
  198. status->setText("Erstelle Annotation ...");
  199. status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
  200. status->repaint();
  201. int index = 0;
  202. // Erzteuge Ordnerstruktur
  203. QDir().mkpath( targetDir + "/Annotations" );
  204. QDir().mkpath( targetDir + "/SourceImages" );
  205. QDir().mkpath( targetDir + "/SourceMasks" );
  206. QDir().mkpath( targetDir + "/JPEGImages" );
  207. int nLen = 0;
  208. int count = limit;
  209. while( count > 0 )
  210. { // Ermittle die maximale Länge des Bildnamens (Die bilder werden 00..01-99..99 nummerriert)
  211. count /= 10;
  212. nLen++;
  213. }
  214. QProgressDialog progress( "Annotation wird erstellt...", "", 0, limit );
  215. progress.setWindowModality(Qt::WindowModal);
  216. progress.setCancelButton( 0 );
  217. int kamId = 0;
  218. for( int i = 2; i < fileCount; i++ )
  219. { // Erzeuge die neue Bildsequenz
  220. createAnnotationFor( fileInfos.at( i ), index, "", targetDir, nLen, status, offset, limit, progress, kamId );
  221. }
  222. AnnotationLoader loader( targetDir, status );
  223. sequenz = loader.getSequenz(); // lade die Bildsequenz
  224. }
  225. }
  226. }
  227. }
  228. else
  229. { // Falls eine CSV Datei existiert
  230. do {
  231. targetDir = QFileDialog::getExistingDirectory(0,
  232. "Wo soll die neue Sequenz gespeichert werden?",
  233. "/studi-tmp/kstrohm",
  234. QFileDialog::ShowDirsOnly |
  235. QFileDialog::DontResolveSymlinks);
  236. if( !QDir( targetDir ).count() )
  237. QMessageBox::critical(0,"Fehler","Bitte wählen sie einen leeren Ordner aus.");
  238. } while( !QDir( targetDir ).count() );
  239. // Erzeuge die Ordnerstruktur
  240. QDir().mkpath( targetDir + "/Annotations" );
  241. QDir().mkpath( targetDir + "/SourceImages" );
  242. QDir().mkpath( targetDir + "/SourceMasks" );
  243. QDir().mkpath( targetDir + "/JPEGImages" );
  244. CSVReader reader( pathToCSV.toStdString() );
  245. status->setText("Suche Nach Bildern ...");
  246. int numFrames = 0;
  247. while( reader.hasNext() )
  248. { // Zahle die Anzahl der Bilder (ohne Info Bild)
  249. std::vector< std::string > row = reader.getNextRow();
  250. if(row.size() < 3 || row.at( 1 ) == "Info Bild")
  251. continue;
  252. numFrames++;
  253. }
  254. NewSequenz nseq( numFrames );
  255. nseq.exec(); // Frage den Nutzer welche Bilder in die neue Sequenz übernommen werden sollen
  256. int offset = nseq.getOffset();
  257. int limit = nseq.getLimit();
  258. int max = limit;
  259. if( limit > 0 && offset >= 0 )
  260. { // falls die Erstellung nicht abgebrochen wurde
  261. reader = CSVReader( pathToCSV.toStdString() );
  262. int nLen = 0;
  263. int count = limit;
  264. while( count > 0 )
  265. { // Ermittle die Maximale Länge des Bildnamens
  266. count /= 10;
  267. nLen++;
  268. }
  269. int index = 0;
  270. QProgressDialog progress( "Annotation wird erstellt...", "", 0, limit );
  271. progress.setWindowModality(Qt::WindowModal);
  272. progress.setCancelButton( 0 );
  273. int maskCount = -1;
  274. QMap< QString, int > cams;
  275. while( reader.hasNext() )
  276. { // Schleife durch jede Zeile der CSV Datei
  277. std::vector< std::string > row = reader.getNextRow();
  278. if(row.size() < 3 || row.at( 1 ) == "Info Bild")
  279. continue;
  280. if( offset > 0 )
  281. {
  282. offset--;
  283. continue;
  284. }
  285. if( !limit )
  286. break;
  287. else
  288. limit--;
  289. QString name = QString::number( index++ );
  290. while( name.length() < nLen )
  291. name = "0" + name;
  292. QString camName;
  293. if( !cams.contains( QString( row.at( 1 ).c_str() ) ) )
  294. {
  295. cams.insert( QString( row.at( 1 ).c_str() ), ++maskCount );
  296. camName = QString::number( maskCount );
  297. }
  298. else
  299. {
  300. camName = QString::number( cams.take( QString( row.at( 1 ).c_str() ) ) );
  301. }
  302. QString sourceImagePath = targetDir + "/SourceImages/" + name + "." + row.at( 0 ).substr(row.at( 0 ).size() - 3).c_str();
  303. QString jpegImagePath = targetDir + "/JPEGImages/" + name + "." + row.at( 0 ).substr(row.at( 0 ).size() - 3).c_str();
  304. QString sourceMaskPath = targetDir + "/SourceMasks/" + camName + ".jpg";
  305. QString imagePath = dir.absolutePath() + "/" + row.at( 0 ).c_str();
  306. QFile( imagePath ).copy( sourceImagePath );
  307. QFile( imagePath ).copy( jpegImagePath );
  308. if( !QFileInfo(sourceMaskPath).exists() )
  309. { // Erzeuge die Maske der Kamera falls sie noch nicht existiert
  310. QImage mask( imagePath );
  311. mask.fill( 0xFFFFFFFF );
  312. mask.save( sourceMaskPath );
  313. }
  314. Frame currentFrame( sourceImagePath, QString( row.at( 2 ).c_str() ), 0, 0, 1 );
  315. tinyxml2::XMLDocument doc; // Erstelle xml Datei
  316. doc.LinkEndChild( doc.NewDeclaration( "xml version=\"1.0\" " ) );
  317. tinyxml2::XMLElement *annotation = doc.NewElement( "annotation");
  318. annotation->LinkEndChild( doc.NewElement( "folder" ) )->LinkEndChild( doc.NewText( "VOC2007" ) );
  319. annotation->LinkEndChild( doc.NewElement( "filename" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
  320. tinyxml2::XMLElement *source = doc.NewElement( "source" );
  321. source->LinkEndChild( doc.NewElement( "database" ) )->LinkEndChild( doc.NewText( "The VOC2007 Database" ) );
  322. source->LinkEndChild( doc.NewElement( "annotation" ) )->LinkEndChild( doc.NewText( "PASCAL VOC 2007" ) );
  323. source->LinkEndChild( doc.NewElement( "image" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
  324. annotation->LinkEndChild( source );
  325. annotation->LinkEndChild( doc.NewElement( "owner" ) )->LinkEndChild( doc.NewElement( "name" ) )->LinkEndChild( doc.NewText( "Kolja Strohm" ) );
  326. annotation->LinkEndChild( doc.NewElement( "camera_id" ) )->LinkEndChild( doc.NewText( row.at( 1 ).c_str() ) );
  327. tinyxml2::XMLElement *size = doc.NewElement( "size" );
  328. QImage img = currentFrame.getImage();
  329. size->LinkEndChild( doc.NewElement( "width" ) )->LinkEndChild( doc.NewText( std::to_string( img.width() ).c_str() ) );
  330. size->LinkEndChild( doc.NewElement( "height" ) )->LinkEndChild( doc.NewText( std::to_string( img.height() ).c_str() ) );
  331. size->LinkEndChild( doc.NewElement( "depth" ) )->LinkEndChild( doc.NewText( std::to_string( img.depth() ).c_str() ) );
  332. annotation->LinkEndChild( size );
  333. annotation->LinkEndChild( doc.NewElement( "segmented" ) )->LinkEndChild( doc.NewText( "0" ) );
  334. annotation->LinkEndChild( doc.NewElement( "timestamp" ) )->LinkEndChild( doc.NewText( currentFrame.getTimestamp().toStdString().c_str() ) );
  335. annotation->LinkEndChild( doc.NewElement( "noobject" ) )->LinkEndChild( doc.NewText( "need Annotation" ) );
  336. doc.LinkEndChild( annotation );
  337. name = currentFrame.getName();
  338. doc.SaveFile( (targetDir + "/Annotations/" + name.mid( 0, name.lastIndexOf( '.' ) ) + ".xml").toStdString().c_str() );
  339. status->setText( "create Annotation from csv ... " + QString::number((int)((max - limit) / (float)max * 100)) + "% complete" );
  340. status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
  341. status->repaint();
  342. progress.setValue( progress.value() + 1 );
  343. }
  344. AnnotationLoader loader( targetDir, status );
  345. sequenz = loader.getSequenz();
  346. }
  347. }
  348. }
  349. // Zählt alle Bilder in einem Ordner
  350. // f: die Informationen zu dem Ordner
  351. int AnnotationCreator::getImageCount( QFileInfo f )
  352. {
  353. if( f.isDir() )
  354. {
  355. int count = 0;
  356. QFileInfoList fileInfos = QDir( f.absoluteFilePath() ).entryInfoList();
  357. for( QFileInfo f : fileInfos )
  358. {
  359. if( f.fileName() == "." || f.fileName() == ".." )
  360. continue;
  361. count += getImageCount( f );
  362. }
  363. return count;
  364. }
  365. if( f.suffix().toLower() == "jpg" || f.suffix().toLower() == "png" || f.suffix().toLower() == "bmp" )
  366. return 1;
  367. return 0;
  368. }
  369. // Erstellt Annotationen zu allen Bildern in einem Ordner
  370. // file: Die Information zur Datei, zu der Annotationen erstellt werden sollen
  371. // index: Der Index des Bildes
  372. // kamera: Der Name der aktuellen Kamera
  373. // targetDir: Der Pfad zum Ziel Ordner
  374. // nLen: Die maximale Länge des Namens
  375. // status: Ein Zeiger auf den Status Text
  376. // offset: Der Index des sersten Bildes der Sequenz
  377. // limit: Die Anzahl der Bilder in der Sequenz
  378. // progress: Ein Dialog mit einer Fortschrittsleiste
  379. // kamId: Die Id der momentanen Kamera
  380. void AnnotationCreator::createAnnotationFor( QFileInfo file, int &index, QString kamera, QString targetDir, int nLen, QLabel *status, int &offset, int &limit, QProgressDialog &progress, int &kamId )
  381. {
  382. if( limit == 0 )
  383. return;
  384. if( file.isDir() )
  385. { // Falls die Datei ein Ordner ist, erfolgt ein recursiver Aufruf für alle Dateien darin
  386. QString kamera = file.fileName();
  387. QDir kamDir( file.absoluteFilePath() );
  388. QFileInfoList kfInfos = kamDir.entryInfoList();
  389. for( QFileInfo file : kfInfos )
  390. {
  391. QString newKam = kamera;
  392. if( newKam != "" )
  393. newKam += "/";
  394. newKam += file.fileName();
  395. createAnnotationFor( file, index, newKam, targetDir, nLen, status, offset, limit, progress, kamId );
  396. }
  397. kamId++;
  398. }
  399. else
  400. { // Falls die Datei kein Ordner ist
  401. if( offset > 0 )
  402. {
  403. offset--;
  404. return;
  405. }
  406. if( limit > 0 )
  407. limit--;
  408. if( file.suffix().toLower() == "jpg" || file.suffix().toLower() == "png" || file.suffix().toLower() == "bmp" )
  409. { // Falls die Datei ein Bild ist, wird eine Annotation für sie erstellt
  410. QString name = QString::number( index );
  411. while( name.length() < nLen )
  412. name = "0" + name;
  413. if( kamera == "" )
  414. kamera = "Ohne Kamera";
  415. QString sourceImagePath = targetDir + "/SourceImages/" + name + +"." + file.suffix().toLower();
  416. QString jpegImagePath = targetDir + "/JPEGImages/" + name + +"." + file.suffix().toLower();
  417. QString sourceMaskPath = targetDir + "/SourceMasks/" + QString::number( kamId ) + +".jpg";
  418. QFile( file.absoluteFilePath() ).copy( sourceImagePath );
  419. QFile( file.absoluteFilePath() ).copy( jpegImagePath );
  420. if( !QFileInfo(sourceMaskPath).exists() )
  421. { // Falls die Maske der Kamera noch nicht existiert wird sie erstellt
  422. QImage mask( file.absoluteFilePath() );
  423. mask.fill( 0xFFFFFFFF );
  424. mask.save( sourceMaskPath );
  425. }
  426. Frame currentFrame( sourceImagePath, file.created().toString(Qt::SystemLocaleLongDate), 0, 0, 1 );
  427. tinyxml2::XMLDocument doc;
  428. doc.LinkEndChild( doc.NewDeclaration( "xml version=\"1.0\" " ) );
  429. tinyxml2::XMLElement *annotation = doc.NewElement( "annotation");
  430. annotation->LinkEndChild( doc.NewElement( "folder" ) )->LinkEndChild( doc.NewText( "VOC2007" ) );
  431. annotation->LinkEndChild( doc.NewElement( "filename" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
  432. tinyxml2::XMLElement *source = doc.NewElement( "source" );
  433. source->LinkEndChild( doc.NewElement( "database" ) )->LinkEndChild( doc.NewText( "The VOC2007 Database" ) );
  434. source->LinkEndChild( doc.NewElement( "annotation" ) )->LinkEndChild( doc.NewText( "PASCAL VOC 2007" ) );
  435. source->LinkEndChild( doc.NewElement( "image" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
  436. annotation->LinkEndChild( source );
  437. annotation->LinkEndChild( doc.NewElement( "owner" ) )->LinkEndChild( doc.NewElement( "name" ) )->LinkEndChild( doc.NewText( "Kolja Strohm" ) );
  438. annotation->LinkEndChild( doc.NewElement( "camera_id" ) )->LinkEndChild( doc.NewText( kamera.toStdString().c_str() ) );
  439. tinyxml2::XMLElement *size = doc.NewElement( "size" );
  440. QImage img = currentFrame.getImage();
  441. size->LinkEndChild( doc.NewElement( "width" ) )->LinkEndChild( doc.NewText( std::to_string( img.width() ).c_str() ) );
  442. size->LinkEndChild( doc.NewElement( "height" ) )->LinkEndChild( doc.NewText( std::to_string( img.height() ).c_str() ) );
  443. size->LinkEndChild( doc.NewElement( "depth" ) )->LinkEndChild( doc.NewText( std::to_string( img.depth() ).c_str() ) );
  444. annotation->LinkEndChild( size );
  445. annotation->LinkEndChild( doc.NewElement( "segmented" ) )->LinkEndChild( doc.NewText( "0" ) );
  446. annotation->LinkEndChild( doc.NewElement( "timestamp" ) )->LinkEndChild( doc.NewText( currentFrame.getTimestamp().toStdString().c_str() ) );
  447. annotation->LinkEndChild( doc.NewElement( "noobject" ) )->LinkEndChild( doc.NewText( "need Annotation" ) );
  448. doc.LinkEndChild( annotation );
  449. doc.SaveFile( (targetDir + "/Annotations/" + name + ".xml").toStdString().c_str() );
  450. status->setText( "create Annotation without csv ... " + QString::number((int)((numFrames - limit) / (float)numFrames * 100)) + "% complete" );
  451. status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
  452. status->repaint();
  453. index++;
  454. progress.setValue( progress.value() + 1 );
  455. }
  456. }
  457. }
  458. AnnotationCreator::~AnnotationCreator()
  459. {
  460. if( sequenz )
  461. sequenz->refRelease();
  462. }
  463. // Gibt die geladene neu erstellte Sequenz zurück
  464. // 0 falls beim Erstellen oder beim Laden ein Fehler aufgetreten ist
  465. Sequenz *AnnotationCreator::getSequenz()
  466. {
  467. if( sequenz )
  468. sequenz->refNew();
  469. return sequenz;
  470. }