Jan gewinnt die Code Competition

IT-Talents: Hallo Jan, herzlichen Glückwunsch zu Deinem ersten Platz bei der Code Competition „Mustererkennung“! Erzähl den anderen IT-Talenten doch kurz etwas über Dich. Jan: Ich bin 19 Jahre alt und jetzt in den letzten Wochen meiner Schulzeit, da ich dieses Jahr das Abitur abschließe. Ich habe vor ca. 6 Jahren mit dem Programmieren angefangen und bin immer auf der Suche nach spannenden Aufgaben und Herausforderungen. IT-Talents: Was hat Dich motiviert, an der Competition teilzunehmen und wie bist Du auf den Wettbewerb aufmerksam geworden? Jan: Ich habe vor einem halben Jahr von einem Schulkamerad von der it-talents Seite erzählt bekommen. Seitdem schaue ich immer mal wieder vorbei und gucke was es so Neues gibt, wobei mich diese Code Competition besonders angesprochen hat. Daraufhin habe ich relativ schnell mit dem Programmieren angefangen und mich immer weiter damit beschäftigt. IT-Talents: Wie bist Du an die Lösung der Aufgabenstellung herangegangen? Hattest Du schon Erfahrung mit Algorithmen zur Mustererkennung? Jan: Erfahrung mit dem Thema hatte ich noch nicht wirklich. Es gab dann zunächst einen “Crashkurs” in Bildverarbeitung mit YouTube-Videos und verschiedenen Internetseiten um mich mit gängigen Methoden und Algorithmen vertraut zu machen, die mir möglicherweise bei dem Problem helfen könnten. Dabei bin ich dann auch relativ schnell auf die Bildverarbeitungsbibliothek OpenCV gekommen, die fast alle nötigen Algorithmen zur Verfügung stellt und sich super zur Anschauung anbietet. IT-Talents: Welche Probleme sind bei der Entwicklung der Software aufgekommen? Wie lange hat die Entwicklung gedauert? Jan: Vor allem die Einarbeitung in das Thema und ein grobes Verständnis der Methoden zum Lösen waren sehr demotivierend, da diese oft deutlich tieferes mathematisches Verständnis fordern und ziemlich komplex sind. Außerdem waren Tests während dem Programmieren immer wieder fehlerhaft und haben Zweifel am Funktionieren der Software verursacht. IT-Talents: Und was hast Du durch die Entwicklung gelernt? Jan: Während der Entwicklung war vor allem die Dokumentation des Projekt für mich sehr wichtig, da ich diese meist vernachlässige. Dabei habe ich unter anderem Doxygen und Markdown als gängige Mittel zur Dokumentation kennengelernt. Außerdem waren natürlich die vielen Bildverarbeitungsalgorithmen sehr spannend und haben mein Wissen in diese Richtung deutlich erweitert. IT-Talents: Zu guter Letzt: Was würdest Du Dir thematisch gerne einmal als Code Competition wünschen? Jan: Ich glaube einen konkreten Wunsch habe ich nicht. Ich lasse mich dann lieber überraschen und schaue mal was noch so kommt. IT-Talents: Vielen Dank für Deine Teilnahme, das Interview und viel Spaß mit Deinem Gewinn Wie sieht Jans Programm aus? #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-&gt;setupUi(this); init(); initGui(); setConnections(); registerTemplateMatcher(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::init() { // Instanzen erzeugen, auf die die Pointer verweisen sollen // Memorymanagment wird durch parent (this) übernommen -&gt; Deallokieren nicht nötig _matching_progressbar = new QProgressBar(this); _image_manager = new ImageIOManager(this); _template_matching_processor = new TemplateMatchingProcessor(this); // Pointer auf ImageManager auch an TemplateMatchingProcessor übergeben _template_matching_processor-&gt;setImageManager(_image_manager); } void MainWindow::initGui() { // Ladebalken in Statusbar hinzufügen (nicht möglichen im Designer) ui-&gt;statusBar-&gt;addPermanentWidget(_matching_progressbar,1); // ladebalken erstmal deaktiveren ui-&gt;statusBar-&gt;setVisible(false); // Vorschau zurücksetzten (-&gt;Scrollbar deaktiveren) updateUnfilteredImages(); // Vorschau zurücksetzten (-&gt;Scrollbar deaktiveren) updateFilteredImages(); } void MainWindow::setConnections() { // Alle Verbindungen der Objecte und Widgets untereinander herstellen QObject::connect(ui-&gt;filter_widget, &amp;FilterWidget::templateMatcherChanged, _template_matching_processor, &amp;TemplateMatchingProcessor::setTemplateMatcher); QObject::connect(ui-&gt;filter_widget, &amp;FilterWidget::imagesShouldCotainTemplate, _template_matching_processor, &amp;TemplateMatchingProcessor::imagesShouldContainTemplate); QObject::connect(ui-&gt;apply_filter_button, &amp;QPushButton::clicked, this, &amp;MainWindow::startMatching); QObject::connect(_template_matching_processor, &amp;TemplateMatchingProcessor::matchingStatusChanged, this, &amp;MainWindow::setMatchingStatus); QObject::connect(_template_matching_processor, &amp;TemplateMatchingProcessor::matchingFinished, this, &amp;MainWindow::matchingFinished); QObject::connect(ui-&gt;import_images_button, &amp;QPushButton::clicked, this, &amp;MainWindow::importImagesDialog); QObject::connect(ui-&gt;clear_all_button, &amp;QPushButton::clicked, this, &amp;MainWindow::clearImages); QObject::connect(ui-&gt;export_images_button, &amp;QPushButton::clicked, this, &amp;MainWindow::exportImagesDialog); QObject::connect(ui-&gt;unfiltered_scrollbar, &amp;QScrollBar::valueChanged, this, &amp;MainWindow::unfilteredImagesScroll); QObject::connect(ui-&gt;filtered_scrollbar, &amp;QScrollBar::valueChanged, this, &amp;MainWindow::filterImageScroll); QObject::connect(ui-&gt;stop_filtering_button, &amp;QPushButton::clicked, _template_matching_processor, &amp;TemplateMatchingProcessor::stopMatching); } void MainWindow::registerTemplateMatcher() { // Es wird ein neues Filter Objekt instanziert und der Pointer an das FilterWidget übergeben ui-&gt;filter_widget-&gt;registerTemplateMatcher(new CorrelationTemplateMatcher(this)); ui-&gt;filter_widget-&gt;registerTemplateMatcher(new FeatureTemplateMatcher(this)); } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { // Drop akzeptieren event-&gt;acceptProposedAction(); } void MainWindow::dropEvent(QDropEvent *event) { // Daten des DropEvents holen const QMimeData* mime_data = event-&gt;mimeData(); // nur wenn DropEvent Urls enthält diese weiter überprüfen // (Dateien, werden nur als Urls bei DropEvents übergeben) if (mime_data-&gt;hasUrls()) { // Überprüfen, in welches Widget die Dateien gedropped wurden if (ui-&gt;unfiltered_gbox-&gt;rect().contains( ui-&gt;unfiltered_gbox-&gt;mapFromParent(event-&gt;pos()) )) { // DropEvent annehmen event-&gt;acceptProposedAction(); // Urls holen QList<qurl> urls = mime_data-&gt;urls(); QStringList filenames; // aus Url konkreten Dateipfad (als String) machen for (QUrl url : urls) { if (url.isLocalFile()) { filenames += url.toLocalFile(); } } // ImageManager Dateipfade zum Importieren übergeben _image_manager-&gt;importImages(filenames,ui-&gt;import_recursive_checkbox-&gt;isChecked()); // Vorschau im Programm aktualisieren updateUnfilteredImages(); } else if (ui-&gt;filtered_gbox-&gt;rect().contains( ui-&gt;filtered_gbox-&gt;mapFromParent(event-&gt;pos()) )) { // Daten holen QList<qurl> urls = mime_data-&gt;urls(); // Überprüfen ob nur eine Url übergebn wurde if (urls.size()==1) { // weitere Infos zur übergebenen Url QFileInfo info(urls.first().toLocalFile()); // Überprüfen ob Url auf Ordner verweist if (info.isDir()) { event-&gt;acceptProposedAction(); // gefilterte Bilder in diesen Ordner exportieren _image_manager-&gt;exportImages(info.absoluteFilePath()); } } } } } void MainWindow::importImagesDialog() { // Urls per Dateidialog holen QList<qurl> urls = QFileDialog::getOpenFileUrls(this,"Bild laden"); // Überprüfen ob min. 1 Datei ausgwählt wurde if (urls.size()) { QStringList filenames; // Urls zu Dateipfaden (Strings) konvertieren for (QUrl url : urls) { if (url.isLocalFile()) { filenames += url.toLocalFile(); } } // ImageManager Dateipfade zum Importieren übergeben _image_manager-&gt;importImages(filenames,ui-&gt;import_recursive_checkbox-&gt;isChecked()); // Vorschau aktualiesieren updateUnfilteredImages(); } } void MainWindow::clearImages() { // Bilder aus ImageManager löschen _image_manager-&gt;clearAll(); // Vorschau aktualisieren updateUnfilteredImages(); } void MainWindow::exportImagesDialog() { // Dateidialog zum Auswahlen eines Ordner öffnen QString dirname = QFileDialog::getExistingDirectory(this, "Bilder in Ordner speichern"); // Überprüfen ob Ordner ausgewählt wurde if (dirname.size()) { // ImageManager Ordner zum exportieren übergeben _image_manager-&gt;exportImages(dirname); } } void MainWindow::updateUnfilteredImages() { int unfiltered_count = _image_manager-&gt;unfilteredImagesCount(); // Wenn mehr als 1 Bild Scrollbar anzeigen ui-&gt;unfiltered_scrollbar-&gt;setVisible(unfiltered_count&gt;1); // Überprüfen ob min. 1 Bild vorhanden ist if (unfiltered_count) { // Scrollbar-Grenzen anpassen ui-&gt;unfiltered_scrollbar-&gt;setMinimum(0); ui-&gt;unfiltered_scrollbar-&gt;setMaximum(unfiltered_count-1); // Erstes Bild in Vorschau anzeigen ui-&gt;unfiltered_image_label-&gt;setImage(_image_manager-&gt;unfilteredImage(0)); } else { // Vorschau aufräumen ui-&gt;unfiltered_image_label-&gt;clear(); } } void MainWindow::updateFilteredImages() { int filtered_count = _image_manager-&gt;filteredImagesCount(); // Wenn mehr als 1 Bild Scrollbar anzeigen ui-&gt;filtered_scrollbar-&gt;setVisible(filtered_count&gt;1); // Überprüfen ob min. 1 Bild vorhanden ist if (filtered_count) { // Scrollbar-Grenzen anpassen ui-&gt;filtered_scrollbar-&gt;setMinimum(0); ui-&gt;filtered_scrollbar-&gt;setMaximum(filtered_count-1); // Erstes Bild in Vorschau anzeigen ui-&gt;filtered_image_label-&gt;setImage(_image_manager-&gt;filteredImage(0)); } else { // Vorschau aufräumen ui-&gt;filtered_image_label-&gt;clear(); } } void MainWindow::unfilteredImagesScroll(int index) { // Vorschaubild anhand der Scrollbar Position (-&gt; index) anpassen ui-&gt;unfiltered_image_label-&gt;setImage(_image_manager-&gt;unfilteredImage(index)); } void MainWindow::filterImageScroll(int index) { // Vorschaubild anhand der Scrollbar Position (-&gt; index) anpassen ui-&gt;filtered_image_label-&gt;setImage(_image_manager-&gt;filteredImage(index)); } void MainWindow::startMatching() { // Alte gefilterten Bilder löschen _image_manager-&gt;clearFilteredImages(); // Vorschau löschen updateFilteredImages(); // Ladebalken anzeigen ui-&gt;statusBar-&gt;setVisible(true); // Matching Vorgang starten _template_matching_processor-&gt;startMatching(); } void MainWindow::setMatchingStatus(int status) { // Matching Vorgang mit neuem status aktualisieren _matching_progressbar-&gt;setValue(status); } void MainWindow::matchingFinished() { // Ladebalken deaktivieren ui-&gt;statusBar-&gt;setVisible(false); // Vorschau aktualisieren updateFilteredImages(); } Der Beitrag Jan gewinnt die Code Competition erschien zuerst auf IT-Talents.de.

