/** archive the trained model and return a CVAC style path to the archive; * This file should include the following: * Name of Detector * Name of Extractor * Name of Matcher * Filename of vocabulary * Filename of svm result * OpenCV Version * Optional: one-class ID */ FilePath BowICETrainI::createArchive( DetectorDataArchive& dda, bowCV* pBowCV, const LabelMap& labelmap, const string& clientName, const string& CVAC_DataDir, const string& tempDir ) { std::string clientDir = mServiceMan->getSandbox()->createClientDir(clientName); std::string archiveFilename = getDateFilename(clientDir, "bow")+ ".zip"; dda.setArchiveFilename(archiveFilename); dda.addFile(bowCV::BOW_VOC_FILE, tempDir + "/" + pBowCV->filenameVocabulary); dda.addFile(bowCV::BOW_SVM_FILE, tempDir + "/" + pBowCV->filenameSVM); for (LabelMap::const_iterator it=labelmap.begin(); it!=labelmap.end(); it++) { string classID = "labelname_" + getPurposeName( it->first ); dda.setProperty( classID, it->second ); } dda.createArchive(tempDir); mServiceMan->getSandbox()->deleteTrainingDir(clientName); // create a CVAC FilePath out of the DDA file system path FilePath file; file.filename = getFileName(archiveFilename); std::string relDir; int idx = clientDir.find(CVAC_DataDir.c_str(), 0, CVAC_DataDir.length()); if (idx == 0) { relDir = clientDir.substr(CVAC_DataDir.length() + 1); }else { relDir = clientDir; } file.directory.relativePath = relDir; return file; }
void CascadeTrainI::process(const Identity &client, const RunSet& runset, const TrainerProperties& trainProps, const Current& current) { mTrainProps->load(trainProps); // Obtain CVAC verbosity - TODO: this should happen earlier PropertiesPtr svcprops = current.adapter->getCommunicator()->getProperties(); string verbStr = svcprops->getProperty("CVAC.ServicesVerbosity"); if (!verbStr.empty()) { getVLogger().setLocalVerbosityLevel( verbStr ); } TrainerCallbackHandlerPrx callback = TrainerCallbackHandlerPrx::uncheckedCast(current.con->createProxy(client)->ice_oneway()); if (mTrainProps->hasInfoFile == false) { // check the validity of the runset. if (!checkPurposedLists( runset.purposedLists, callback )) return; } // Get the remote client name to use to save cascade file std::string connectName = cvac::getClientConnectionName(current); const std::string CVAC_DataDir = svcprops->getProperty("CVAC.DataDir"); if(runset.purposedLists.size() == 0 && mTrainProps->hasInfoFile == false) { string _resStr = "Error: no data (runset) for processing\n"; localAndClientMsg(VLogger::WARN, callback, _resStr.c_str()); return; } // Since createSamples fails if there is a space in a file name we will create a temporary runset // and provide symbolic links to files that name spaces in there names. //cvac::RunSet tempRunSet = runset; // Add the cvac data dir to the directories in the runset //addDataPath(tempRunSet, CVAC_DataDir); // The symbolic links are created in a tempdir so lets remember it so we can delete it at the end //std::string tempRSDir = fixupRunSet(tempRunSet, CVAC_DataDir); // Iterate over runset, inserting each POSITIVE Labelable into // the input file to "createsamples". Add each NEGATIVE into // the bgFile. Put both created files into a tempdir. std::string clientName = mServiceMan->getSandbox()->createClientName(mServiceMan->getServiceName(), connectName); std::string tempDir = mServiceMan->getSandbox()->createTrainingDir(clientName); //RunSetWrapper rsw( &tempRunSet, CVAC_DataDir, mServiceMan ); RunSetWrapper rsw( &runset, CVAC_DataDir, mServiceMan ); // We can't put the bgName and infoName in the tempdir without // changing cvSamples since it assumes that this files location is the root // directory for the data. //string bgName = tempDir + "/cascade_negatives.txt"; //string infoName = tempDir + "/cascade_positives.txt"; string bgName = "cascade_negatives.txt"; string infoName = "cascade_positives.txt"; if (mTrainProps->hasInfoFile) infoName = mTrainProps->infoFile; int numNeg = 0; writeBgFile( rsw, bgName, &numNeg, CVAC_DataDir, callback ); // set parameters to createsamples SamplesParams samplesParams; samplesParams.numSamples = 1000; if (mTrainProps->sampleSize.width != 0) samplesParams.width = mTrainProps->sampleSize.width; else samplesParams.width = mTrainProps->windowSize.width; if (mTrainProps->sampleSize.height != 0) samplesParams.height = mTrainProps->sampleSize.height; else samplesParams.height = mTrainProps->windowSize.height; // run createsamples std::string vecFname = tempDir + "/cascade_positives.vec"; int numPos = 0; createSamples( rsw, samplesParams, infoName, vecFname, &numPos, CVAC_DataDir, callback, bgName, numNeg); // Tell ServiceManager that we will listen for stop mServiceMan->setStoppable(); bool created = createClassifier( tempDir, vecFname, bgName, numPos, numNeg, mTrainProps ); // Tell ServiceManager that we are done listening for stop mServiceMan->clearStop(); if (created) { DetectorDataArchive dda; std::string clientDir = mServiceMan->getSandbox()->createClientDir(clientName); std::string archiveFilename = getDateFilename(clientDir, "cascade")+ ".zip"; dda.setArchiveFilename(archiveFilename); dda.addFile(XMLID, tempDir + "/cascade.xml"); dda.createArchive(tempDir); mServiceMan->getSandbox()->deleteTrainingDir(clientName); FilePath detectorData; detectorData.filename = getFileName(archiveFilename); std::string relDir; int idx = clientDir.find(CVAC_DataDir.c_str(), 0, CVAC_DataDir.length()); if (idx == 0) { relDir = clientDir.substr(CVAC_DataDir.length() + 1); }else { relDir = clientDir; } detectorData.directory.relativePath = relDir; callback->createdDetector(detectorData); localAndClientMsg(VLogger::INFO, callback, "Cascade training done.\n"); }else { localAndClientMsg(VLogger::INFO, callback, "Cascade training failed.\n"); } //deleteDirectory(tempRSDir); }