123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- #include <QFile>
- #include <QDebug>
- #include <QApplication>
- #include <QDir>
- #include <QTime>
- #include <QCoreApplication>
- #include <QLayout>
- #include <QMessageBox>
- #include <QFileDialog>
- #include <QMap>
- #include "CSVReader.h"
- #include "tinyxml2.h"
- #include "annotationxml.h"
- #include "object.h"
- #include "newsequenz.h"
- AnnotationLoader::AnnotationLoader( QString file, QLabel *status )
- {
- sequenz = 0;
- error = "Pfad nicht gefunden.";
- QDir dir( file + "/Annotations" );
- QFileInfoList fileInfos = dir.entryInfoList();
- int fileCount = fileInfos.count();
- QList< Kamera* > cams;
- QList< Object > objects;
- QList< QString > classes;
- QProgressDialog progress( "Annotation wird geladen...", "", 0, fileCount );
- progress.setWindowModality(Qt::WindowModal);
- progress.setCancelButton( 0 );
- for( int i = 2; i < fileCount; i++ )
- {
- status->setText( "frame " + QString::number( i - 1 ) + "/" + QString::number( fileCount - 2 ) + ", found cameras: " + QString::number( cams.count() ) + ", found packets: " + QString::number( objects.count() ) + " . . ." );
- status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
- status->repaint();
- tinyxml2::XMLDocument doc;
- doc.LoadFile(fileInfos.at( i ).absoluteFilePath().toStdString().c_str() );
- tinyxml2::XMLElement *camera = doc.FirstChildElement()->FirstChildElement("camera_id");
- QString camName = camera->GetText();
- Kamera *c = 0;
- for( auto cam = cams.begin(); cam != cams.end(); cam++ )
- {
- if( (*cam)->getName() == camName )
- c = *cam;
- }
- if( !c )
- {
- c = new Kamera( camName, file + "/SourceMasks/" + QString::number( cams.size() ) + ".jpg", cams.size() );
- cams.append( c );
- }
- Frame *f = new Frame( file + "/SourceImages/" + doc.FirstChildElement()->FirstChildElement("filename")->GetText(),
- doc.FirstChildElement()->FirstChildElement("timestamp")->GetText(), c->getChildCount(), c, doc.FirstChildElement()->FirstChildElement( "noobject" ) != 0 );
- c->addFrame( f );
- tinyxml2::XMLElement *object = doc.FirstChildElement()->FirstChildElement("object");
- if( object )
- {
- do
- {
- int truncated = 0;
- QString className = object->FirstChildElement("name")->GetText();
- int classId = classes.indexOf( className );
- if( classId < 0 )
- {
- classId = classes.size();
- classes.append( className );
- }
- object->FirstChildElement("truncated")->QueryIntText(&truncated);
- QList< QPolygon > polygons;
- tinyxml2::XMLElement *polygon = object->FirstChildElement( "polygon" );
- if( polygon )
- {
- do
- {
- QPolygon pol;
- tinyxml2::XMLElement *point = polygon->FirstChildElement( "point" );
- if( point )
- {
- do
- {
- int x, y;
- point->FirstChildElement( "x" )->QueryIntText( &x );
- point->FirstChildElement( "y" )->QueryIntText( &y );
- pol.push_back( QPoint( x, y ) );
- } while( (point = point->NextSiblingElement() ) != NULL );
- polygons.append( pol );
- }
- } while( (polygon = polygon->NextSiblingElement() ) != NULL );
- }
- QString pName = object->FirstChildElement("id")->GetText();
- if( objects.indexOf( Object( pName, classId ) ) < 0 )
- objects.append( Object( pName, classId ) );
- f->addObject( pName, truncated != 0, polygons );
- } while( ( object = object->NextSiblingElement() ) != NULL );
- }
- f->wasChangedSinceLastSave();
- progress.setValue( progress.value() + 1 );
- }
- sequenz = new Sequenz( file, cams, objects );
- if( !cams.size() )
- {
- sequenz->refRelease();
- sequenz = 0;
- }
- foreach( QString className, classes )
- {
- sequenz->addClass( className );
- }
- }
- AnnotationLoader::~AnnotationLoader()
- {
- if( sequenz )
- sequenz->refRelease();
- }
- Sequenz *AnnotationLoader::getSequenz()
- {
- if( sequenz )
- sequenz->refNew();
- return sequenz;
- }
- QString AnnotationLoader::getErrorMessage()
- {
- return error;
- }
- AnnotationCreator::AnnotationCreator( QString directory, QLabel *status )
- {
- QDir dir( directory );
- QFileInfoList fileInfos = dir.entryInfoList();
- int fileCount = fileInfos.count();
- QString pathToCSV = "";
- for( int i = 2; i < fileCount; i++ )
- {
- if( fileInfos.at( i ).suffix().toLower() == "csv" )
- {
- CSVReader reader( fileInfos.at( i ).absoluteFilePath().toStdString() );
- bool ok = false;
- while( reader.hasNext() )
- {
- std::vector< std::string > row = reader.getNextRow();
- if( row.size() < 3 )
- {
- ok = false;
- break;
- }
- if( row.at( 1 ) == "Info Bild" )
- ok = true;
- }
- if( ok )
- pathToCSV = fileInfos.at( i ).absoluteFilePath();
- }
- }
- QString targetDir;
- if( pathToCSV == "" )
- {
- 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.",
- QMessageBox::Yes|QMessageBox::No);
- if (reply == QMessageBox::Yes) {
- do {
- targetDir = QFileDialog::getExistingDirectory(0,
- "Wo soll die neue Sequenz gespeichert werden?",
- "/studi-tmp/kstrohm",
- QFileDialog::ShowDirsOnly |
- QFileDialog::DontResolveSymlinks);
- if( !QDir( targetDir ).count() )
- QMessageBox::critical(0,"Fehler","Bitte wählen sie einen leeren Ordner aus.");
- } while( !QDir( targetDir ).count() );
- status->setText("Suche Nach Bildern ...");
- status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
- status->repaint();
- numFrames = 0;
- for( int i = 2; i < fileCount; i++ )
- {
- numFrames += getImageCount( fileInfos.at( i ) );
- }
- if( !numFrames )
- {
- QMessageBox::critical(0,"Fehler","Es wurden keine Bilder gefunden. Unterstützte Bildformate sind: jpg, png und bmp.");
- }
- else
- {
- NewSequenz nseq( numFrames );
- nseq.exec();
- int offset = nseq.getOffset();
- int limit = nseq.getLimit();
- numFrames = limit;
- if( limit > 0 && offset >= 0 )
- {
- status->setText("Erstelle Annotation ...");
- status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
- status->repaint();
- int index = 0;
-
- QDir().mkpath( targetDir + "/Annotations" );
- QDir().mkpath( targetDir + "/SourceImages" );
- QDir().mkpath( targetDir + "/SourceMasks" );
- QDir().mkpath( targetDir + "/JPEGImages" );
- int nLen = 0;
- int count = limit;
- while( count > 0 )
- {
- count /= 10;
- nLen++;
- }
- QProgressDialog progress( "Annotation wird erstellt...", "", 0, limit );
- progress.setWindowModality(Qt::WindowModal);
- progress.setCancelButton( 0 );
- int kamId = 0;
- for( int i = 2; i < fileCount; i++ )
- {
- createAnnotationFor( fileInfos.at( i ), index, "", targetDir, nLen, status, offset, limit, progress, kamId );
- }
- AnnotationLoader loader( targetDir, status );
- sequenz = loader.getSequenz();
- }
- }
- }
- }
- else
- {
- do {
- targetDir = QFileDialog::getExistingDirectory(0,
- "Wo soll die neue Sequenz gespeichert werden?",
- "/studi-tmp/kstrohm",
- QFileDialog::ShowDirsOnly |
- QFileDialog::DontResolveSymlinks);
- if( !QDir( targetDir ).count() )
- QMessageBox::critical(0,"Fehler","Bitte wählen sie einen leeren Ordner aus.");
- } while( !QDir( targetDir ).count() );
-
- QDir().mkpath( targetDir + "/Annotations" );
- QDir().mkpath( targetDir + "/SourceImages" );
- QDir().mkpath( targetDir + "/SourceMasks" );
- QDir().mkpath( targetDir + "/JPEGImages" );
- CSVReader reader( pathToCSV.toStdString() );
- status->setText("Suche Nach Bildern ...");
- int numFrames = 0;
- while( reader.hasNext() )
- {
- std::vector< std::string > row = reader.getNextRow();
- if(row.size() < 3 || row.at( 1 ) == "Info Bild")
- continue;
- numFrames++;
- }
- NewSequenz nseq( numFrames );
- nseq.exec();
- int offset = nseq.getOffset();
- int limit = nseq.getLimit();
- int max = limit;
- if( limit > 0 && offset >= 0 )
- {
- reader = CSVReader( pathToCSV.toStdString() );
- int nLen = 0;
- int count = limit;
- while( count > 0 )
- {
- count /= 10;
- nLen++;
- }
- int index = 0;
- QProgressDialog progress( "Annotation wird erstellt...", "", 0, limit );
- progress.setWindowModality(Qt::WindowModal);
- progress.setCancelButton( 0 );
- int maskCount = -1;
- QMap< QString, int > cams;
- while( reader.hasNext() )
- {
- std::vector< std::string > row = reader.getNextRow();
- if(row.size() < 3 || row.at( 1 ) == "Info Bild")
- continue;
- if( offset > 0 )
- {
- offset--;
- continue;
- }
- if( !limit )
- break;
- else
- limit--;
- QString name = QString::number( index++ );
- while( name.length() < nLen )
- name = "0" + name;
- QString camName;
- if( !cams.contains( QString( row.at( 1 ).c_str() ) ) )
- {
- cams.insert( QString( row.at( 1 ).c_str() ), ++maskCount );
- camName = QString::number( maskCount );
- }
- else
- {
- camName = QString::number( cams.take( QString( row.at( 1 ).c_str() ) ) );
- }
- QString sourceImagePath = targetDir + "/SourceImages/" + name + "." + row.at( 0 ).substr(row.at( 0 ).size() - 3).c_str();
- QString jpegImagePath = targetDir + "/JPEGImages/" + name + "." + row.at( 0 ).substr(row.at( 0 ).size() - 3).c_str();
- QString sourceMaskPath = targetDir + "/SourceMasks/" + camName + ".jpg";
- QString imagePath = dir.absolutePath() + "/" + row.at( 0 ).c_str();
- QFile( imagePath ).copy( sourceImagePath );
- QFile( imagePath ).copy( jpegImagePath );
- if( !QFileInfo(sourceMaskPath).exists() )
- {
- QImage mask( imagePath );
- mask.fill( 0xFFFFFFFF );
- mask.save( sourceMaskPath );
- }
- Frame currentFrame( sourceImagePath, QString( row.at( 2 ).c_str() ), 0, 0, 1 );
- tinyxml2::XMLDocument doc;
- doc.LinkEndChild( doc.NewDeclaration( "xml version=\"1.0\" " ) );
- tinyxml2::XMLElement *annotation = doc.NewElement( "annotation");
- annotation->LinkEndChild( doc.NewElement( "folder" ) )->LinkEndChild( doc.NewText( "VOC2007" ) );
- annotation->LinkEndChild( doc.NewElement( "filename" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
- tinyxml2::XMLElement *source = doc.NewElement( "source" );
- source->LinkEndChild( doc.NewElement( "database" ) )->LinkEndChild( doc.NewText( "The VOC2007 Database" ) );
- source->LinkEndChild( doc.NewElement( "annotation" ) )->LinkEndChild( doc.NewText( "PASCAL VOC 2007" ) );
- source->LinkEndChild( doc.NewElement( "image" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
- annotation->LinkEndChild( source );
- annotation->LinkEndChild( doc.NewElement( "owner" ) )->LinkEndChild( doc.NewElement( "name" ) )->LinkEndChild( doc.NewText( "Kolja Strohm" ) );
- annotation->LinkEndChild( doc.NewElement( "camera_id" ) )->LinkEndChild( doc.NewText( row.at( 1 ).c_str() ) );
- tinyxml2::XMLElement *size = doc.NewElement( "size" );
- QImage img = currentFrame.getImage();
- size->LinkEndChild( doc.NewElement( "width" ) )->LinkEndChild( doc.NewText( std::to_string( img.width() ).c_str() ) );
- size->LinkEndChild( doc.NewElement( "height" ) )->LinkEndChild( doc.NewText( std::to_string( img.height() ).c_str() ) );
- size->LinkEndChild( doc.NewElement( "depth" ) )->LinkEndChild( doc.NewText( std::to_string( img.depth() ).c_str() ) );
- annotation->LinkEndChild( size );
- annotation->LinkEndChild( doc.NewElement( "segmented" ) )->LinkEndChild( doc.NewText( "0" ) );
- annotation->LinkEndChild( doc.NewElement( "timestamp" ) )->LinkEndChild( doc.NewText( currentFrame.getTimestamp().toStdString().c_str() ) );
- annotation->LinkEndChild( doc.NewElement( "noobject" ) )->LinkEndChild( doc.NewText( "need Annotation" ) );
- doc.LinkEndChild( annotation );
- name = currentFrame.getName();
- doc.SaveFile( (targetDir + "/Annotations/" + name.mid( 0, name.lastIndexOf( '.' ) ) + ".xml").toStdString().c_str() );
- status->setText( "create Annotation from csv ... " + QString::number((int)((max - limit) / (float)max * 100)) + "% complete" );
- status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
- status->repaint();
- progress.setValue( progress.value() + 1 );
- }
- AnnotationLoader loader( targetDir, status );
- sequenz = loader.getSequenz();
- }
- }
- }
- int AnnotationCreator::getImageCount( QFileInfo f )
- {
- if( f.isDir() )
- {
- int count = 0;
- QFileInfoList fileInfos = QDir( f.absoluteFilePath() ).entryInfoList();
- for( QFileInfo f : fileInfos )
- {
- if( f.fileName() == "." || f.fileName() == ".." )
- continue;
- count += getImageCount( f );
- }
- return count;
- }
- if( f.suffix().toLower() == "jpg" || f.suffix().toLower() == "png" || f.suffix().toLower() == "bmp" )
- return 1;
- return 0;
- }
- void AnnotationCreator::createAnnotationFor( QFileInfo file, int &index, QString kamera, QString targetDir, int nLen, QLabel *status, int &offset, int &limit, QProgressDialog &progress, int &kamId )
- {
- if( limit == 0 )
- return;
- if( file.isDir() )
- {
- QString kamera = file.fileName();
- QDir kamDir( file.absoluteFilePath() );
- QFileInfoList kfInfos = kamDir.entryInfoList();
- for( QFileInfo file : kfInfos )
- {
- QString newKam = kamera;
- if( newKam != "" )
- newKam += "/";
- newKam += file.fileName();
- createAnnotationFor( file, index, newKam, targetDir, nLen, status, offset, limit, progress, kamId );
- }
- kamId++;
- }
- else
- {
- if( offset > 0 )
- {
- offset--;
- return;
- }
- if( limit > 0 )
- limit--;
- if( file.suffix().toLower() == "jpg" || file.suffix().toLower() == "png" || file.suffix().toLower() == "bmp" )
- {
- QString name = QString::number( index );
- while( name.length() < nLen )
- name = "0" + name;
- if( kamera == "" )
- kamera = "Ohne Kamera";
- QString sourceImagePath = targetDir + "/SourceImages/" + name + +"." + file.suffix().toLower();
- QString jpegImagePath = targetDir + "/JPEGImages/" + name + +"." + file.suffix().toLower();
- QString sourceMaskPath = targetDir + "/SourceMasks/" + QString::number( kamId ) + +".jpg";
- QFile( file.absoluteFilePath() ).copy( sourceImagePath );
- QFile( file.absoluteFilePath() ).copy( jpegImagePath );
- if( !QFileInfo(sourceMaskPath).exists() )
- {
- QImage mask( file.absoluteFilePath() );
- mask.fill( 0xFFFFFFFF );
- mask.save( sourceMaskPath );
- }
- Frame currentFrame( sourceImagePath, file.created().toString(Qt::SystemLocaleLongDate), 0, 0, 1 );
- tinyxml2::XMLDocument doc;
- doc.LinkEndChild( doc.NewDeclaration( "xml version=\"1.0\" " ) );
- tinyxml2::XMLElement *annotation = doc.NewElement( "annotation");
- annotation->LinkEndChild( doc.NewElement( "folder" ) )->LinkEndChild( doc.NewText( "VOC2007" ) );
- annotation->LinkEndChild( doc.NewElement( "filename" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
- tinyxml2::XMLElement *source = doc.NewElement( "source" );
- source->LinkEndChild( doc.NewElement( "database" ) )->LinkEndChild( doc.NewText( "The VOC2007 Database" ) );
- source->LinkEndChild( doc.NewElement( "annotation" ) )->LinkEndChild( doc.NewText( "PASCAL VOC 2007" ) );
- source->LinkEndChild( doc.NewElement( "image" ) )->LinkEndChild( doc.NewText( currentFrame.getName().toStdString().c_str() ) );
- annotation->LinkEndChild( source );
- annotation->LinkEndChild( doc.NewElement( "owner" ) )->LinkEndChild( doc.NewElement( "name" ) )->LinkEndChild( doc.NewText( "Kolja Strohm" ) );
- annotation->LinkEndChild( doc.NewElement( "camera_id" ) )->LinkEndChild( doc.NewText( kamera.toStdString().c_str() ) );
- tinyxml2::XMLElement *size = doc.NewElement( "size" );
- QImage img = currentFrame.getImage();
- size->LinkEndChild( doc.NewElement( "width" ) )->LinkEndChild( doc.NewText( std::to_string( img.width() ).c_str() ) );
- size->LinkEndChild( doc.NewElement( "height" ) )->LinkEndChild( doc.NewText( std::to_string( img.height() ).c_str() ) );
- size->LinkEndChild( doc.NewElement( "depth" ) )->LinkEndChild( doc.NewText( std::to_string( img.depth() ).c_str() ) );
- annotation->LinkEndChild( size );
- annotation->LinkEndChild( doc.NewElement( "segmented" ) )->LinkEndChild( doc.NewText( "0" ) );
- annotation->LinkEndChild( doc.NewElement( "timestamp" ) )->LinkEndChild( doc.NewText( currentFrame.getTimestamp().toStdString().c_str() ) );
- annotation->LinkEndChild( doc.NewElement( "noobject" ) )->LinkEndChild( doc.NewText( "need Annotation" ) );
- doc.LinkEndChild( annotation );
- doc.SaveFile( (targetDir + "/Annotations/" + name + ".xml").toStdString().c_str() );
- status->setText( "create Annotation without csv ... " + QString::number((int)((numFrames - limit) / (float)numFrames * 100)) + "% complete" );
- status->setGeometry( status->x(), status->y(), status->fontMetrics().width( status->text() ) + 10, status->height() );
- status->repaint();
- index++;
- progress.setValue( progress.value() + 1 );
- }
- }
- }
- AnnotationCreator::~AnnotationCreator()
- {
- if( sequenz )
- sequenz->refRelease();
- }
- Sequenz *AnnotationCreator::getSequenz()
- {
- if( sequenz )
- sequenz->refNew();
- return sequenz;
- }
|