zum Artikel gehen

Die Gewinner der Code Competition Chatbot

Herzlichen Glückwunsch und Danke für viele spannende Lösungen! Die Auswertung der Code Competition 06/2017 Chatbot und maschinelles Lernen ist ausgewertet. Vielen Dank für die wie immer sehr spannenden Lösungen.Und herzlichen Glückwunsch an die Gewinne

zum Artikel gehen

James gewinnt Code Competition Rucksackproblem

Mit einer tollen Lösung des Rucksackproblems in Java. Der 27jährige Student der Angewandten Informatik in Duisburg gewinnt die Code Competition und erhält 400€ Förderung. Herzlichen Glückwunsch! IT-Talents: Hallo James, herzlichen Glückwunsch zu Dei

zum Artikel gehen

Ist Low Code der neueste Hit

Low Code ist eine Methode zur Entwicklung von Software, bei der viele Elemente bereits vorcodiert zur Verfügung gestellt werden und Programmierer nur noch wenig Code selbst schreiben bzw. ergänzen müssen. Diese Methode zur Softwareentwicklung gewinnt seit

zum Artikel gehen

Florian gewinnt dritten Platz bei Code Competition

Mit seiner Lösung in C# wird er zu einem unserer Hackathon-Gewinner! Florian konnte mit seiner Abgabe bei der Code Competition Zapfsäulenkönig überzeugen und sich beim Programmierwettbewerb einen dritten Platz sichern. Im Folgenden stellt er sich und s

zum Artikel gehen

Manuel gewinnt Code Competition

Für den ersten Platz bei der Code Competition erhält er 500€ Preisgeld! Manuel hat an der Code Competition Changelog Explorer unserers Partnerunternehmens SNP Schneider-Neureither & Partner AG teilgenommen. Mit seiner Lösung konnte Manuel überzeuge

zum Artikel gehen