diff --git a/src/args.cpp b/src/args.cpp index 46789e4..ba6f2b3 100644 --- a/src/args.cpp +++ b/src/args.cpp @@ -1,5 +1,6 @@ #include #include +#include const char* argp_program_version = PROJECT_NAME " " VERSION_CODE "\n\n" @@ -14,6 +15,11 @@ const struct argp_option options[] = { {"haar-cascade", 0x00, 0, 0, "Use Haar Cascades for faster (but less accurate) face detection.", 0}, {"show-camera", 0x01, 0, 0, "Show the camera feed in another window", 0}, {"model", 'm', "model", 0, "Name of the model file to use. (not including '.fma')", 0}, + // this option actually selects the minimum camera id to use, + // i.e. instead of trying video0, video1, ... it will try + // starting from 'c'. + // e.g. -c6 is passed, so the program will try video6, video7, etc. + {"camera", 'c', "id", 0, "ID number of camera to use (e.g. /dev/videoXX where XX is the ID)", 0}, {0} }; @@ -29,10 +35,12 @@ struct optData optData = { false, false, "test", + 0, }; #ifndef _WIN32 error_t parseOptions(int key, char* arg, struct argp_state* state) { + std::cout << key << ": " << arg << std::endl; switch (key) { case 0x00: //--haar-cascade optData.useHaar = true; @@ -46,6 +54,10 @@ error_t parseOptions(int key, char* arg, struct argp_state* state) { optData.model = std::string(arg); break; + case 'c': + optData.minCameraID = std::stoi(arg); + break; + default: return ARGP_ERR_UNKNOWN; } diff --git a/src/args.hpp b/src/args.hpp index e006bef..a007e4d 100644 --- a/src/args.hpp +++ b/src/args.hpp @@ -13,6 +13,7 @@ struct optData { bool useHaar; // use haar cascades (0x00) bool showCamera; // show camera feed (0x01) std::string model; // model to open (0x6d 'm') + int minCameraID; // camera id to start search on (0x63 'c') }; extern const char* argp_program_version; diff --git a/src/configfile.cpp b/src/configfile.cpp index 80275a9..eaff972 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -24,6 +24,10 @@ bool configFileOpen(struct optData* data) { if (modelNameResult.first) { data->model = modelNameResult.second; } + auto cameraResult = configFile.table->getInt("min_camera_id"); + if (cameraResult.first) { + data->minCameraID = cameraResult.second; + } return true; } diff --git a/src/cv.cpp b/src/cv.cpp index 23b5c52..6a908c1 100644 --- a/src/cv.cpp +++ b/src/cv.cpp @@ -44,7 +44,7 @@ void initCV() { // cycle through all available cameras until we find one we can open std::cout << "Looking for an open camera..." << std::endl; - for (int i = 0; i < 127; i++) { + for (int i = optData.minCameraID; i < 127; i++) { vid = cv::VideoCapture (i); if (vid.isOpened()) { std::cout << "Camera " << i << " opened" << std::endl; diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 72e209a..93b59a5 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -10,6 +10,7 @@ #ifndef WX_PRECOMP #include #endif +#include class ConfigurationApp : public wxApp { public: @@ -24,6 +25,7 @@ class ConfigurationFrame : public wxFrame { wxCheckBox* useHaarCheckBox; wxCheckBox* showCameraCheckBox; wxChoice* modelNameChoice; + wxSpinCtrl* cameraSpinCtrl; void loadExistingConfig(); // loads existing config file and populates controls void OnApply(wxCommandEvent& event); void OnExit(wxCommandEvent& event); @@ -56,13 +58,20 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " showCameraCheckBox = new wxCheckBox(panel, wxID_ANY, "Show camera feed"); wxStaticText* modelNameText = new wxStaticText(panel, wxID_ANY, "Model name:"); modelNameChoice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, modelVec.size(), modelArray); + wxStaticText* cameraText = new wxStaticText(panel, wxID_ANY, "Camera ID:"); + cameraSpinCtrl = new wxSpinCtrl(panel); wxBoxSizer* modelSizer = new wxBoxSizer(wxHORIZONTAL); // need to put label next to dropdown modelSizer->Add(modelNameText, 0, wxALIGN_CENTER | wxALL, 5); modelSizer->Add(modelNameChoice, 0, wxLEFT, 20); + wxBoxSizer* cameraSizer = new wxBoxSizer(wxHORIZONTAL); + cameraSizer->Add(cameraText, 0, wxALIGN_CENTER | wxALL, 5); + cameraSizer->Add(cameraSpinCtrl, 0, wxLEFT, 20); + wxStaticBoxSizer* generalBoxSizer = new wxStaticBoxSizer(new wxStaticBox(panel, wxID_ANY, "General"), wxVERTICAL); generalBoxSizer->Add(modelSizer, 0, wxALL, 5); + generalBoxSizer->Add(cameraSizer, 0, wxALL, 5); generalBoxSizer->Add(showCameraCheckBox, 0, wxALL, 5); wxStaticBoxSizer* performanceBoxSizer = new wxStaticBoxSizer(new wxStaticBox(panel, wxID_ANY, "Performance"), wxVERTICAL); @@ -102,6 +111,7 @@ void ConfigurationFrame::loadExistingConfig() { break; } } + cameraSpinCtrl->SetValue(configData.minCameraID); } void ConfigurationFrame::OnApply(wxCommandEvent& event) { @@ -115,6 +125,7 @@ void ConfigurationFrame::OnApply(wxCommandEvent& event) { if (modelNameChoice->GetSelection() != wxNOT_FOUND) { configFile << "model = \"" << modelVec[modelNameChoice->GetSelection()] << "\""<< std::endl; } + configFile << "min_camera_id = " << cameraSpinCtrl->GetValue() << std::endl; configFile.close(); Close(true);