diff --git a/src/Acid.Cam.v2.Linux.Qt.pro b/src/Acid.Cam.v2.Linux.Qt.pro index b109f9c..3e39d19 100644 --- a/src/Acid.Cam.v2.Linux.Qt.pro +++ b/src/Acid.Cam.v2.Linux.Qt.pro @@ -14,5 +14,5 @@ QMAKE_CXXFLAGS += -std=c++11 `pkg-config acidcam opencv --cflags` RESOURCES += qresource.qrc # Input -HEADERS += main_window.h new_dialog.h plugin.h qtheaders.h select_image.h display_window.h playback_thread.h search_box.h -SOURCES += main.cpp main_window.cpp new_dialog.cpp plugin.cpp select_image.cpp display_window.cpp playback_thread.cpp search_box.cpp +HEADERS += main_window.h new_dialog.h plugin.h qtheaders.h select_image.h display_window.h playback_thread.h search_box.h goto_window.h +SOURCES += main.cpp main_window.cpp new_dialog.cpp plugin.cpp select_image.cpp display_window.cpp playback_thread.cpp search_box.cpp goto_window.cpp diff --git a/src/main_window.cpp b/src/main_window.cpp index f72b2f3..f519d77 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -2,7 +2,7 @@ * Acid Cam v2 - Qt/OpenCV Edition * written by Jared Bruni ( http://lostsidedead.com ) * (C) 2017 GPL -*/ + */ #include "main_window.h" @@ -10,7 +10,7 @@ #include"plugin.h" #include -std::unordered_map filter_map; +std::unordered_map> filter_map; void custom_filter(cv::Mat &); const char *filter_names[] = { "AC Self AlphaBlend", "Reverse Self AlphaBlend", @@ -24,19 +24,19 @@ const char *filter_names[] = { "AC Self AlphaBlend", "Reverse Self AlphaBlend", "Gradient Repeat", 0 }; void generate_map() { - for(int i = 0; i < ac::draw_max; ++i ) { - filter_map[ac::draw_strings[i]] = FilterValue(0, i, -1); - } + for(int i = 0; i < ac::draw_max; ++i ) + filter_map[ac::draw_strings[i]] = std::make_pair(0, i); + int index = 0; while(filter_names[index] != 0) { std::string filter_n = "AF_"; filter_n += filter_names[index]; - filter_map[filter_n] = FilterValue(1, index, -1); + filter_map[filter_n] = std::make_pair(1, index); ++index; } for(unsigned int j = 0; j < plugins.plugin_list.size(); ++j) { std::string name = "plugin " + plugins.plugin_list[j]->name(); - filter_map[name] = FilterValue(2, j, -1); + filter_map[name] = std::make_pair(2, j); } } @@ -68,14 +68,23 @@ AC_MainWindow::AC_MainWindow(QWidget *parent) : QMainWindow(parent) { search_box = new SearchWindow(this); search_box->setParent(this); - + search_box->setFiltersControl(filters, custom_filters); + search_box->main_window = this; statusBar()->showMessage(tr("Acid Cam v2 Loaded - Use File Menu to Start")); take_snapshot = false; + goto_window = new GotoWindow(this); disp = new DisplayWindow(this); playback = new Playback(); + + goto_window->setParent(this); + goto_window->setDisplayWindow(disp); + goto_window->setPlayback(playback); + goto_window->setMainWindow(this); + QObject::connect(playback, SIGNAL(procImage(QImage)), this, SLOT(updateFrame(QImage))); QObject::connect(playback, SIGNAL(stopRecording()), this, SLOT(stopRecording())); QObject::connect(playback, SIGNAL(frameIncrement()), this, SLOT(frameInc())); + QObject::connect(playback, SIGNAL(resetIndex()), this, SLOT(resetIndex())); for(unsigned int i = 0; i < plugins.plugin_list.size(); ++i) { QString text; @@ -90,10 +99,10 @@ AC_MainWindow::AC_MainWindow(QWidget *parent) : QMainWindow(parent) { void AC_MainWindow::createControls() { /* - filters = new QListWidget(this); - filters->setGeometry(10, 30, 390, 180); - filters->show(); - */ + filters = new QListWidget(this); + filters->setGeometry(10, 30, 390, 180); + filters->show(); + */ custom_filters = new QListWidget(this); custom_filters->setGeometry(400, 30, 390, 180); custom_filters->show(); @@ -109,8 +118,6 @@ void AC_MainWindow::createControls() { std::sort(fnames.begin(), fnames.end()); for(unsigned long i = 0; i < fnames.size(); ++i) { - std::string s = fnames[i]; - std::string v = fnames[i]; filters->addItem(fnames[i].c_str()); } @@ -133,10 +140,10 @@ void AC_MainWindow::createControls() { filter_custom->setGeometry(30, 65, 100, 15); filter_single->setChecked(true); - + connect(filter_single, SIGNAL(pressed()), this, SLOT(setFilterSingle())); connect(filter_custom, SIGNAL(pressed()), this, SLOT(setFilterCustom())); - + btn_add = new QPushButton(tr("Add"), this); btn_remove = new QPushButton(tr("Remove"), this); btn_moveup = new QPushButton(tr("Move Up"), this); @@ -190,7 +197,7 @@ void AC_MainWindow::createControls() { slide_bright->setMaximum(255); slide_bright->setMinimum(0); slide_bright->setTickInterval(0); - + QLabel *label_slide_gamma = new QLabel(tr("Gamma: "), this); label_slide_gamma->setGeometry(190, 280, 65, 20); @@ -199,7 +206,7 @@ void AC_MainWindow::createControls() { slide_gamma->setMaximum(255); slide_gamma->setMinimum(0); slide_gamma->setTickInterval(0); - + QLabel *label_sat = new QLabel(tr("Saturation: "), this); label_sat->setGeometry(350, 280, 100, 20); slide_saturation = new QSlider(Qt::Horizontal, this); @@ -215,7 +222,7 @@ void AC_MainWindow::createControls() { QLabel *color_maps_label = new QLabel("Color Maps", this); color_maps_label->setGeometry(545, 260, 75, 20); - color_maps = new QComboBox(this); + color_maps = new QComboBox(this); color_maps->setGeometry(540, 275, 250, 30); color_maps->addItem(tr("None")); color_maps->addItem(tr("Autum")); @@ -232,7 +239,7 @@ void AC_MainWindow::createControls() { color_maps->addItem(tr("Parula")); connect(color_maps, SIGNAL(currentIndexChanged(int)), this, SLOT(colorMapChanged(int))); - + log_text = new QTextEdit(this); log_text->setGeometry(10, 325, 780,310); log_text->setReadOnly(true); @@ -269,6 +276,7 @@ void AC_MainWindow::createMenu() { file_menu = menuBar()->addMenu(tr("&File")); controls_menu = menuBar()->addMenu(tr("&Controls")); + options = menuBar()->addMenu(tr("&Options")); help_menu = menuBar()->addMenu(tr("Help")); file_new_capture = new QAction(tr("Capture from Webcam"),this); @@ -283,51 +291,109 @@ void AC_MainWindow::createMenu() { file_exit->setShortcut(tr("Ctrl+X")); file_menu->addAction(file_exit); + movement = options->addMenu(tr("Movement")); + in_out_increase = new QAction(tr("Move In, Move Out, Increase"), this); + in_out_increase->setCheckable(true); + in_out_increase->setChecked(true); + movement->addAction(in_out_increase); + + in_out = new QAction(tr("Move in, Move Out"), this); + in_out->setCheckable(true); + movement->addAction(in_out); + + out_reset = new QAction(tr("Move Out, Reset"), this); + out_reset->setCheckable(true); + movement->addAction(out_reset); + speed_actions[0] = 0.001; + speed_actions[1] = 0.05; + speed_actions[2] = 0.01; + speed_actions[3] = 0.1; + speed_actions[4] = 0.5; + speed_actions[5] = 1.0; + speed_actions[6] = 3.0; + const QString act_val[] = { "0.001 (Very Slow)", "0.05 (Slow)", "0.01 (Normal)", "0.1 (Regular)", "0.5 (Fast)", "1.0 (Faster)", "3.0 (Very Fast)"}; + speed_menu = options->addMenu("Movement Speed"); + for(int i = 0; i < 7; ++i) { + speed_action_items[i] = new QAction(act_val[i], this); + speed_action_items[i]->setCheckable(true); + speed_menu->addAction(speed_action_items[i]); + } + image_menu = options->addMenu(tr("Image")); + noflip = new QAction(tr("Normal"), this); + noflip->setCheckable(true); + noflip->setChecked(true); + image_menu->addAction(noflip); + flip1 = new QAction(tr("Flip Vertical"), this); + flip1->setCheckable(true); + flip1->setChecked(false); + image_menu->addAction(flip1); + flip2 = new QAction(tr("Flip Horizontal"), this); + flip2->setCheckable(true); + flip2->setChecked(false); + image_menu->addAction(flip2); + flip3 = new QAction(tr("Flip Vertical and Horizontal"), this); + flip3->setCheckable(true); + flip3->setChecked(false); + image_menu->addAction(flip3); + options->addSeparator(); + clear_sub = new QAction(tr("Clear SubFilter"), this); + options->addAction(clear_sub); + clear_sub->setShortcut(tr("Ctrl+F")); + clear_image = new QAction(tr("Clear Image"), this); + options->addAction(clear_image); + options->addSeparator(); + repeat_v = new QAction(tr("Repeat"), this); + repeat_v->setCheckable(true); + repeat_v->setChecked(false); + options->addAction(repeat_v); + connect(repeat_v, SIGNAL(triggered()), this, SLOT(repeat_vid())); + connect(clear_image, SIGNAL(triggered()), this, SLOT(clear_img())); + connect(clear_sub, SIGNAL(triggered()), this, SLOT(clear_subfilter())); + connect(flip1, SIGNAL(triggered()), this, SLOT(flip1_action())); + connect(flip2, SIGNAL(triggered()), this, SLOT(flip2_action())); + connect(flip3, SIGNAL(triggered()), this, SLOT(flip3_action())); + connect(noflip, SIGNAL(triggered()), this, SLOT(noflip_action())); + connect(speed_action_items[0], SIGNAL(triggered()), this, SLOT(speed1())); + connect(speed_action_items[1], SIGNAL(triggered()), this, SLOT(speed2())); + connect(speed_action_items[2], SIGNAL(triggered()), this, SLOT(speed3())); + connect(speed_action_items[3], SIGNAL(triggered()), this, SLOT(speed4())); + connect(speed_action_items[4], SIGNAL(triggered()), this, SLOT(speed5())); + connect(speed_action_items[5], SIGNAL(triggered()), this, SLOT(speed6())); + connect(speed_action_items[6], SIGNAL(triggered()), this, SLOT(speed7())); + speed2(); connect(file_new_capture, SIGNAL(triggered()), this, SLOT(file_NewCamera())); connect(file_new_video, SIGNAL(triggered()), this, SLOT(file_NewVideo())); connect(file_exit, SIGNAL(triggered()), this, SLOT(file_Exit())); - + connect(in_out_increase, SIGNAL(triggered()), this, SLOT(movementOption1())); + connect(in_out, SIGNAL(triggered()), this, SLOT(movementOption2())); + connect(out_reset, SIGNAL(triggered()), this, SLOT(movementOption3())); controls_stop = new QAction(tr("Sto&p"), this); controls_stop->setShortcut(tr("Ctrl+C")); controls_menu->addAction(controls_stop); - controls_stop->setEnabled(false); - controls_snapshot = new QAction(tr("Take &Snapshot"), this); - controls_snapshot->setShortcut(tr("S")); + controls_snapshot->setShortcut(tr("Ctrl+A")); controls_menu->addAction(controls_snapshot); - controls_pause = new QAction(tr("&Pause"), this); - controls_pause->setShortcut(tr("P")); + controls_pause->setShortcut(tr("Ctrl+P")); controls_menu->addAction(controls_pause); - controls_step = new QAction(tr("Step"), this); - controls_step->setShortcut(tr("I")); + controls_step->setShortcut(tr("Ctrl+I")); controls_menu->addAction(controls_step); - controls_setimage = new QAction(tr("Set Image"), this); - controls_setimage->setShortcut(tr("Ctrl+I")); + //controls_setimage->setShortcut(tr("Ctrl+Q")); controls_menu->addAction(controls_setimage); - controls_setkey = new QAction(tr("Set Color Key Image"), this); - controls_setkey->setShortcut(tr("Ctrl+K")); + //controls_setkey->setShortcut(tr("Ctrl+K")); controls_menu->addAction(controls_setkey); - - clear_images = new QAction(tr("Clear Images"), this); - clear_images->setShortcut(tr("Ctrl+E")); - controls_menu->addAction(clear_images); - controls_showvideo = new QAction(tr("Hide Display Video"), this); controls_showvideo->setShortcut(tr("Ctrl+V")); controls_menu->addAction(controls_showvideo); - reset_filters = new QAction(tr("Reset Filters"), this); reset_filters->setShortcut(tr("Ctrl+R")); controls_menu->addAction(reset_filters); - controls_showvideo->setEnabled(false); controls_showvideo->setCheckable(true); - open_search = new QAction(tr("Search Filters"), this); open_search->setShortcut(tr("Ctrl+S")); controls_menu->addAction(open_search); @@ -340,7 +406,6 @@ void AC_MainWindow::createMenu() { connect(controls_setkey, SIGNAL(triggered()), this, SLOT(controls_SetKey())); connect(controls_showvideo, SIGNAL(triggered()), this, SLOT(controls_ShowVideo())); connect(reset_filters, SIGNAL(triggered()), this, SLOT(controls_Reset())); - connect(clear_images, SIGNAL(triggered()), this, SLOT(controls_Clear())); connect(combo_rgb, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_SetIndex(int))); controls_pause->setText(tr("Pause")); help_about = new QAction(tr("About"), this); @@ -353,6 +418,173 @@ void AC_MainWindow::createMenu() { controls_snapshot->setEnabled(false); } +void AC_MainWindow::resetIndex() { + frame_index = 0; +} + +void AC_MainWindow::clear_subfilter() { + ac::setSubFilter(-1); + Log(tr("Cleared SubFilter")); +} + +void AC_MainWindow::clear_img() { + blend_set = false; + blend_image.release(); + Log(tr("Cleared Image\n")); +} + +void AC_MainWindow::flip1_action() { + flip1->setChecked(true); + flip2->setChecked(false); + flip3->setChecked(false); + noflip->setChecked(false); + playback->SetFlip(false, true); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::flip2_action() { + flip1->setChecked(false); + flip2->setChecked(true); + flip3->setChecked(false); + noflip->setChecked(false); + playback->SetFlip(true, false); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::flip3_action() { + flip1->setChecked(false); + flip2->setChecked(false); + flip3->setChecked(true); + noflip->setChecked(false); + playback->SetFlip(true, true); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::noflip_action() { + flip1->setChecked(false); + flip2->setChecked(false); + flip3->setChecked(false); + noflip->setChecked(true); + playback->SetFlip(false, false); + Log(tr("Removed Flip Action\n")); + +} + +void AC_MainWindow::repeat_vid() { + bool val = repeat_v->isChecked(); + playback->enableRepeat(val); + if(val == true) { + Log(tr("Repeat Enabled\n")); + } else { + Log(tr("Repeat Disabled\n")); + } +} + +void AC_MainWindow::speed1() { + ac::alpha_increase = speed_actions[0]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[0]->setChecked(true); + +} +void AC_MainWindow::speed2() { + QString text; + QTextStream stream(&text); + ac::alpha_increase = speed_actions[1]; + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[1]->setChecked(true); + +} +void AC_MainWindow::speed3() { + ac::alpha_increase = speed_actions[2]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[2]->setChecked(true); + +} +void AC_MainWindow::speed4() { + ac::alpha_increase = speed_actions[3]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[3]->setChecked(true); +} +void AC_MainWindow::speed5() { + ac::alpha_increase = speed_actions[4]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[4]->setChecked(true); +} +void AC_MainWindow::speed6() { + ac::alpha_increase = speed_actions[5]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[5]->setChecked(true); +} + +void AC_MainWindow::speed7() { + QString text; + QTextStream stream(&text); + ac::alpha_increase = speed_actions[6]; + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[6]->setChecked(true); +} + +void AC_MainWindow::movementOption1() { + ac::setProcMode(0); + in_out_increase->setChecked(true); + in_out->setChecked(false); + out_reset->setChecked(false); + Log(tr("Proc Mode set to: 0\n")); +} +void AC_MainWindow::movementOption2() { + in_out_increase->setChecked(false); + in_out->setChecked(true); + out_reset->setChecked(false); + ac::setProcMode(1); + Log(tr("Proc Mode set to: 1\n")); +} + +void AC_MainWindow::movementOption3() { + in_out_increase->setChecked(false); + in_out->setChecked(false); + out_reset->setChecked(true); + ac::setProcMode(2); + Log(tr("Proc Mode set to: 2\n")); +} + void AC_MainWindow::chk_Clicked() { playback->setOptions(chk_negate->isChecked(), combo_rgb->currentIndex()); } @@ -379,6 +611,12 @@ void AC_MainWindow::comboFilterChanged(int) { QTextStream stream(&str); stream << "Filter changed to: " << filters->currentText() << "\n"; Log(str); + std::string text = filters->currentText().toStdString(); + if(blend_set == false && text.find("Image") != std::string::npos) + Log(tr("Set an Image to use this filter\n")); + else if(ac::subfilter == -1 && text.find("SubFilter") != std::string::npos) + Log(tr("Set a SubFilter to use this filter\n")); + } void AC_MainWindow::setFilterSingle() { @@ -394,25 +632,29 @@ void AC_MainWindow::addClicked() { int row = filters->currentIndex(); if(row != -1) { //QListWidgetItem *item = filters->item(row); - - std::string sub_str = filters->currentText().toStdString(); - if(sub_str.find("SubFilter") == std::string::npos) - sub_str += ":No Sub Filter"; - else - sub_str += ":Select SubFilter"; - custom_filters->addItem(filters->currentText()); - //custom_filters->addItem(sub_str.c_str()); QString qs; QTextStream stream(&qs); stream << "Added Filter: " << filters->currentText() << "\n"; Log(qs); - std::vector v; + std::string text = filters->currentText().toStdString(); + if(blend_set == false && text.find("Image") != std::string::npos) + Log(tr("Set an Image to use this filter\n")); + else if(ac::subfilter != -1 && text.find("SubFilter") != std::string::npos) + Log(tr("Set a SubFilter to use this filter\n")); + + std::vector> v; buildVector(v); playback->setVector(v); } } +void AC_MainWindow::updateList() { + std::vector> v; + buildVector(v); + playback->setVector(v); +} + void AC_MainWindow::rmvClicked() { int item = custom_filters->currentRow(); if(item != -1) { @@ -421,7 +663,7 @@ void AC_MainWindow::rmvClicked() { QTextStream stream(&qs); stream << "Removed Filter: " << i->text() << "\n"; Log(qs); - std::vector v; + std::vector> v; buildVector(v); playback->setVector(v); } @@ -433,7 +675,7 @@ void AC_MainWindow::upClicked() { QListWidgetItem *i = custom_filters->takeItem(item); custom_filters->insertItem(item-1, i->text()); custom_filters->setCurrentRow(item-1); - std::vector v; + std::vector> v; buildVector(v); playback->setVector(v); } @@ -445,38 +687,40 @@ void AC_MainWindow::downClicked() { QListWidgetItem *i = custom_filters->takeItem(item); custom_filters->insertItem(item+1, i->text()); custom_filters->setCurrentRow(item+1); - std::vector v; + std::vector> v; buildVector(v); playback->setVector(v); } + } void AC_MainWindow::setSub() { int row = filters->currentIndex(); - int crow = custom_filters->currentRow(); - if(row != -1 && crow != -1) { + if(row != -1) { std::ostringstream stream; - QListWidgetItem *item = custom_filters->item(crow); + //QListWidgetItem *item = filters->item(row); QString filter_num = filters->currentText(); - int value_index = filter_map[filter_num.toStdString()].index; - int filter_index = filter_map[filter_num.toStdString()].filter; + std::string text = filter_num.toStdString(); + if(text.find("SubFilter") != std::string::npos) { + std::ostringstream stream; + stream << "SubFilter function: " << filter_num.toStdString() << " cannot be set to a SubFilter function.\n"; + Log(stream.str().c_str()); + return; + } + + int value_index = filter_map[filter_num.toStdString()].first; + int filter_index = filter_map[filter_num.toStdString()].second; if(value_index == 0) { - std::string filter_val = item->text().toStdString(); - if(filter_val.find("SubFilter") == std::string::npos) { - stream << filter_val << " does not support a subfilter.\n"; - Log(stream.str().c_str()); - return; - } stream << "SubFilter set to: " << filter_num.toStdString() << "\n"; - stream << "SubFilter index: " << filter_index << "\n"; - std::ostringstream stream1; - stream1 << filter_num.toStdString() << ":" << item->text().toStdString(); - item->setText(stream1.str().c_str()); - std::vector v; - buildVector(v); - playback->setVector(v); + stream << "SubFilter index: " << filter_index << "\n"; + playback->setSubFilter(filter_index); QString l = stream.str().c_str(); Log(l); + } else { + QString txt; + QTextStream stream(&txt); + stream << "Only Regular Filters can be used as a SubFilter not AF\n"; + Log(txt); } } } @@ -505,21 +749,21 @@ bool AC_MainWindow::startCamera(int res, int dev, const QString &outdir, bool re video_file_name = ""; frame_index = 0; /* - capture_camera.open(dev); - if(!capture_camera.isOpened()) { - return false; - }*/ + capture_camera.open(dev); + if(!capture_camera.isOpened()) { + return false; + }*/ video_frames = 0; video_fps = 24; /* - int ores_w = capture_camera.get(CV_CAP_PROP_FRAME_WIDTH); - int ores_h = capture_camera.get(CV_CAP_PROP_FRAME_HEIGHT); - */ + int ores_w = capture_camera.get(CV_CAP_PROP_FRAME_WIDTH); + int ores_h = capture_camera.get(CV_CAP_PROP_FRAME_HEIGHT); + */ int res_w = 0; int res_h = 0; /*QString str; - QTextStream stream(&str); - stream << "Opened capture device " << res_w << "x" << res_h << "\n"; - stream << "FPS: " << video_fps << "\n";*/ + QTextStream stream(&str); + stream << "Opened capture device " << res_w << "x" << res_h << "\n"; + stream << "FPS: " << video_fps << "\n";*/ output_directory = outdir; frame_index = 0; //Log(str); @@ -549,26 +793,26 @@ bool AC_MainWindow::startCamera(int res, int dev, const QString &outdir, bool re case 2: res_w = 1920; res_h = 1080; - - break; + + break; } /* - bool cw = capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); - bool ch = capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); - - if(cw == false || ch == false) { - QMessageBox::information(this, tr("Info"), tr("Could not set resolution reverting to default ..")); - res_w = ores_w; - res_h = ores_h; - capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); - capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); - } */ + bool cw = capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + bool ch = capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + + if(cw == false || ch == false) { + QMessageBox::information(this, tr("Info"), tr("Could not set resolution reverting to default ..")); + res_w = ores_w; + res_h = ores_h; + capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + } */ if(recording) { video_file_name = output_name; writer = cv::VideoWriter(output_name.toStdString(), (type == 0) ? CV_FOURCC('m', 'p', '4', 'v') : CV_FOURCC('X','V','I','D'), video_fps, cv::Size(res_w, res_h), true); - + if(!writer.isOpened()) { Log(tr("Could not create video writer..\n")); QMessageBox::information(this, tr("Error"), tr("Incorrect Pathname/Or you do not have permission to write to the directory.")); @@ -597,7 +841,7 @@ bool AC_MainWindow::startVideo(const QString &filename, const QString &outdir, b controls_step->setEnabled(true); controls_snapshot->setEnabled(true); if(record == true) - controls_showvideo->setEnabled(true); + controls_showvideo->setEnabled(true); progress_bar->show(); playback->setDisplayed(true); @@ -643,7 +887,7 @@ bool AC_MainWindow::startVideo(const QString &filename, const QString &outdir, b if(recording) { video_file_name = output_name; writer = cv::VideoWriter(output_name.toStdString(), (type == 0) ? CV_FOURCC('m', 'p', '4', 'v') : CV_FOURCC('X','V','I','D'), video_fps, cv::Size(res_w, res_h), true); - + if(!writer.isOpened()) { Log("Error could not open video writer.\n"); QMessageBox::information(this, tr("Error invalid path"), tr("Incorrect Pathname/Or you do not have permission to write to the directory.")); @@ -662,6 +906,7 @@ bool AC_MainWindow::startVideo(const QString &filename, const QString &outdir, b void AC_MainWindow::controls_Stop() { playback->Stop(); + goto_window->hide(); progress_bar->hide(); controls_showvideo->setEnabled(false); controls_stop->setEnabled(false); @@ -723,10 +968,12 @@ void AC_MainWindow::file_Exit() { void AC_MainWindow::file_NewVideo() { cap_video->show(); + goto_window->hide(); } void AC_MainWindow::file_NewCamera() { cap_camera->show(); + goto_window->hide(); } void AC_MainWindow::controls_Snap() { @@ -739,26 +986,27 @@ void AC_MainWindow::controls_Pause() { controls_pause->setText("Paused"); controls_pause->setChecked(true); paused = true; + if(programMode == MODE_VIDEO) goto_window->showWindow(frame_index, 0, video_frames); playback->Stop(); } else { controls_pause->setText("Pause"); controls_pause->setChecked(false); + goto_window->hide(); playback->Play(); paused = false; } } -void AC_MainWindow::controls_Clear() { - playback->Clear(); -} - void AC_MainWindow::controls_SetImage() { QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home", tr("Image Files (*.png *.jpg)")); if(fileName != "") { cv::Mat tblend_image = cv::imread(fileName.toStdString()); if(!tblend_image.empty()) { playback->setImage(tblend_image); - QMessageBox::information(this, tr("Loaded Image"), tr("Image set")); + QString text; + QTextStream stream(&text); + stream << "Successfully Loaded Image: [" << fileName << "] Size: " << tblend_image.cols << "x" << tblend_image.rows << "\n"; + Log(text); } else { QMessageBox::information(this, tr("Image Load failed"), tr("Could not load image")); } @@ -787,22 +1035,12 @@ void AC_MainWindow::controls_Step() { step_frame = true; } -void AC_MainWindow::buildVector(std::vector &v) { +void AC_MainWindow::buildVector(std::vector> &v) { if(!v.empty()) v.erase(v.begin(), v.end()); for(int i = 0; i < custom_filters->count(); ++i) { QListWidgetItem *val = custom_filters->item(i); QString name = val->text(); - std::string n = name.toStdString(); - if(n.find(":") == std::string::npos) - v.push_back(filter_map[name.toStdString()]); - else { - std::string namev = name.toStdString(); - std::string left_str = namev.substr(0, namev.find(":")); - std::string right_str = namev.substr(namev.find(":")+1,namev.length()-left_str.length()-1); - int index_val = filter_map[right_str].filter; - FilterValue fv(filter_map[left_str].index, filter_map[left_str].filter, index_val); - v.push_back(fv); - } + v.push_back(filter_map[name.toStdString()]); } } @@ -824,6 +1062,9 @@ QImage Mat2QImage(cv::Mat const& src) return dest; } +void AC_MainWindow::setFrameIndex(int index) { + frame_index = index; +} void AC_MainWindow::updateFrame(QImage img) { if(playback->isStopped() == false) { @@ -832,7 +1073,7 @@ void AC_MainWindow::updateFrame(QImage img) { QString frame_string; QTextStream frame_stream(&frame_string); if(!recording) { - frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned long)(frame_index/video_fps) << ") "; + frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned long)(frame_index/video_fps) << ") "; } else { struct stat buf; stat(video_file_name.toStdString().c_str(), &buf); @@ -880,18 +1121,43 @@ void AC_MainWindow::stopRecording() { progress_bar->hide(); } +void AC_MainWindow::setSubFilter(const QString &filter_num) { + int value_index = filter_map[filter_num.toStdString()].first; + int filter_index = filter_map[filter_num.toStdString()].second; + if(value_index == 0) { + std::string text = filter_num.toStdString(); + if(text.find("SubFilter") != std::string::npos) { + std::ostringstream stream; + stream << "SubFilter function: " << filter_num.toStdString() << " cannot be set to a SubFilter function.\n"; + Log(stream.str().c_str()); + return; + } + std::ostringstream stream; + stream << "SubFilter set to: " << filter_num.toStdString() << "\n"; + stream << "SubFilter index: " << filter_index << "\n"; + playback->setSubFilter(filter_index); + QString l = stream.str().c_str(); + Log(l); + } else { + QString txt; + QTextStream stream(&txt); + stream << "Only Regular Filters can be used as a SubFilter not AF\n"; + Log(txt); + } +} + void AC_MainWindow::frameInc() { frame_index++; QString frame_string; QTextStream frame_stream(&frame_string); if(!recording) { - frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << ") "; + frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << ") "; } else { struct stat buf; stat(video_file_name.toStdString().c_str(), &buf); frame_stream << "(Current/Total Frames/Seconds/Size) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << "/" << ((buf.st_size/1024)/1024) << " MB) "; - + } if(programMode == MODE_VIDEO) { float index = frame_index; diff --git a/src/main_window.h b/src/main_window.h index 4fcc36d..80fd774 100644 --- a/src/main_window.h +++ b/src/main_window.h @@ -13,6 +13,9 @@ #include "display_window.h" #include "playback_thread.h" #include "search_box.h" +#include "goto_window.h" + +class SearchWindow; class AC_MainWindow : public QMainWindow { Q_OBJECT @@ -30,13 +33,25 @@ public: QSlider *slide_r, *slide_g, *slide_b, *slide_bright, *slide_gamma, *slide_saturation; QProgressBar *progress_bar; QComboBox *color_maps, *filters; - QMenu *file_menu, *controls_menu, *help_menu; + QMenu *file_menu, *controls_menu, *help_menu, *options, *movement, *speed_menu; QAction *file_exit, *file_new_capture, *file_new_video; - QAction *controls_snapshot, *controls_pause, *controls_step, *controls_stop, *controls_setimage,*controls_setkey,*controls_showvideo, *clear_images, *reset_filters; + QAction *controls_snapshot, *controls_pause, *controls_step, *controls_stop, *controls_setimage,*controls_setkey,*controls_showvideo, *reset_filters; QAction *help_about; QAction *open_search; + QAction *in_out_increase; + QAction *in_out; + QAction *out_reset; + QAction *speed_action_items[7]; + QMenu *image_menu; + QAction *flip1, *flip2, *flip3, *noflip; + QAction *clear_sub; + QAction *clear_image; + QAction *repeat_v; + double speed_actions[7]; QRadioButton *filter_single, *filter_custom; - + void updateList(); + void setSubFilter(const QString &num); + void setFrameIndex(int i); public slots: void addClicked(); void rmvClicked(); @@ -53,11 +68,11 @@ public slots: void controls_SetImage(); void controls_ShowVideo(); void controls_SetKey(); - void controls_Clear(); void controls_Reset(); void help_About(); void updateFrame(QImage img); void stopRecording(); + void resetIndex(); void chk_Clicked(); void cb_SetIndex(int index); void frameInc(); @@ -68,6 +83,23 @@ public slots: void setFilterSingle(); void setFilterCustom(); void openSearch(); + void movementOption1(); + void movementOption2(); + void movementOption3(); + void speed1(); + void speed2(); + void speed3(); + void speed4(); + void speed5(); + void speed6(); + void speed7(); + void flip1_action(); + void flip2_action(); + void flip3_action(); + void noflip_action(); + void clear_subfilter(); + void clear_img(); + void repeat_vid(); private: void createControls(); void createMenu(); @@ -75,6 +107,7 @@ private: CaptureCamera *cap_camera; CaptureVideo *cap_video; SearchWindow *search_box; + GotoWindow *goto_window; cv::VideoCapture capture_camera, capture_video; cv::VideoWriter writer; unsigned long video_frames; @@ -86,11 +119,11 @@ private: unsigned long file_pos, frame_index; Playback *playback; VideoMode programMode; - void buildVector(std::vector &v); + void buildVector(std::vector> &v); }; extern const char *filer_names[]; -extern std::unordered_map filter_map; +extern std::unordered_map> filter_map; void generate_map(); #endif diff --git a/src/playback_thread.cpp b/src/playback_thread.cpp index 1a52a94..6513632 100644 --- a/src/playback_thread.cpp +++ b/src/playback_thread.cpp @@ -14,7 +14,10 @@ Playback::Playback(QObject *parent) : QThread(parent) { bright_ = gamma_ = saturation_ = 0; single_mode = true; alpha = 0; - prev_filter = FilterValue(); + prev_filter = std::pair(0, 0); + flip_frame1 = false; + flip_frame2 = false; + repeat_video = false; } void Playback::Play() { @@ -23,7 +26,7 @@ void Playback::Play() { stop = false; } } - // start(LowPriority); + //start(LowPriority); start(HighPriority); } @@ -89,7 +92,7 @@ bool Playback::setVideoCamera(int device, int res, cv::VideoWriter wr, bool reco return true; } -void Playback::setVector(std::vector v) { +void Playback::setVector(std::vector> v) { mutex_add.lock(); current = v; mutex_add.unlock(); @@ -114,6 +117,13 @@ void Playback::reset_filters() { mutex.unlock(); } +void Playback::SetFlip(bool f1, bool f2) { + mutex.lock(); + flip_frame1 = f1; + flip_frame2 = f2; + mutex.unlock(); +} + void Playback::setColorOptions(int b, int g, int s) { mutex.lock(); bright_ = b; @@ -177,31 +187,47 @@ void Playback::drawEffects(cv::Mat &frame) { } } -void Playback::drawFilter(cv::Mat &frame, FilterValue &f) { - if(f.index == 0) { - ac::setSubFilter(f.subfilter); - ac::draw_func[f.filter](frame); - ac::setSubFilter(-1); - } else if(current_filter.index == 1) { - current_filterx = f.filter; +void Playback::drawFilter(cv::Mat &frame, std::pair &filter) { + if(filter.first == 0) { + ac::draw_func[filter.second](frame); + } else if(current_filter.first == 1) { + current_filterx = filter.second; ac::alphaFlame(frame); - } else if(f.index == 2) { - draw_plugin(frame, f.filter); + } else if(filter.first == 2) { + draw_plugin(frame, filter.second); } } void Playback::run() { + int duration = 1000/ac::fps; + while(!stop) { mutex.lock(); if(!capture.read(frame)) { + if(repeat_video && mode == MODE_VIDEO) { + mutex.unlock(); + setFrameIndex(0); + emit resetIndex(); + continue; + } stop = true; mutex.unlock(); emit stopRecording(); return; } + cv::Mat temp_frame; + if(flip_frame1 == true) { + cv::flip(frame, temp_frame, 1); + frame = temp_frame; + } + if(flip_frame2 == true) { + cv::flip(frame, temp_frame, 0); + frame = temp_frame; + } + mutex.unlock(); - static std::vector cur; + static std::vector> cur; mutex_shown.lock(); cur = current; mutex_shown.unlock(); @@ -254,6 +280,7 @@ void Playback::run() { } } + Playback::~Playback() { mutex.lock(); stop = true; @@ -266,6 +293,35 @@ Playback::~Playback() { #endif } +void Playback::setFrameIndex(const long &index) { + mutex.lock(); + capture.set(CV_CAP_PROP_POS_FRAMES, index); + mutex.unlock(); +} + +bool Playback::getFrame(QImage &img, const int &index) { + QImage image; + setFrameIndex(index); + mutex.lock(); + cv::Mat frame; + if(mode == MODE_VIDEO && capture.read(frame)) { + cv::cvtColor(frame, rgb_frame, CV_BGR2RGB); + img = QImage((const unsigned char*)(rgb_frame.data), rgb_frame.cols, rgb_frame.rows, QImage::Format_RGB888); + mutex.unlock(); + setFrameIndex(index); + return true; + } + mutex.unlock(); + return false; +} + +void Playback::enableRepeat(bool re) { + mutex.lock(); + repeat_video = re; + mutex.unlock(); +} + + void Playback::Clear() { mutex.lock(); blend_set = false; @@ -278,7 +334,7 @@ void Playback::Clear() { void Playback::Stop() { stop = true; alpha = 0; - prev_filter = FilterValue(0, 0, -1); + prev_filter = std::pair(0, 0); } void Playback::Release() { @@ -317,7 +373,7 @@ void Playback::setColorKey(const cv::Mat &image) { mutex.unlock(); } -void Playback::filterFade(cv::Mat &frame, FilterValue &filter1, FilterValue &filter2, double alpha) { +void Playback::filterFade(cv::Mat &frame, std::pair &filter1, std::pair &filter2, double alpha) { unsigned int h = frame.rows; // frame height unsigned int w = frame.cols;// framew idth // make copies of original frame diff --git a/src/playback_thread.h b/src/playback_thread.h index 587ae80..9bf3ea5 100644 --- a/src/playback_thread.h +++ b/src/playback_thread.h @@ -27,32 +27,37 @@ private: cv::VideoWriter writer; cv::Mat rgb_frame; QImage img; - //std::vector> current; - std::vector current; + std::vector> current; bool isPaused, isStep; VideoMode mode; int device_num; + unsigned long *frame_index; unsigned int red, green, blue; unsigned int bright_, gamma_, saturation_; bool single_mode; - FilterValue current_filter, prev_filter; + std::pair current_filter, prev_filter; double alpha; + bool flip_frame1, flip_frame2; + bool repeat_video; public: Playback(QObject *parent = 0); ~Playback(); + void setFrameIndex(const long &index); + bool getFrame(QImage &img, const int &index); void setRGB(int r, int g, int b); void setColorOptions(int b, int g, int s); void setColorMap(int c); void Play(); void Stop(); void Release(); + void SetFlip(bool f1, bool f2); void setVideo(cv::VideoCapture cap, cv::VideoWriter writer, bool record); bool setVideoCamera(int device, int res, cv::VideoWriter writer, bool record); bool isStopped() const; void run(); void Clear(); void msleep(int ms); - void setVector(std::vector s); + void setVector(std::vector> s); void setOptions(bool n, int c); void setImage(const cv::Mat &image); void setColorKey(const cv::Mat &image); @@ -60,15 +65,17 @@ public: void setDisplayed(bool shown); void setIndexChanged(std::string name); void setSingleMode(bool val); - void drawFilter(cv::Mat &frame, FilterValue &filter); + void drawFilter(cv::Mat &frame, std::pair &filter); void drawEffects(cv::Mat &frame); - void filterFade(cv::Mat &frame, FilterValue &filter1, FilterValue &filter2, double alpha); + void filterFade(cv::Mat &frame, std::pair &filter1, std::pair &filter2, double alpha); void reset_filters(); void setSubFilter(int index); + void enableRepeat(bool re); signals: void procImage(const QImage image); void stopRecording(); void frameIncrement(); + void resetIndex(); }; diff --git a/src/qtheaders.h b/src/qtheaders.h index e5fc8a9..2596105 100644 --- a/src/qtheaders.h +++ b/src/qtheaders.h @@ -6,7 +6,7 @@ #ifndef _QT_HEADERS__ #define _QT_HEADERS__ -#define ac_version "v1.19.0" +#define ac_version "v1.18.0" #include #include #include @@ -44,22 +44,7 @@ #include #include - -struct FilterValue { - int index, filter, subfilter; - FilterValue() : index(0), filter(0), subfilter(-1) {} - FilterValue(int i, int f, int s) : index(i), filter(f), subfilter(s) {} - FilterValue &operator=(const FilterValue &v) { - index = v.index; - filter = v.filter; - subfilter = v.subfilter; - return *this; - } -}; void init_plugins(); void draw_plugin(cv::Mat &frame, int filter); -extern std::unordered_map filter_map; - - - +extern std::unordered_map> filter_map; #endif diff --git a/src/search_box.cpp b/src/search_box.cpp index bad770a..7c6400b 100644 --- a/src/search_box.cpp +++ b/src/search_box.cpp @@ -1,4 +1,12 @@ -#include "search_box.h" +#include"search_box.h" +#include"tokenize.h" + +std::string lowerString(std::string text) { + std::string new_text; + for(unsigned long i = 0; i < text.length(); ++i) + new_text += tolower(text[i]); + return new_text; +} SearchWindow::SearchWindow(QWidget *parent) : QDialog(parent) { setFixedSize(640, 480); @@ -13,21 +21,70 @@ void SearchWindow::createControls() { search_list->setGeometry(25, 25, 595, 400); search_list->show(); search_text = new QLineEdit(this); - search_text->setGeometry(25, 430, 390, 25); + search_text->setGeometry(25, 430, 290, 30); search_text->show(); search = new QPushButton(this); - search->setGeometry(490+25+10,430, 100, 35); + search->setGeometry(325, 430, 100, 30); search->setText(tr("Search")); + subf = new QPushButton(this); + subf->setGeometry(490+25+10,430, 100, 30); + subf->setText(tr("SubFilter")); add = new QPushButton(this); add->setText(tr("Add")); - add->setGeometry((490+25+10)-100, 430, 100, 35); - + add->setGeometry((490+25+10)-100, 430, 100, 30); connect(search, SIGNAL(pressed()), this, SLOT(search_filter())); + connect(add, SIGNAL(pressed()), this, SLOT(add_current())); + connect(subf, SIGNAL(pressed()), this, SLOT(set_subf())); } void SearchWindow::search_filter() { - + while(search_list->count() > 0) { search_list->takeItem(0); } + + std::string search = lowerString(search_text->text().toStdString()); + std::vector tokens; + token::tokenize(search, std::string(" "), tokens); + + for(int i = 0; i < filters->count(); ++i) { + std::string search_items = lowerString(filters->itemText(i).toStdString()); + for(unsigned q = 0; q < tokens.size(); ++q) { + if(search_items.find(tokens[q]) != std::string::npos) { + search_list->addItem(filters->itemText(i)); + } + } + } +} + +void SearchWindow::add_current() { + int index = search_list->currentRow(); + if(index >= 0) { + QListWidgetItem *in = search_list->item(index); + custom_list->addItem(in->text()); + main_window->updateList(); + std::string text = in->text().toStdString(); + if(blend_set == false && text.find("Image") != std::string::npos) + main_window->Log(tr("Set an Image to use this filter\n")); + else if(text.find("SubFilter") != std::string::npos) + main_window->Log(tr("Set a SubFilter to use this filter\n")); + QString qtext; + QTextStream stream(&qtext); + stream << "Filter set to: " << in->text() << "\n"; + main_window->Log(qtext); + } +} + +void SearchWindow::setFiltersControl(QComboBox *filter_box, QListWidget *custombox) { + filters = filter_box; + custom_list = custombox; +} + +void SearchWindow::set_subf() { + int index = search_list->currentRow(); + if(index >= 0) { + QListWidgetItem *in = search_list->item(index); + main_window->setSubFilter(in->text()); + main_window->updateList(); + } } diff --git a/src/search_box.h b/src/search_box.h index f7f01c4..3b0f2c4 100644 --- a/src/search_box.h +++ b/src/search_box.h @@ -3,22 +3,25 @@ #define __SEARCHBOX__H__ #include "qtheaders.h" +#include "main_window.h" class SearchWindow : public QDialog { Q_OBJECT public: + AC_MainWindow *main_window; SearchWindow(QWidget *parent = 0); void createControls(); + void setFiltersControl(QComboBox *filter_box, QListWidget *custom); public slots: void search_filter(); + void add_current(); + void set_subf(); private: - QListWidget *search_list; + QListWidget *search_list,*custom_list; QLineEdit *search_text; - QPushButton *search, *add; - + QPushButton *search, *add, *subf; + QComboBox *filters; }; - - #endif