Merge remote-tracking branch 'master' into stitch-fix

* 'master' of github.com:itseez/opencv: (82 commits)
  moved part of video to contrib/{outflow, bgsegm}; moved matlab to contrib
  added some basic functionality needed by the new face module (moved from the old "contrib")
  moved to the new opencv_contrib/face module
  fixed various warnings and obvious errors reported by clang compiler and the coverity tool.
  Fixed review comment from Vadim Pisarevsky
  modified farneback sample to use T-API
  ECC patch by the author (G. Evangelidis); fixed some OCL Farneback optical flow test failures on Mac
  small fix for GaussianBlur ocl test
  fix binary package build
  small fix for ocl_resize
  fix IOS framework
  fixed test ocl_MatchTemplate for sparse matrix
  Fixed typos
  fixing error, wrong template method param.
  fixing Mac build
  some formal changes (generally adding constness)
  Fixed choice of kercn and rowsPerWI for non-Intel device.
  fixed nDiffs for CalcBackProject
  fixed tests for ocl_filter2d, ocl_matchTemplate, ocl_histogram.cpp
  Fixed issue: Mat::copyTo(UMat) if device copy is obsolete. Added test.
  ...

Conflicts:
	modules/core/include/opencv2/core/mat.inl.hpp
This commit is contained in:
mshabunin
2014-08-11 14:50:08 +04:00
346 changed files with 26116 additions and 422526 deletions
+2 -2
View File
@@ -19,9 +19,9 @@ add_subdirectory(native-activity)
# hello-android sample
if(HAVE_opencv_highgui)
ocv_include_modules_recurse(opencv_imgcodecs opencv_videoio opencv_highgui opencv_core)
add_executable(hello-android hello-android/main.cpp)
target_link_libraries(hello-android ${OPENCV_LINKER_LIBS} opencv_imgcodecs opencv_videoio opencv_highgui opencv_core)
ocv_target_include_modules_recurse(hello-android opencv_imgcodecs opencv_videoio opencv_highgui opencv_core)
ocv_target_link_libraries(hello-android ${OPENCV_LINKER_LIBS} opencv_imgcodecs opencv_videoio opencv_highgui opencv_core)
set_target_properties(hello-android PROPERTIES OUTPUT_NAME hello-android RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}")
add_dependencies(opencv_android_examples hello-android)
endif()
+3 -3
View File
@@ -55,14 +55,14 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
set(the_target "${sample_kind}_${name}")
add_executable(${the_target} ${srcs})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
if("${srcs}" MATCHES "gpu/")
target_link_libraries(${the_target} opencv_cudaarithm opencv_cudafilters)
ocv_target_link_libraries(${the_target} opencv_cudaarithm opencv_cudafilters)
endif()
if(HAVE_opencv_ocl)
target_link_libraries(${the_target} opencv_ocl)
ocv_target_link_libraries(${the_target} opencv_ocl)
endif()
set_target_properties(${the_target} PROPERTIES
File diff suppressed because it is too large Load Diff
+63 -58
View File
@@ -23,6 +23,7 @@
#define DEBUG_DESC_PROGRESS
using namespace cv;
using namespace cv::ml;
using namespace std;
const string paramsFile = "params.xml";
@@ -677,7 +678,7 @@ void VocData::writeClassifierResultsFile( const string& out_dir, const string& o
result_file.close();
} else {
string err_msg = "could not open classifier results file '" + output_file + "' for writing. Before running for the first time, a 'results' subdirectory should be created within the VOC dataset base directory. e.g. if the VOC data is stored in /VOC/VOC2010 then the path /VOC/results must be created.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
}
@@ -701,9 +702,9 @@ void VocData::writeClassifierResultsFile( const string& out_dir, const string& o
string VocData::getResultsFilename(const string& obj_class, const VocTask task, const ObdDatasetType dataset, const int competition, const int number)
{
if ((competition < 1) && (competition != -1))
CV_Error(CV_StsBadArg,"competition argument should be a positive non-zero number or -1 to accept the default");
CV_Error(Error::StsBadArg,"competition argument should be a positive non-zero number or -1 to accept the default");
if ((number < 1) && (number != -1))
CV_Error(CV_StsBadArg,"number argument should be a positive non-zero number or -1 to accept the default");
CV_Error(Error::StsBadArg,"number argument should be a positive non-zero number or -1 to accept the default");
string dset, task_type;
@@ -815,7 +816,7 @@ void VocData::calcClassifierPrecRecall(const string& input_file, vector<float>&
scoregt_file.close();
} else {
string err_msg = "could not open scoregt file '" + scoregt_file_str + "' for writing.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
}
@@ -974,7 +975,7 @@ void VocData::calcClassifierConfMatRow(const string& obj_class, const vector<Obd
if (target_idx_it == output_headers.end())
{
string err_msg = "could not find the target object class '" + obj_class + "' in list of valid classes.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
/* convert iterator to index */
target_idx = (int)std::distance(output_headers.begin(),target_idx_it);
@@ -1037,7 +1038,7 @@ void VocData::calcClassifierConfMatRow(const string& obj_class, const vector<Obd
if (class_idx_it == output_headers.end())
{
string err_msg = "could not find object class '" + img_objects[obj_idx].object_class + "' specified in the ground truth file of '" + images[ranking[image_idx]].id +"'in list of valid classes.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
/* convert iterator to index */
int class_idx = (int)std::distance(output_headers.begin(),class_idx_it);
@@ -1189,7 +1190,7 @@ void VocData::calcDetectorConfMatRow(const string& obj_class, const ObdDatasetTy
if (class_idx_it == output_headers.end())
{
string err_msg = "could not find object class '" + img_objects[max_gt_obj_idx].object_class + "' specified in the ground truth file of '" + images[ranking[image_idx]].id +"'in list of valid classes.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
/* convert iterator to index */
int class_idx = (int)std::distance(output_headers.begin(),class_idx_it);
@@ -1282,7 +1283,7 @@ void VocData::savePrecRecallToGnuplot(const string& output_file, const vector<fl
plot_file.close();
} else {
string err_msg = "could not open plot file '" + output_file_std + "' for writing.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
}
@@ -1446,7 +1447,7 @@ void VocData::readClassifierGroundTruth(const string& filename, vector<string>&
if (!gtfile.is_open())
{
string err_msg = "could not open VOC ground truth textfile '" + filename + "'.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
string line;
@@ -1462,7 +1463,7 @@ void VocData::readClassifierGroundTruth(const string& filename, vector<string>&
image_codes.push_back(image);
object_present.push_back(obj_present == 1);
} else {
if (!gtfile.eof()) CV_Error(CV_StsParseError,"error parsing VOC ground truth textfile.");
if (!gtfile.eof()) CV_Error(Error::StsParseError,"error parsing VOC ground truth textfile.");
}
}
gtfile.close();
@@ -1488,13 +1489,13 @@ void VocData::readClassifierResultsFile(const string& input_file, vector<string>
image_codes.push_back(image);
scores.push_back(score);
} else {
if(!result_file.eof()) CV_Error(CV_StsParseError,"error parsing VOC classifier results file.");
if(!result_file.eof()) CV_Error(Error::StsParseError,"error parsing VOC classifier results file.");
}
}
result_file.close();
} else {
string err_msg = "could not open classifier results file '" + input_file + "' for reading.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
}
@@ -1545,13 +1546,13 @@ void VocData::readDetectorResultsFile(const string& input_file, vector<string>&
bounding_boxes[image_idx].push_back(bounding_box);
}
} else {
if(!result_file.eof()) CV_Error(CV_StsParseError,"error parsing VOC detector results file.");
if(!result_file.eof()) CV_Error(Error::StsParseError,"error parsing VOC detector results file.");
}
}
result_file.close();
} else {
string err_msg = "could not open detector results file '" + input_file + "' for reading.";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
}
@@ -1595,23 +1596,23 @@ void VocData::extractVocObjects(const string filename, vector<ObdObject>& object
//object class -------------
if (extractXMLBlock(object_contents, "name", 0, tag_contents) == -1) CV_Error(CV_StsError,"missing <name> tag in object definition of '" + filename + "'");
if (extractXMLBlock(object_contents, "name", 0, tag_contents) == -1) CV_Error(Error::StsError,"missing <name> tag in object definition of '" + filename + "'");
object.object_class.swap(tag_contents);
//object bounding box -------------
int xmax, xmin, ymax, ymin;
if (extractXMLBlock(object_contents, "xmax", 0, tag_contents) == -1) CV_Error(CV_StsError,"missing <xmax> tag in object definition of '" + filename + "'");
if (extractXMLBlock(object_contents, "xmax", 0, tag_contents) == -1) CV_Error(Error::StsError,"missing <xmax> tag in object definition of '" + filename + "'");
xmax = stringToInteger(tag_contents);
if (extractXMLBlock(object_contents, "xmin", 0, tag_contents) == -1) CV_Error(CV_StsError,"missing <xmin> tag in object definition of '" + filename + "'");
if (extractXMLBlock(object_contents, "xmin", 0, tag_contents) == -1) CV_Error(Error::StsError,"missing <xmin> tag in object definition of '" + filename + "'");
xmin = stringToInteger(tag_contents);
if (extractXMLBlock(object_contents, "ymax", 0, tag_contents) == -1) CV_Error(CV_StsError,"missing <ymax> tag in object definition of '" + filename + "'");
if (extractXMLBlock(object_contents, "ymax", 0, tag_contents) == -1) CV_Error(Error::StsError,"missing <ymax> tag in object definition of '" + filename + "'");
ymax = stringToInteger(tag_contents);
if (extractXMLBlock(object_contents, "ymin", 0, tag_contents) == -1) CV_Error(CV_StsError,"missing <ymin> tag in object definition of '" + filename + "'");
if (extractXMLBlock(object_contents, "ymin", 0, tag_contents) == -1) CV_Error(Error::StsError,"missing <ymin> tag in object definition of '" + filename + "'");
ymin = stringToInteger(tag_contents);
object.boundingBox.x = xmin-1; //convert to 0-based indexing
@@ -1714,11 +1715,11 @@ void VocData::extractDataFromResultsFilename(const string& input_file, string& c
size_t fnameend = input_file_std.rfind(".txt");
if ((fnamestart == input_file_std.npos) || (fnameend == input_file_std.npos))
CV_Error(CV_StsError,"Could not extract filename of results file.");
CV_Error(Error::StsError,"Could not extract filename of results file.");
++fnamestart;
if (fnamestart >= fnameend)
CV_Error(CV_StsError,"Could not extract filename of results file.");
CV_Error(Error::StsError,"Could not extract filename of results file.");
//extract dataset and class names, triggering exception if the filename format is not correct
string filename = input_file_std.substr(fnamestart, fnameend-fnamestart);
@@ -1729,11 +1730,11 @@ void VocData::extractDataFromResultsFilename(const string& input_file, string& c
size_t classend = filename.find("_",classstart+1);
if (classend == filename.npos) classend = filename.size();
if ((datasetstart == filename.npos) || (classstart == filename.npos))
CV_Error(CV_StsError,"Error parsing results filename. Is it in standard format of 'comp<n>_{cls/det}_<dataset>_<objclass>.txt'?");
CV_Error(Error::StsError,"Error parsing results filename. Is it in standard format of 'comp<n>_{cls/det}_<dataset>_<objclass>.txt'?");
++datasetstart;
++classstart;
if (((datasetstart-classstart) < 1) || ((classend-datasetstart) < 1))
CV_Error(CV_StsError,"Error parsing results filename. Is it in standard format of 'comp<n>_{cls/det}_<dataset>_<objclass>.txt'?");
CV_Error(Error::StsError,"Error parsing results filename. Is it in standard format of 'comp<n>_{cls/det}_<dataset>_<objclass>.txt'?");
dataset_name = filename.substr(datasetstart,classstart-datasetstart-1);
class_name = filename.substr(classstart,classend-classstart);
@@ -1781,7 +1782,7 @@ bool VocData::getClassifierGroundTruthImage(const string& obj_class, const strin
return m_classifier_gt_all_present[std::distance(m_classifier_gt_all_ids.begin(),it)] != 0;
} else {
string err_msg = "could not find classifier ground truth for image '" + id + "' and class '" + obj_class + "'";
CV_Error(CV_StsError,err_msg.c_str());
CV_Error(Error::StsError,err_msg.c_str());
}
return true;
@@ -1814,7 +1815,7 @@ void VocData::getSortOrder(const vector<float>& values, vector<size_t>& order, b
void VocData::readFileToString(const string filename, string& file_contents)
{
std::ifstream ifs(filename.c_str());
if (!ifs.is_open()) CV_Error(CV_StsError,"could not open text file");
if (!ifs.is_open()) CV_Error(Error::StsError,"could not open text file");
stringstream oss;
oss << ifs.rdbuf();
@@ -1829,7 +1830,7 @@ int VocData::stringToInteger(const string input_str)
stringstream ss(input_str);
if ((ss >> result).fail())
{
CV_Error(CV_StsBadArg,"could not perform string to integer conversion");
CV_Error(Error::StsBadArg,"could not perform string to integer conversion");
}
return result;
}
@@ -1841,7 +1842,7 @@ string VocData::integerToString(const int input_int)
stringstream ss;
if ((ss << input_int).fail())
{
CV_Error(CV_StsBadArg,"could not perform integer to string conversion");
CV_Error(Error::StsBadArg,"could not perform integer to string conversion");
}
result = ss.str();
return result;
@@ -2325,14 +2326,14 @@ static void removeBowImageDescriptorsByCount( vector<ObdImage>& images, vector<M
CV_Assert( bowImageDescriptors.size() == objectPresent.size() );
}
static void setSVMParams( CvSVMParams& svmParams, CvMat& class_wts_cv, const Mat& responses, bool balanceClasses )
static void setSVMParams( SVM::Params& svmParams, Mat& class_wts_cv, const Mat& responses, bool balanceClasses )
{
int pos_ex = countNonZero(responses == 1);
int neg_ex = countNonZero(responses == -1);
cout << pos_ex << " positive training samples; " << neg_ex << " negative training samples" << endl;
svmParams.svm_type = CvSVM::C_SVC;
svmParams.kernel_type = CvSVM::RBF;
svmParams.svmType = SVM::C_SVC;
svmParams.kernelType = SVM::RBF;
if( balanceClasses )
{
Mat class_wts( 2, 1, CV_32FC1 );
@@ -2350,43 +2351,44 @@ static void setSVMParams( CvSVMParams& svmParams, CvMat& class_wts_cv, const Mat
class_wts.at<float>(1) = static_cast<float>(pos_ex)/static_cast<float>(pos_ex+neg_ex);
}
class_wts_cv = class_wts;
svmParams.class_weights = &class_wts_cv;
svmParams.classWeights = class_wts_cv;
}
}
static void setSVMTrainAutoParams( CvParamGrid& c_grid, CvParamGrid& gamma_grid,
CvParamGrid& p_grid, CvParamGrid& nu_grid,
CvParamGrid& coef_grid, CvParamGrid& degree_grid )
static void setSVMTrainAutoParams( ParamGrid& c_grid, ParamGrid& gamma_grid,
ParamGrid& p_grid, ParamGrid& nu_grid,
ParamGrid& coef_grid, ParamGrid& degree_grid )
{
c_grid = CvSVM::get_default_grid(CvSVM::C);
c_grid = SVM::getDefaultGrid(SVM::C);
gamma_grid = CvSVM::get_default_grid(CvSVM::GAMMA);
gamma_grid = SVM::getDefaultGrid(SVM::GAMMA);
p_grid = CvSVM::get_default_grid(CvSVM::P);
p_grid.step = 0;
p_grid = SVM::getDefaultGrid(SVM::P);
p_grid.logStep = 0;
nu_grid = CvSVM::get_default_grid(CvSVM::NU);
nu_grid.step = 0;
nu_grid = SVM::getDefaultGrid(SVM::NU);
nu_grid.logStep = 0;
coef_grid = CvSVM::get_default_grid(CvSVM::COEF);
coef_grid.step = 0;
coef_grid = SVM::getDefaultGrid(SVM::COEF);
coef_grid.logStep = 0;
degree_grid = CvSVM::get_default_grid(CvSVM::DEGREE);
degree_grid.step = 0;
degree_grid = SVM::getDefaultGrid(SVM::DEGREE);
degree_grid.logStep = 0;
}
static void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsExt, const string& objClassName, VocData& vocData,
static Ptr<SVM> trainSVMClassifier( const SVMTrainParamsExt& svmParamsExt, const string& objClassName, VocData& vocData,
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
const string& resPath )
{
/* first check if a previously trained svm for the current class has been saved to file */
string svmFilename = resPath + svmsDir + "/" + objClassName + ".xml.gz";
Ptr<SVM> svm;
FileStorage fs( svmFilename, FileStorage::READ);
if( fs.isOpened() )
{
cout << "*** LOADING SVM CLASSIFIER FOR CLASS " << objClassName << " ***" << endl;
svm.load( svmFilename.c_str() );
svm = StatModel::load<SVM>( svmFilename );
}
else
{
@@ -2437,20 +2439,24 @@ static void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsEx
}
cout << "TRAINING SVM FOR CLASS ..." << objClassName << "..." << endl;
CvSVMParams svmParams;
CvMat class_wts_cv;
SVM::Params svmParams;
Mat class_wts_cv;
setSVMParams( svmParams, class_wts_cv, responses, svmParamsExt.balanceClasses );
CvParamGrid c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid;
svm = SVM::create(svmParams);
ParamGrid c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid;
setSVMTrainAutoParams( c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid );
svm.train_auto( trainData, responses, Mat(), Mat(), svmParams, 10, c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid );
svm->trainAuto(TrainData::create(trainData, ROW_SAMPLE, responses), 10,
c_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid);
cout << "SVM TRAINING FOR CLASS " << objClassName << " COMPLETED" << endl;
svm.save( svmFilename.c_str() );
svm->save( svmFilename );
cout << "SAVED CLASSIFIER TO FILE" << endl;
}
return svm;
}
static void computeConfidences( CvSVM& svm, const string& objClassName, VocData& vocData,
static void computeConfidences( const Ptr<SVM>& svm, const string& objClassName, VocData& vocData,
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
const string& resPath )
{
@@ -2476,12 +2482,12 @@ static void computeConfidences( CvSVM& svm, const string& objClassName, VocData&
if( imageIdx == 0 )
{
// In the first iteration, determine the sign of the positive class
float classVal = confidences[imageIdx] = svm.predict( bowImageDescriptors[imageIdx], false );
float scoreVal = confidences[imageIdx] = svm.predict( bowImageDescriptors[imageIdx], true );
float classVal = confidences[imageIdx] = svm->predict( bowImageDescriptors[imageIdx], noArray(), 0 );
float scoreVal = confidences[imageIdx] = svm->predict( bowImageDescriptors[imageIdx], noArray(), StatModel::RAW_OUTPUT );
signMul = (classVal < 0) == (scoreVal < 0) ? 1.f : -1.f;
}
// svm output of decision function
confidences[imageIdx] = signMul * svm.predict( bowImageDescriptors[imageIdx], true );
confidences[imageIdx] = signMul * svm->predict( bowImageDescriptors[imageIdx], noArray(), StatModel::RAW_OUTPUT );
}
cout << "WRITING QUERY RESULTS TO VOC RESULTS FILE FOR CLASS " << objClassName << "..." << endl;
@@ -2591,9 +2597,8 @@ int main(int argc, char** argv)
for( size_t classIdx = 0; classIdx < objClasses.size(); ++classIdx )
{
// Train a classifier on train dataset
CvSVM svm;
trainSVMClassifier( svm, svmTrainParamsExt, objClasses[classIdx], vocData,
bowExtractor, featureDetector, resPath );
Ptr<SVM> svm = trainSVMClassifier( svmTrainParamsExt, objClasses[classIdx], vocData,
bowExtractor, featureDetector, resPath );
// Now use the classifier over all images on the test dataset and rank according to score order
// also calculating precision-recall etc.
-81
View File
@@ -1,81 +0,0 @@
/*
* FGBGTest.cpp
*
* Created on: May 7, 2012
* Author: Andrew B. Godbehere
*/
#include "opencv2/video.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/utility.hpp>
#include <iostream>
using namespace cv;
static void help()
{
std::cout <<
"\nA program demonstrating the use and capabilities of a particular BackgroundSubtraction\n"
"algorithm described in A. Godbehere, A. Matsukawa, K. Goldberg, \n"
"\"Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive\n"
"Audio Art Installation\", American Control Conference, 2012, used in an interactive\n"
"installation at the Contemporary Jewish Museum in San Francisco, CA from March 31 through\n"
"July 31, 2011.\n"
"Call:\n"
"./BackgroundSubtractorGMG_sample\n"
"Using OpenCV version " << CV_VERSION << "\n"<<std::endl;
}
int main(int argc, char** argv)
{
help();
initModule_video();
setUseOptimized(true);
setNumThreads(8);
Ptr<BackgroundSubtractor> fgbg = createBackgroundSubtractorGMG(20, 0.7);
if (!fgbg)
{
std::cerr << "Failed to create BackgroundSubtractor.GMG Algorithm." << std::endl;
return -1;
}
VideoCapture cap;
if (argc > 1)
cap.open(argv[1]);
else
cap.open(0);
if (!cap.isOpened())
{
std::cerr << "Cannot read video. Try moving video file to sample directory." << std::endl;
return -1;
}
Mat frame, fgmask, segm;
namedWindow("FG Segmentation", WINDOW_NORMAL);
for (;;)
{
cap >> frame;
if (frame.empty())
break;
fgbg->apply(frame, fgmask);
frame.convertTo(segm, CV_8U, 0.5);
add(frame, Scalar(100, 100, 0), segm, fgmask);
imshow("FG Segmentation", segm);
int c = waitKey(30);
if (c == 'q' || c == 'Q' || (c & 255) == 27)
break;
}
return 0;
}
+16 -5
View File
@@ -21,6 +21,8 @@ static void help()
const char* keys =
{
"{c camera | | use camera or not}"
"{m method |mog2 | method (knn or mog2) }"
"{s smooth | | smooth the mask }"
"{fn file_name|tree.avi | movie file }"
};
@@ -31,7 +33,9 @@ int main(int argc, const char** argv)
CommandLineParser parser(argc, argv, keys);
bool useCamera = parser.has("camera");
bool smoothMask = parser.has("smooth");
string file = parser.get<string>("file_name");
string method = parser.get<string>("method");
VideoCapture cap;
bool update_bg_model = true;
@@ -53,24 +57,31 @@ int main(int argc, const char** argv)
namedWindow("foreground image", WINDOW_NORMAL);
namedWindow("mean background image", WINDOW_NORMAL);
Ptr<BackgroundSubtractor> bg_model = createBackgroundSubtractorMOG2();
Ptr<BackgroundSubtractor> bg_model = method == "knn" ?
createBackgroundSubtractorKNN().dynamicCast<BackgroundSubtractor>() :
createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();
Mat img, fgmask, fgimg;
Mat img0, img, fgmask, fgimg;
for(;;)
{
cap >> img;
cap >> img0;
if( img.empty() )
if( img0.empty() )
break;
//cvtColor(_img, img, COLOR_BGR2GRAY);
resize(img0, img, Size(640, 640*img0.rows/img0.cols), INTER_LINEAR);
if( fgimg.empty() )
fgimg.create(img.size(), img.type());
//update the model
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);
if( smoothMask )
{
GaussianBlur(fgmask, fgmask, Size(11, 11), 3.5, 3.5);
threshold(fgmask, fgmask, 10, 255, THRESH_BINARY);
}
fgimg = Scalar::all(0);
img.copyTo(fgimg, fgmask);
+5 -3
View File
@@ -2,6 +2,7 @@
#include "opencv2/ml.hpp"
using namespace cv;
using namespace cv::ml;
int main( int /*argc*/, char** /*argv*/ )
{
@@ -34,8 +35,9 @@ int main( int /*argc*/, char** /*argv*/ )
samples = samples.reshape(1, 0);
// cluster the data
EM em_model(N, EM::COV_MAT_SPHERICAL, TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 300, 0.1));
em_model.train( samples, noArray(), labels, noArray() );
Ptr<EM> em_model = EM::train( samples, noArray(), labels, noArray(),
EM::Params(N, EM::COV_MAT_SPHERICAL,
TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 300, 0.1)));
// classify every image pixel
for( i = 0; i < img.rows; i++ )
@@ -44,7 +46,7 @@ int main( int /*argc*/, char** /*argv*/ )
{
sample.at<float>(0) = (float)j;
sample.at<float>(1) = (float)i;
int response = cvRound(em_model.predict( sample )[1]);
int response = cvRound(em_model->predict2( sample, noArray() )[1]);
Scalar c = colors[response];
circle( img, Point(j, i), 1, c*0.75, FILLED );
+5 -3
View File
@@ -37,7 +37,8 @@ int main(int, char**)
if( !cap.isOpened() )
return -1;
Mat prevgray, gray, flow, cflow, frame;
Mat flow, cflow, frame;
UMat gray, prevgray, uflow;
namedWindow("flow", 1);
for(;;)
@@ -45,10 +46,11 @@ int main(int, char**)
cap >> frame;
cvtColor(frame, gray, COLOR_BGR2GRAY);
if( prevgray.data )
if( !prevgray.empty() )
{
calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
calcOpticalFlowFarneback(prevgray, gray, uflow, 0.5, 3, 15, 3, 5, 1.2, 0);
cvtColor(prevgray, cflow, COLOR_GRAY2BGR);
uflow.copyTo(flow);
drawOptFlowMap(flow, cflow, 16, 1.5, Scalar(0, 255, 0));
imshow("flow", cflow);
}
File diff suppressed because it is too large Load Diff
-204
View File
@@ -1,204 +0,0 @@
#include "opencv2/video/tracking_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/videoio/videoio_c.h"
#include "opencv2/highgui/highgui_c.h"
#include <time.h>
#include <stdio.h>
#include <ctype.h>
static void help(void)
{
printf(
"\nThis program demonstrated the use of motion templates -- basically using the gradients\n"
"of thresholded layers of decaying frame differencing. New movements are stamped on top with floating system\n"
"time code and motions too old are thresholded away. This is the 'motion history file'. The program reads from the camera of your choice or from\n"
"a file. Gradients of motion history are used to detect direction of motoin etc\n"
"Usage :\n"
"./motempl [camera number 0-n or file name, default is camera 0]\n"
);
}
// various tracking parameters (in seconds)
const double MHI_DURATION = 1;
const double MAX_TIME_DELTA = 0.5;
const double MIN_TIME_DELTA = 0.05;
// number of cyclic frame buffer used for motion detection
// (should, probably, depend on FPS)
const int N = 4;
// ring image buffer
IplImage **buf = 0;
int last = 0;
// temporary images
IplImage *mhi = 0; // MHI
IplImage *orient = 0; // orientation
IplImage *mask = 0; // valid orientation mask
IplImage *segmask = 0; // motion segmentation map
CvMemStorage* storage = 0; // temporary storage
// parameters:
// img - input video frame
// dst - resultant motion picture
// args - optional parameters
static void update_mhi( IplImage* img, IplImage* dst, int diff_threshold )
{
double timestamp = (double)clock()/CLOCKS_PER_SEC; // get current time in seconds
CvSize size = cvSize(img->width,img->height); // get current frame size
int i, idx1 = last, idx2;
IplImage* silh;
CvSeq* seq;
CvRect comp_rect;
double count;
double angle;
CvPoint center;
double magnitude;
CvScalar color;
// allocate images at the beginning or
// reallocate them if the frame size is changed
if( !mhi || mhi->width != size.width || mhi->height != size.height ) {
if( buf == 0 ) {
buf = (IplImage**)malloc(N*sizeof(buf[0]));
memset( buf, 0, N*sizeof(buf[0]));
}
for( i = 0; i < N; i++ ) {
cvReleaseImage( &buf[i] );
buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
cvZero( buf[i] );
}
cvReleaseImage( &mhi );
cvReleaseImage( &orient );
cvReleaseImage( &segmask );
cvReleaseImage( &mask );
mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
cvZero( mhi ); // clear MHI at the beginning
orient = cvCreateImage( size, IPL_DEPTH_32F, 1 );
segmask = cvCreateImage( size, IPL_DEPTH_32F, 1 );
mask = cvCreateImage( size, IPL_DEPTH_8U, 1 );
}
cvCvtColor( img, buf[last], CV_BGR2GRAY ); // convert frame to grayscale
idx2 = (last + 1) % N; // index of (last - (N-1))th frame
last = idx2;
silh = buf[idx2];
cvAbsDiff( buf[idx1], buf[idx2], silh ); // get difference between frames
cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY ); // and threshold it
cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ); // update MHI
// convert MHI to blue 8u image
cvCvtScale( mhi, mask, 255./MHI_DURATION,
(MHI_DURATION - timestamp)*255./MHI_DURATION );
cvZero( dst );
cvMerge( mask, 0, 0, 0, dst );
// calculate motion gradient orientation and valid orientation mask
cvCalcMotionGradient( mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 );
if( !storage )
storage = cvCreateMemStorage(0);
else
cvClearMemStorage(storage);
// segment motion: get sequence of motion components
// segmask is marked motion components map. It is not used further
seq = cvSegmentMotion( mhi, segmask, storage, timestamp, MAX_TIME_DELTA );
// iterate through the motion components,
// One more iteration (i == -1) corresponds to the whole image (global motion)
for( i = -1; i < seq->total; i++ ) {
if( i < 0 ) { // case of the whole image
comp_rect = cvRect( 0, 0, size.width, size.height );
color = CV_RGB(255,255,255);
magnitude = 100;
}
else { // i-th motion component
comp_rect = ((CvConnectedComp*)cvGetSeqElem( seq, i ))->rect;
if( comp_rect.width + comp_rect.height < 100 ) // reject very small components
continue;
color = CV_RGB(255,0,0);
magnitude = 30;
}
// select component ROI
cvSetImageROI( silh, comp_rect );
cvSetImageROI( mhi, comp_rect );
cvSetImageROI( orient, comp_rect );
cvSetImageROI( mask, comp_rect );
// calculate orientation
angle = cvCalcGlobalOrientation( orient, mask, mhi, timestamp, MHI_DURATION);
angle = 360.0 - angle; // adjust for images with top-left origin
count = cvNorm( silh, 0, CV_L1, 0 ); // calculate number of points within silhouette ROI
cvResetImageROI( mhi );
cvResetImageROI( orient );
cvResetImageROI( mask );
cvResetImageROI( silh );
// check for the case of little motion
if( count < comp_rect.width*comp_rect.height * 0.05 )
continue;
// draw a clock with arrow indicating the direction
center = cvPoint( (comp_rect.x + comp_rect.width/2),
(comp_rect.y + comp_rect.height/2) );
cvCircle( dst, center, cvRound(magnitude*1.2), color, 3, CV_AA, 0 );
cvLine( dst, center, cvPoint( cvRound( center.x + magnitude*cos(angle*CV_PI/180)),
cvRound( center.y - magnitude*sin(angle*CV_PI/180))), color, 3, CV_AA, 0 );
}
}
int main(int argc, char** argv)
{
IplImage* motion = 0;
CvCapture* capture = 0;
help();
if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
else if( argc == 2 )
capture = cvCaptureFromFile( argv[1] );
if( capture )
{
cvNamedWindow( "Motion", 1 );
for(;;)
{
IplImage* image = cvQueryFrame( capture );
if( !image )
break;
if( !motion )
{
motion = cvCreateImage( cvSize(image->width,image->height), 8, 3 );
cvZero( motion );
motion->origin = image->origin;
}
update_mhi( image, motion, 30 );
cvShowImage( "Motion", motion );
if( cvWaitKey(10) >= 0 )
break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "Motion" );
}
return 0;
}
#ifdef _EiC
main(1,"motempl.c");
#endif
-322
View File
@@ -1,322 +0,0 @@
#include "opencv2/core/core_c.h"
#include "opencv2/ml/ml.hpp"
#include <stdio.h>
static void help()
{
printf("\nThis program demonstrated the use of OpenCV's decision tree function for learning and predicting data\n"
"Usage :\n"
"./mushroom <path to agaricus-lepiota.data>\n"
"\n"
"The sample demonstrates how to build a decision tree for classifying mushrooms.\n"
"It uses the sample base agaricus-lepiota.data from UCI Repository, here is the link:\n"
"\n"
"Newman, D.J. & Hettich, S. & Blake, C.L. & Merz, C.J. (1998).\n"
"UCI Repository of machine learning databases\n"
"[http://www.ics.uci.edu/~mlearn/MLRepository.html].\n"
"Irvine, CA: University of California, Department of Information and Computer Science.\n"
"\n"
"// loads the mushroom database, which is a text file, containing\n"
"// one training sample per row, all the input variables and the output variable are categorical,\n"
"// the values are encoded by characters.\n\n");
}
static int mushroom_read_database( const char* filename, CvMat** data, CvMat** missing, CvMat** responses )
{
const int M = 1024;
FILE* f = fopen( filename, "rt" );
CvMemStorage* storage;
CvSeq* seq;
char buf[M+2], *ptr;
float* el_ptr;
CvSeqReader reader;
int i, j, var_count = 0;
if( !f )
return 0;
// read the first line and determine the number of variables
if( !fgets( buf, M, f ))
{
fclose(f);
return 0;
}
for( ptr = buf; *ptr != '\0'; ptr++ )
var_count += *ptr == ',';
assert( ptr - buf == (var_count+1)*2 );
// create temporary memory storage to store the whole database
el_ptr = new float[var_count+1];
storage = cvCreateMemStorage();
seq = cvCreateSeq( 0, sizeof(*seq), (var_count+1)*sizeof(float), storage );
for(;;)
{
for( i = 0; i <= var_count; i++ )
{
int c = buf[i*2];
el_ptr[i] = c == '?' ? -1.f : (float)c;
}
if( i != var_count+1 )
break;
cvSeqPush( seq, el_ptr );
if( !fgets( buf, M, f ) || !strchr( buf, ',' ) )
break;
}
fclose(f);
// allocate the output matrices and copy the base there
*data = cvCreateMat( seq->total, var_count, CV_32F );
*missing = cvCreateMat( seq->total, var_count, CV_8U );
*responses = cvCreateMat( seq->total, 1, CV_32F );
cvStartReadSeq( seq, &reader );
for( i = 0; i < seq->total; i++ )
{
const float* sdata = (float*)reader.ptr + 1;
float* ddata = data[0]->data.fl + var_count*i;
float* dr = responses[0]->data.fl + i;
uchar* dm = missing[0]->data.ptr + var_count*i;
for( j = 0; j < var_count; j++ )
{
ddata[j] = sdata[j];
dm[j] = sdata[j] < 0;
}
*dr = sdata[-1];
CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
}
cvReleaseMemStorage( &storage );
delete [] el_ptr;
return 1;
}
static CvDTree* mushroom_create_dtree( const CvMat* data, const CvMat* missing,
const CvMat* responses, float p_weight )
{
CvDTree* dtree;
CvMat* var_type;
int i, hr1 = 0, hr2 = 0, p_total = 0;
float priors[] = { 1, p_weight };
var_type = cvCreateMat( data->cols + 1, 1, CV_8U );
cvSet( var_type, cvScalarAll(CV_VAR_CATEGORICAL) ); // all the variables are categorical
dtree = new CvDTree;
dtree->train( data, CV_ROW_SAMPLE, responses, 0, 0, var_type, missing,
CvDTreeParams( 8, // max depth
10, // min sample count
0, // regression accuracy: N/A here
true, // compute surrogate split, as we have missing data
15, // max number of categories (use sub-optimal algorithm for larger numbers)
10, // the number of cross-validation folds
true, // use 1SE rule => smaller tree
true, // throw away the pruned tree branches
priors // the array of priors, the bigger p_weight, the more attention
// to the poisonous mushrooms
// (a mushroom will be judjed to be poisonous with bigger chance)
));
// compute hit-rate on the training database, demonstrates predict usage.
for( i = 0; i < data->rows; i++ )
{
CvMat sample, mask;
cvGetRow( data, &sample, i );
cvGetRow( missing, &mask, i );
double r = dtree->predict( &sample, &mask )->value;
int d = fabs(r - responses->data.fl[i]) >= FLT_EPSILON;
if( d )
{
if( r != 'p' )
hr1++;
else
hr2++;
}
p_total += responses->data.fl[i] == 'p';
}
printf( "Results on the training database:\n"
"\tPoisonous mushrooms mis-predicted: %d (%g%%)\n"
"\tFalse-alarms: %d (%g%%)\n", hr1, (double)hr1*100/p_total,
hr2, (double)hr2*100/(data->rows - p_total) );
cvReleaseMat( &var_type );
return dtree;
}
static const char* var_desc[] =
{
"cap shape (bell=b,conical=c,convex=x,flat=f)",
"cap surface (fibrous=f,grooves=g,scaly=y,smooth=s)",
"cap color (brown=n,buff=b,cinnamon=c,gray=g,green=r,\n\tpink=p,purple=u,red=e,white=w,yellow=y)",
"bruises? (bruises=t,no=f)",
"odor (almond=a,anise=l,creosote=c,fishy=y,foul=f,\n\tmusty=m,none=n,pungent=p,spicy=s)",
"gill attachment (attached=a,descending=d,free=f,notched=n)",
"gill spacing (close=c,crowded=w,distant=d)",
"gill size (broad=b,narrow=n)",
"gill color (black=k,brown=n,buff=b,chocolate=h,gray=g,\n\tgreen=r,orange=o,pink=p,purple=u,red=e,white=w,yellow=y)",
"stalk shape (enlarging=e,tapering=t)",
"stalk root (bulbous=b,club=c,cup=u,equal=e,rhizomorphs=z,rooted=r)",
"stalk surface above ring (ibrous=f,scaly=y,silky=k,smooth=s)",
"stalk surface below ring (ibrous=f,scaly=y,silky=k,smooth=s)",
"stalk color above ring (brown=n,buff=b,cinnamon=c,gray=g,orange=o,\n\tpink=p,red=e,white=w,yellow=y)",
"stalk color below ring (brown=n,buff=b,cinnamon=c,gray=g,orange=o,\n\tpink=p,red=e,white=w,yellow=y)",
"veil type (partial=p,universal=u)",
"veil color (brown=n,orange=o,white=w,yellow=y)",
"ring number (none=n,one=o,two=t)",
"ring type (cobwebby=c,evanescent=e,flaring=f,large=l,\n\tnone=n,pendant=p,sheathing=s,zone=z)",
"spore print color (black=k,brown=n,buff=b,chocolate=h,green=r,\n\torange=o,purple=u,white=w,yellow=y)",
"population (abundant=a,clustered=c,numerous=n,\n\tscattered=s,several=v,solitary=y)",
"habitat (grasses=g,leaves=l,meadows=m,paths=p\n\turban=u,waste=w,woods=d)",
0
};
static void print_variable_importance( CvDTree* dtree )
{
const CvMat* var_importance = dtree->get_var_importance();
int i;
char input[1000];
if( !var_importance )
{
printf( "Error: Variable importance can not be retrieved\n" );
return;
}
printf( "Print variable importance information? (y/n) " );
int values_read = scanf( "%1s", input );
CV_Assert(values_read == 1);
if( input[0] != 'y' && input[0] != 'Y' )
return;
for( i = 0; i < var_importance->cols*var_importance->rows; i++ )
{
double val = var_importance->data.db[i];
char buf[100];
int len = (int)(strchr( var_desc[i], '(' ) - var_desc[i] - 1);
strncpy( buf, var_desc[i], len );
buf[len] = '\0';
printf( "%s", buf );
printf( ": %g%%\n", val*100. );
}
}
static void interactive_classification( CvDTree* dtree )
{
char input[1000];
const CvDTreeNode* root;
CvDTreeTrainData* data;
if( !dtree )
return;
root = dtree->get_root();
data = dtree->get_data();
for(;;)
{
const CvDTreeNode* node;
printf( "Start/Proceed with interactive mushroom classification (y/n): " );
int values_read = scanf( "%1s", input );
CV_Assert(values_read == 1);
if( input[0] != 'y' && input[0] != 'Y' )
break;
printf( "Enter 1-letter answers, '?' for missing/unknown value...\n" );
// custom version of predict
node = root;
for(;;)
{
CvDTreeSplit* split = node->split;
int dir = 0;
if( !node->left || node->Tn <= dtree->get_pruned_tree_idx() || !node->split )
break;
for( ; split != 0; )
{
int vi = split->var_idx, j;
int count = data->cat_count->data.i[vi];
const int* map = data->cat_map->data.i + data->cat_ofs->data.i[vi];
printf( "%s: ", var_desc[vi] );
values_read = scanf( "%1s", input );
CV_Assert(values_read == 1);
if( input[0] == '?' )
{
split = split->next;
continue;
}
// convert the input character to the normalized value of the variable
for( j = 0; j < count; j++ )
if( map[j] == input[0] )
break;
if( j < count )
{
dir = (split->subset[j>>5] & (1 << (j&31))) ? -1 : 1;
if( split->inversed )
dir = -dir;
break;
}
else
printf( "Error: unrecognized value\n" );
}
if( !dir )
{
printf( "Impossible to classify the sample\n");
node = 0;
break;
}
node = dir < 0 ? node->left : node->right;
}
if( node )
printf( "Prediction result: the mushroom is %s\n",
node->class_idx == 0 ? "EDIBLE" : "POISONOUS" );
printf( "\n-----------------------------\n" );
}
}
int main( int argc, char** argv )
{
CvMat *data = 0, *missing = 0, *responses = 0;
CvDTree* dtree;
const char* base_path = argc >= 2 ? argv[1] : "agaricus-lepiota.data";
help();
if( !mushroom_read_database( base_path, &data, &missing, &responses ) )
{
printf( "\nUnable to load the training database\n\n");
help();
return -1;
}
dtree = mushroom_create_dtree( data, missing, responses,
10 // poisonous mushrooms will have 10x higher weight in the decision tree
);
cvReleaseMat( &data );
cvReleaseMat( &missing );
cvReleaseMat( &responses );
print_variable_importance( dtree );
interactive_classification( dtree );
delete dtree;
return 0;
}
+137 -378
View File
@@ -12,6 +12,7 @@
using namespace std;
using namespace cv;
using namespace cv::ml;
const Scalar WHITE_COLOR = Scalar(255,255,255);
const string winName = "points";
@@ -22,18 +23,20 @@ RNG rng;
vector<Point> trainedPoints;
vector<int> trainedPointsMarkers;
vector<Scalar> classColors;
const int MAX_CLASSES = 2;
vector<Vec3b> classColors(MAX_CLASSES);
int currentClass = 0;
vector<int> classCounters(MAX_CLASSES);
#define _NBC_ 0 // normal Bayessian classifier
#define _KNN_ 0 // k nearest neighbors classifier
#define _SVM_ 0 // support vectors machine
#define _NBC_ 1 // normal Bayessian classifier
#define _KNN_ 1 // k nearest neighbors classifier
#define _SVM_ 1 // support vectors machine
#define _DT_ 1 // decision tree
#define _BT_ 0 // ADA Boost
#define _BT_ 1 // ADA Boost
#define _GBT_ 0 // gradient boosted trees
#define _RF_ 0 // random forest
#define _ERT_ 0 // extremely randomized trees
#define _ANN_ 0 // artificial neural networks
#define _EM_ 0 // expectation-maximization
#define _RF_ 1 // random forest
#define _ANN_ 1 // artificial neural networks
#define _EM_ 1 // expectation-maximization
static void on_mouse( int event, int x, int y, int /*flags*/, void* )
{
@@ -44,76 +47,43 @@ static void on_mouse( int event, int x, int y, int /*flags*/, void* )
if( event == EVENT_LBUTTONUP )
{
if( classColors.empty() )
return;
trainedPoints.push_back( Point(x,y) );
trainedPointsMarkers.push_back( (int)(classColors.size()-1) );
trainedPointsMarkers.push_back( currentClass );
classCounters[currentClass]++;
updateFlag = true;
}
else if( event == EVENT_RBUTTONUP )
{
#if _BT_
if( classColors.size() < 2 )
{
#endif
classColors.push_back( Scalar((uchar)rng(256), (uchar)rng(256), (uchar)rng(256)) );
updateFlag = true;
#if _BT_
}
else
cout << "New class can not be added, because CvBoost can only be used for 2-class classification" << endl;
#endif
}
//draw
if( updateFlag )
{
img = Scalar::all(0);
// put the text
stringstream text;
text << "current class " << classColors.size()-1;
putText( img, text.str(), Point(10,25), FONT_HERSHEY_SIMPLEX, 0.8f, WHITE_COLOR, 2 );
text.str("");
text << "total classes " << classColors.size();
putText( img, text.str(), Point(10,50), FONT_HERSHEY_SIMPLEX, 0.8f, WHITE_COLOR, 2 );
text.str("");
text << "total points " << trainedPoints.size();
putText(img, text.str(), Point(10,75), FONT_HERSHEY_SIMPLEX, 0.8f, WHITE_COLOR, 2 );
// draw points
for( size_t i = 0; i < trainedPoints.size(); i++ )
circle( img, trainedPoints[i], 5, classColors[trainedPointsMarkers[i]], -1 );
{
Vec3b c = classColors[trainedPointsMarkers[i]];
circle( img, trainedPoints[i], 5, Scalar(c), -1 );
}
imshow( winName, img );
}
}
static void prepare_train_data( Mat& samples, Mat& classes )
static Mat prepare_train_samples(const vector<Point>& pts)
{
Mat( trainedPoints ).copyTo( samples );
Mat( trainedPointsMarkers ).copyTo( classes );
// reshape trainData and change its type
samples = samples.reshape( 1, samples.rows );
samples.convertTo( samples, CV_32FC1 );
Mat samples;
Mat(pts).reshape(1, (int)pts.size()).convertTo(samples, CV_32F);
return samples;
}
#if _NBC_
static void find_decision_boundary_NBC()
static Ptr<TrainData> prepare_train_data()
{
img.copyTo( imgDst );
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
CvNormalBayesClassifier normalBayesClassifier( trainSamples, trainClasses );
Mat samples = prepare_train_samples(trainedPoints);
return TrainData::create(samples, ROW_SAMPLE, Mat(trainedPointsMarkers));
}
static void predict_and_paint(const Ptr<StatModel>& model, Mat& dst)
{
Mat testSample( 1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
@@ -122,378 +92,171 @@ static void find_decision_boundary_NBC()
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)normalBayesClassifier.predict( testSample );
circle( imgDst, Point(x,y), 1, classColors[response] );
int response = (int)model->predict( testSample );
dst.at<Vec3b>(y, x) = classColors[response];
}
}
}
#if _NBC_
static void find_decision_boundary_NBC()
{
// learn classifier
Ptr<NormalBayesClassifier> normalBayesClassifier = StatModel::train<NormalBayesClassifier>(prepare_train_data(), NormalBayesClassifier::Params());
predict_and_paint(normalBayesClassifier, imgDst);
}
#endif
#if _KNN_
static void find_decision_boundary_KNN( int K )
{
img.copyTo( imgDst );
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
#if defined HAVE_OPENCV_OCL && _OCL_KNN_
cv::ocl::KNearestNeighbour knnClassifier;
Mat temp, result;
knnClassifier.train(trainSamples, trainClasses, temp, false, K);
cv::ocl::oclMat testSample_ocl, reslut_ocl;
#else
CvKNearest knnClassifier( trainSamples, trainClasses, Mat(), false, K );
#endif
Mat testSample( 1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
#if defined HAVE_OPENCV_OCL && _OCL_KNN_
testSample_ocl.upload(testSample);
knnClassifier.find_nearest(testSample_ocl, K, reslut_ocl);
reslut_ocl.download(result);
int response = saturate_cast<int>(result.at<float>(0));
circle(imgDst, Point(x, y), 1, classColors[response]);
#else
int response = (int)knnClassifier.find_nearest( testSample, K );
circle( imgDst, Point(x,y), 1, classColors[response] );
#endif
}
}
Ptr<KNearest> knn = StatModel::train<KNearest>(prepare_train_data(), KNearest::Params(K, true));
predict_and_paint(knn, imgDst);
}
#endif
#if _SVM_
static void find_decision_boundary_SVM( CvSVMParams params )
static void find_decision_boundary_SVM( SVM::Params params )
{
img.copyTo( imgDst );
Ptr<SVM> svm = StatModel::train<SVM>(prepare_train_data(), params);
predict_and_paint(svm, imgDst);
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
#if defined HAVE_OPENCV_OCL && _OCL_SVM_
cv::ocl::CvSVM_OCL svmClassifier(trainSamples, trainClasses, Mat(), Mat(), params);
#else
CvSVM svmClassifier( trainSamples, trainClasses, Mat(), Mat(), params );
#endif
Mat testSample( 1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
Mat sv = svm->getSupportVectors();
for( int i = 0; i < sv.rows; i++ )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)svmClassifier.predict( testSample );
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
const float* supportVector = sv.ptr<float>(i);
circle( imgDst, Point(saturate_cast<int>(supportVector[0]),saturate_cast<int>(supportVector[1])), 5, Scalar(255,255,255), -1 );
}
for( int i = 0; i < svmClassifier.get_support_vector_count(); i++ )
{
const float* supportVector = svmClassifier.get_support_vector(i);
circle( imgDst, Point(saturate_cast<int>(supportVector[0]),saturate_cast<int>(supportVector[1])), 5, CV_RGB(255,255,255), -1 );
}
}
#endif
#if _DT_
static void find_decision_boundary_DT()
{
img.copyTo( imgDst );
DTrees::Params params;
params.maxDepth = 8;
params.minSampleCount = 2;
params.useSurrogates = false;
params.CVFolds = 0; // the number of cross-validation folds
params.use1SERule = false;
params.truncatePrunedTree = false;
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
Ptr<DTrees> dtree = StatModel::train<DTrees>(prepare_train_data(), params);
// learn classifier
CvDTree dtree;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvDTreeParams params;
params.max_depth = 8;
params.min_sample_count = 2;
params.use_surrogates = false;
params.cv_folds = 0; // the number of cross-validation folds
params.use_1se_rule = false;
params.truncate_pruned_tree = false;
dtree.train( trainSamples, CV_ROW_SAMPLE, trainClasses,
Mat(), Mat(), var_types, Mat(), params );
Mat testSample(1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)dtree.predict( testSample )->value;
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
}
predict_and_paint(dtree, imgDst);
}
#endif
#if _BT_
void find_decision_boundary_BT()
static void find_decision_boundary_BT()
{
img.copyTo( imgDst );
Boost::Params params( Boost::DISCRETE, // boost_type
100, // weak_count
0.95, // weight_trim_rate
2, // max_depth
false, //use_surrogates
Mat() // priors
);
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
CvBoost boost;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvBoostParams params( CvBoost::DISCRETE, // boost_type
100, // weak_count
0.95, // weight_trim_rate
2, // max_depth
false, //use_surrogates
0 // priors
);
boost.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), var_types, Mat(), params );
Mat testSample(1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)boost.predict( testSample );
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
}
Ptr<Boost> boost = StatModel::train<Boost>(prepare_train_data(), params);
predict_and_paint(boost, imgDst);
}
#endif
#if _GBT_
void find_decision_boundary_GBT()
static void find_decision_boundary_GBT()
{
img.copyTo( imgDst );
GBTrees::Params params( GBTrees::DEVIANCE_LOSS, // loss_function_type
100, // weak_count
0.1f, // shrinkage
1.0f, // subsample_portion
2, // max_depth
false // use_surrogates )
);
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
CvGBTrees gbtrees;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvGBTreesParams params( CvGBTrees::DEVIANCE_LOSS, // loss_function_type
100, // weak_count
0.1f, // shrinkage
1.0f, // subsample_portion
2, // max_depth
false // use_surrogates )
);
gbtrees.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), var_types, Mat(), params );
Mat testSample(1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)gbtrees.predict( testSample );
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
}
Ptr<GBTrees> gbtrees = StatModel::train<GBTrees>(prepare_train_data(), params);
predict_and_paint(gbtrees, imgDst);
}
#endif
#if _RF_
void find_decision_boundary_RF()
static void find_decision_boundary_RF()
{
img.copyTo( imgDst );
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
CvRTrees rtrees;
CvRTParams params( 4, // max_depth,
RTrees::Params params( 4, // max_depth,
2, // min_sample_count,
0.f, // regression_accuracy,
false, // use_surrogates,
16, // max_categories,
0, // priors,
Mat(), // priors,
false, // calc_var_importance,
1, // nactive_vars,
5, // max_num_of_trees_in_the_forest,
0, // forest_accuracy,
CV_TERMCRIT_ITER // termcrit_type
TermCriteria(TermCriteria::MAX_ITER, 5, 0) // max_num_of_trees_in_the_forest,
);
rtrees.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), Mat(), Mat(), params );
Mat testSample(1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)rtrees.predict( testSample );
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
}
Ptr<RTrees> rtrees = StatModel::train<RTrees>(prepare_train_data(), params);
predict_and_paint(rtrees, imgDst);
}
#endif
#if _ERT_
void find_decision_boundary_ERT()
{
img.copyTo( imgDst );
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// learn classifier
CvERTrees ertrees;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvRTParams params( 4, // max_depth,
2, // min_sample_count,
0.f, // regression_accuracy,
false, // use_surrogates,
16, // max_categories,
0, // priors,
false, // calc_var_importance,
1, // nactive_vars,
5, // max_num_of_trees_in_the_forest,
0, // forest_accuracy,
CV_TERMCRIT_ITER // termcrit_type
);
ertrees.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), var_types, Mat(), params );
Mat testSample(1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
int response = (int)ertrees.predict( testSample );
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
}
}
}
#endif
#if _ANN_
void find_decision_boundary_ANN( const Mat& layer_sizes )
static void find_decision_boundary_ANN( const Mat& layer_sizes )
{
img.copyTo( imgDst );
ANN_MLP::Params params(layer_sizes, ANN_MLP::SIGMOID_SYM, 1, 1, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 300, FLT_EPSILON),
ANN_MLP::Params::BACKPROP, 0.001);
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
// prerare trainClasses
trainClasses.create( trainedPoints.size(), classColors.size(), CV_32FC1 );
for( int i = 0; i < trainClasses.rows; i++ )
Mat trainClasses = Mat::zeros( (int)trainedPoints.size(), (int)classColors.size(), CV_32FC1 );
for( int i = 0; i < trainClasses.rows; i++ )
{
for( int k = 0; k < trainClasses.cols; k++ )
{
if( k == trainedPointsMarkers[i] )
trainClasses.at<float>(i,k) = 1;
else
trainClasses.at<float>(i,k) = 0;
}
trainClasses.at<float>(i, trainedPointsMarkers[i]) = 1.f;
}
Mat weights( 1, trainedPoints.size(), CV_32FC1, Scalar::all(1) );
Mat samples = prepare_train_samples(trainedPoints);
Ptr<TrainData> tdata = TrainData::create(samples, ROW_SAMPLE, trainClasses);
// learn classifier
CvANN_MLP ann( layer_sizes, CvANN_MLP::SIGMOID_SYM, 1, 1 );
ann.train( trainSamples, trainClasses, weights );
Mat testSample( 1, 2, CV_32FC1 );
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
{
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
Mat outputs( 1, classColors.size(), CV_32FC1, testSample.data );
ann.predict( testSample, outputs );
Point maxLoc;
minMaxLoc( outputs, 0, 0, 0, &maxLoc );
circle( imgDst, Point(x,y), 2, classColors[maxLoc.x], 1 );
}
}
Ptr<ANN_MLP> ann = StatModel::train<ANN_MLP>(tdata, params);
predict_and_paint(ann, imgDst);
}
#endif
#if _EM_
void find_decision_boundary_EM()
static void find_decision_boundary_EM()
{
img.copyTo( imgDst );
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
Mat samples = prepare_train_samples(trainedPoints);
vector<cv::EM> em_models(classColors.size());
int i, j, nmodels = (int)classColors.size();
vector<Ptr<EM> > em_models(nmodels);
Mat modelSamples;
CV_Assert((int)trainClasses.total() == trainSamples.rows);
CV_Assert((int)trainClasses.type() == CV_32SC1);
for(size_t modelIndex = 0; modelIndex < em_models.size(); modelIndex++)
for( i = 0; i < nmodels; i++ )
{
const int componentCount = 3;
em_models[modelIndex] = EM(componentCount, cv::EM::COV_MAT_DIAGONAL);
Mat modelSamples;
for(int sampleIndex = 0; sampleIndex < trainSamples.rows; sampleIndex++)
modelSamples.release();
for( j = 0; j < samples.rows; j++ )
{
if(trainClasses.at<int>(sampleIndex) == (int)modelIndex)
modelSamples.push_back(trainSamples.row(sampleIndex));
if( trainedPointsMarkers[j] == i )
modelSamples.push_back(samples.row(j));
}
// learn models
if(!modelSamples.empty())
em_models[modelIndex].train(modelSamples);
if( !modelSamples.empty() )
{
em_models[i] = EM::train(modelSamples, noArray(), noArray(), noArray(),
EM::Params(componentCount, EM::COV_MAT_DIAGONAL));
}
}
// classify coordinate plane points using the bayes classifier, i.e.
// y(x) = arg max_i=1_modelsCount likelihoods_i(x)
Mat testSample(1, 2, CV_32FC1 );
Mat logLikelihoods(1, nmodels, CV_64FC1, Scalar(-DBL_MAX));
for( int y = 0; y < img.rows; y += testStep )
{
for( int x = 0; x < img.cols; x += testStep )
@@ -501,17 +264,14 @@ void find_decision_boundary_EM()
testSample.at<float>(0) = (float)x;
testSample.at<float>(1) = (float)y;
Mat logLikelihoods(1, em_models.size(), CV_64FC1, Scalar(-DBL_MAX));
for(size_t modelIndex = 0; modelIndex < em_models.size(); modelIndex++)
for( i = 0; i < nmodels; i++ )
{
if(em_models[modelIndex].isTrained())
logLikelihoods.at<double>(modelIndex) = em_models[modelIndex].predict(testSample)[0];
if( !em_models[i].empty() )
logLikelihoods.at<double>(i) = em_models[i]->predict2(testSample, noArray())[0];
}
Point maxLoc;
minMaxLoc(logLikelihoods, 0, 0, 0, &maxLoc);
int response = maxLoc.x;
circle( imgDst, Point(x,y), 2, classColors[response], 1 );
imgDst.at<Vec3b>(y, x) = classColors[maxLoc.x];
}
}
}
@@ -520,7 +280,7 @@ void find_decision_boundary_EM()
int main()
{
cout << "Use:" << endl
<< " right mouse button - to add new class;" << endl
<< " key '0' .. '1' - switch to class #n" << endl
<< " left mouse button - to add new point;" << endl
<< " key 'r' - to run the ML model;" << endl
<< " key 'i' - to init (clear) the data." << endl << endl;
@@ -532,6 +292,9 @@ int main()
imshow( "points", img );
setMouseCallback( "points", on_mouse );
classColors[0] = Vec3b(0, 255, 0);
classColors[1] = Vec3b(0, 0, 255);
for(;;)
{
uchar key = (uchar)waitKey();
@@ -542,98 +305,94 @@ int main()
{
img = Scalar::all(0);
classColors.clear();
trainedPoints.clear();
trainedPointsMarkers.clear();
classCounters.assign(MAX_CLASSES, 0);
imshow( winName, img );
}
if( key == '0' || key == '1' )
{
currentClass = key - '0';
}
if( key == 'r' ) // run
{
double minVal = 0;
minMaxLoc(classCounters, &minVal, 0, 0, 0);
if( minVal == 0 )
{
printf("each class should have at least 1 point\n");
continue;
}
img.copyTo( imgDst );
#if _NBC_
find_decision_boundary_NBC();
namedWindow( "NormalBayesClassifier", WINDOW_AUTOSIZE );
imshow( "NormalBayesClassifier", imgDst );
#endif
#if _KNN_
int K = 3;
find_decision_boundary_KNN( K );
namedWindow( "kNN", WINDOW_AUTOSIZE );
imshow( "kNN", imgDst );
K = 15;
find_decision_boundary_KNN( K );
namedWindow( "kNN2", WINDOW_AUTOSIZE );
imshow( "kNN2", imgDst );
#endif
#if _SVM_
//(1)-(2)separable and not sets
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::POLY; //CvSVM::LINEAR;
SVM::Params params;
params.svmType = SVM::C_SVC;
params.kernelType = SVM::POLY; //CvSVM::LINEAR;
params.degree = 0.5;
params.gamma = 1;
params.coef0 = 1;
params.C = 1;
params.nu = 0.5;
params.p = 0;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
params.termCrit = TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 1000, 0.01);
find_decision_boundary_SVM( params );
namedWindow( "classificationSVM1", WINDOW_AUTOSIZE );
imshow( "classificationSVM1", imgDst );
params.C = 10;
find_decision_boundary_SVM( params );
namedWindow( "classificationSVM2", WINDOW_AUTOSIZE );
imshow( "classificationSVM2", imgDst );
#endif
#if _DT_
find_decision_boundary_DT();
namedWindow( "DT", WINDOW_AUTOSIZE );
imshow( "DT", imgDst );
#endif
#if _BT_
find_decision_boundary_BT();
namedWindow( "BT", WINDOW_AUTOSIZE );
imshow( "BT", imgDst);
#endif
#if _GBT_
find_decision_boundary_GBT();
namedWindow( "GBT", WINDOW_AUTOSIZE );
imshow( "GBT", imgDst);
#endif
#if _RF_
find_decision_boundary_RF();
namedWindow( "RF", WINDOW_AUTOSIZE );
imshow( "RF", imgDst);
#endif
#if _ERT_
find_decision_boundary_ERT();
namedWindow( "ERT", WINDOW_AUTOSIZE );
imshow( "ERT", imgDst);
#endif
#if _ANN_
Mat layer_sizes1( 1, 3, CV_32SC1 );
layer_sizes1.at<int>(0) = 2;
layer_sizes1.at<int>(1) = 5;
layer_sizes1.at<int>(2) = classColors.size();
layer_sizes1.at<int>(2) = (int)classColors.size();
find_decision_boundary_ANN( layer_sizes1 );
namedWindow( "ANN", WINDOW_AUTOSIZE );
imshow( "ANN", imgDst );
#endif
#if _EM_
find_decision_boundary_EM();
namedWindow( "EM", WINDOW_AUTOSIZE );
imshow( "EM", imgDst );
#endif
}
+2 -2
View File
@@ -88,8 +88,8 @@ int main(int argc, char** argv)
namedWindow("video", 1);
namedWindow("segmented", 1);
Ptr<BackgroundSubtractorMOG> bgsubtractor=createBackgroundSubtractorMOG();
bgsubtractor->setNoiseSigma(10);
Ptr<BackgroundSubtractorMOG2> bgsubtractor=createBackgroundSubtractorMOG2();
bgsubtractor->setVarThreshold(10);
for(;;)
{
-221
View File
@@ -1,221 +0,0 @@
#include <opencv2/core/utility.hpp>
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <cstdio>
#include <iostream>
using namespace cv;
using namespace std;
#define APP_NAME "simpleflow_demo : "
static void help()
{
// print a welcome message, and the OpenCV version
printf("This is a demo of SimpleFlow optical flow algorithm,\n"
"Using OpenCV version %s\n\n", CV_VERSION);
printf("Usage: simpleflow_demo frame1 frame2 output_flow"
"\nApplication will write estimated flow "
"\nbetween 'frame1' and 'frame2' in binary format"
"\ninto file 'output_flow'"
"\nThen one can use code from http://vision.middlebury.edu/flow/data/"
"\nto convert flow in binary file to image\n");
}
// binary file format for flow data specified here:
// http://vision.middlebury.edu/flow/data/
static void writeOpticalFlowToFile(const Mat& flow, FILE* file) {
int cols = flow.cols;
int rows = flow.rows;
fprintf(file, "PIEH");
if (fwrite(&cols, sizeof(int), 1, file) != 1 ||
fwrite(&rows, sizeof(int), 1, file) != 1) {
printf(APP_NAME "writeOpticalFlowToFile : problem writing header\n");
exit(1);
}
for (int i= 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
Vec2f flow_at_point = flow.at<Vec2f>(i, j);
if (fwrite(&(flow_at_point[0]), sizeof(float), 1, file) != 1 ||
fwrite(&(flow_at_point[1]), sizeof(float), 1, file) != 1) {
printf(APP_NAME "writeOpticalFlowToFile : problem writing data\n");
exit(1);
}
}
}
}
static void run(int argc, char** argv) {
if (argc < 3) {
printf(APP_NAME "Wrong number of command line arguments for mode `run`: %d (expected %d)\n",
argc, 3);
exit(1);
}
Mat frame1 = imread(argv[0]);
Mat frame2 = imread(argv[1]);
if (frame1.empty()) {
printf(APP_NAME "Image #1 : %s cannot be read\n", argv[0]);
exit(1);
}
if (frame2.empty()) {
printf(APP_NAME "Image #2 : %s cannot be read\n", argv[1]);
exit(1);
}
if (frame1.rows != frame2.rows && frame1.cols != frame2.cols) {
printf(APP_NAME "Images should be of equal sizes\n");
exit(1);
}
if (frame1.type() != 16 || frame2.type() != 16) {
printf(APP_NAME "Images should be of equal type CV_8UC3\n");
exit(1);
}
printf(APP_NAME "Read two images of size [rows = %d, cols = %d]\n",
frame1.rows, frame1.cols);
Mat flow;
float start = (float)getTickCount();
calcOpticalFlowSF(frame1, frame2,
flow,
3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);
printf(APP_NAME "calcOpticalFlowSF : %lf sec\n", (getTickCount() - start) / getTickFrequency());
FILE* file = fopen(argv[2], "wb");
if (file == NULL) {
printf(APP_NAME "Unable to open file '%s' for writing\n", argv[2]);
exit(1);
}
printf(APP_NAME "Writing to file\n");
writeOpticalFlowToFile(flow, file);
fclose(file);
}
static bool readOpticalFlowFromFile(FILE* file, Mat& flow) {
char header[5];
if (fread(header, 1, 4, file) < 4 && (string)header != "PIEH") {
return false;
}
int cols, rows;
if (fread(&cols, sizeof(int), 1, file) != 1||
fread(&rows, sizeof(int), 1, file) != 1) {
return false;
}
flow = Mat::zeros(rows, cols, CV_32FC2);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
Vec2f flow_at_point;
if (fread(&(flow_at_point[0]), sizeof(float), 1, file) != 1 ||
fread(&(flow_at_point[1]), sizeof(float), 1, file) != 1) {
return false;
}
flow.at<Vec2f>(i, j) = flow_at_point;
}
}
return true;
}
static bool isFlowCorrect(float u) {
return !cvIsNaN(u) && (fabs(u) < 1e9);
}
static float calc_rmse(Mat flow1, Mat flow2) {
float sum = 0;
int counter = 0;
const int rows = flow1.rows;
const int cols = flow1.cols;
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < cols; ++x) {
Vec2f flow1_at_point = flow1.at<Vec2f>(y, x);
Vec2f flow2_at_point = flow2.at<Vec2f>(y, x);
float u1 = flow1_at_point[0];
float v1 = flow1_at_point[1];
float u2 = flow2_at_point[0];
float v2 = flow2_at_point[1];
if (isFlowCorrect(u1) && isFlowCorrect(u2) && isFlowCorrect(v1) && isFlowCorrect(v2)) {
sum += (u1-u2)*(u1-u2) + (v1-v2)*(v1-v2);
counter++;
}
}
}
return (float)sqrt(sum / (1e-9 + counter));
}
static void eval(int argc, char** argv) {
if (argc < 2) {
printf(APP_NAME "Wrong number of command line arguments for mode `eval` : %d (expected %d)\n",
argc, 2);
exit(1);
}
Mat flow1, flow2;
FILE* flow_file_1 = fopen(argv[0], "rb");
if (flow_file_1 == NULL) {
printf(APP_NAME "Cannot open file with first flow : %s\n", argv[0]);
exit(1);
}
if (!readOpticalFlowFromFile(flow_file_1, flow1)) {
printf(APP_NAME "Cannot read flow data from file %s\n", argv[0]);
exit(1);
}
fclose(flow_file_1);
FILE* flow_file_2 = fopen(argv[1], "rb");
if (flow_file_2 == NULL) {
printf(APP_NAME "Cannot open file with first flow : %s\n", argv[1]);
exit(1);
}
if (!readOpticalFlowFromFile(flow_file_2, flow2)) {
printf(APP_NAME "Cannot read flow data from file %s\n", argv[1]);
exit(1);
}
fclose(flow_file_2);
float rmse = calc_rmse(flow1, flow2);
printf("%lf\n", rmse);
}
int main(int argc, char** argv) {
if (argc < 2) {
printf(APP_NAME "Mode is not specified\n");
help();
exit(1);
}
string mode = (string)argv[1];
int new_argc = argc - 2;
char** new_argv = &argv[2];
if ("run" == mode) {
run(new_argc, new_argv);
} else if ("eval" == mode) {
eval(new_argc, new_argv);
} else if ("help" == mode)
help();
else {
printf(APP_NAME "Unknown mode : %s\n", argv[1]);
help();
}
return 0;
}
+26 -52
View File
@@ -8,9 +8,10 @@
#include <time.h>
using namespace cv;
using namespace cv::ml;
using namespace std;
void get_svm_detector(const SVM& svm, vector< float > & hog_detector );
void get_svm_detector(const Ptr<SVM>& svm, vector< float > & hog_detector );
void convert_to_ml(const std::vector< cv::Mat > & train_samples, cv::Mat& trainData );
void load_images( const string & prefix, const string & filename, vector< Mat > & img_lst );
void sample_neg( const vector< Mat > & full_neg_lst, vector< Mat > & neg_lst, const Size & size );
@@ -20,49 +21,24 @@ void train_svm( const vector< Mat > & gradient_lst, const vector< int > & labels
void draw_locations( Mat & img, const vector< Rect > & locations, const Scalar & color );
void test_it( const Size & size );
void get_svm_detector(const SVM& svm, vector< float > & hog_detector )
void get_svm_detector(const Ptr<SVM>& svm, vector< float > & hog_detector )
{
// get the number of variables
const int var_all = svm.get_var_count();
// get the number of support vectors
const int sv_total = svm.get_support_vector_count();
// get the decision function
const CvSVMDecisionFunc* decision_func = svm.get_decision_function();
// get the support vectors
const float** sv = new const float*[ sv_total ];
for( int i = 0 ; i < sv_total ; ++i )
sv[ i ] = svm.get_support_vector(i);
Mat sv = svm->getSupportVectors();
const int sv_total = sv.rows;
// get the decision function
Mat alpha, svidx;
double rho = svm->getDecisionFunction(0, alpha, svidx);
CV_Assert( var_all > 0 &&
sv_total > 0 &&
decision_func != 0 &&
decision_func->alpha != 0 &&
decision_func->sv_count == sv_total );
CV_Assert( alpha.total() == 1 && svidx.total() == 1 && sv_total == 1 );
CV_Assert( (alpha.type() == CV_64F && alpha.at<double>(0) == 1.) ||
(alpha.type() == CV_32F && alpha.at<float>(0) == 1.f) );
CV_Assert( sv.type() == CV_32F );
hog_detector.clear();
float svi = 0.f;
hog_detector.clear(); //clear stuff in vector.
hog_detector.reserve( var_all + 1 ); //reserve place for memory efficiency.
/**
* hog_detector^i = \sum_j support_vector_j^i * \alpha_j
* hog_detector^dim = -\rho
*/
for( int i = 0 ; i < var_all ; ++i )
{
svi = 0.f;
for( int j = 0 ; j < sv_total ; ++j )
{
if( decision_func->sv_index != NULL ) // sometime the sv_index isn't store on YML/XML.
svi += (float)( sv[decision_func->sv_index[j]][i] * decision_func->alpha[ j ] );
else
svi += (float)( sv[j][i] * decision_func->alpha[ j ] );
}
hog_detector.push_back( svi );
}
hog_detector.push_back( (float)-decision_func->rho );
delete[] sv;
hog_detector.resize(sv.cols + 1);
memcpy(&hog_detector[0], sv.data, sv.cols*sizeof(hog_detector[0]));
hog_detector[sv.cols] = (float)-rho;
}
@@ -263,7 +239,7 @@ Mat get_hogdescriptor_visu(const Mat& color_origImg, vector<float>& descriptorVa
int mx = drawX + cellSize/2;
int my = drawY + cellSize/2;
rectangle(visu, Point((int)(drawX*zoomFac), (int)(drawY*zoomFac)), Point((int)((drawX+cellSize)*zoomFac), (int)((drawY+cellSize)*zoomFac)), CV_RGB(100,100,100), 1);
rectangle(visu, Point((int)(drawX*zoomFac), (int)(drawY*zoomFac)), Point((int)((drawX+cellSize)*zoomFac), (int)((drawY+cellSize)*zoomFac)), Scalar(100,100,100), 1);
// draw in each cell all 9 gradient strengths
for (int bin=0; bin<gradientBinSize; bin++)
@@ -288,7 +264,7 @@ Mat get_hogdescriptor_visu(const Mat& color_origImg, vector<float>& descriptorVa
float y2 = my + dirVecY * currentGradStrength * maxVecLen * scale;
// draw gradient visualization
line(visu, Point((int)(x1*zoomFac),(int)(y1*zoomFac)), Point((int)(x2*zoomFac),(int)(y2*zoomFac)), CV_RGB(0,255,0), 1);
line(visu, Point((int)(x1*zoomFac),(int)(y1*zoomFac)), Point((int)(x2*zoomFac),(int)(y2*zoomFac)), Scalar(0,255,0), 1);
} // for (all bins)
@@ -337,28 +313,26 @@ void compute_hog( const vector< Mat > & img_lst, vector< Mat > & gradient_lst, c
void train_svm( const vector< Mat > & gradient_lst, const vector< int > & labels )
{
SVM svm;
/* Default values to train SVM */
SVMParams params;
SVM::Params params;
params.coef0 = 0.0;
params.degree = 3;
params.term_crit.epsilon = 1e-3;
params.termCrit.epsilon = 1e-3;
params.gamma = 0;
params.kernel_type = SVM::LINEAR;
params.kernelType = SVM::LINEAR;
params.nu = 0.5;
params.p = 0.1; // for EPSILON_SVR, epsilon in loss function?
params.C = 0.01; // From paper, soft classifier
params.svm_type = SVM::EPS_SVR; // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
params.svmType = SVM::EPS_SVR; // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
Mat train_data;
convert_to_ml( gradient_lst, train_data );
clog << "Start training...";
svm.train( train_data, Mat( labels ), Mat(), Mat(), params );
Ptr<SVM> svm = StatModel::train<SVM>(train_data, ROW_SAMPLE, Mat(labels), params);
clog << "...[done]" << endl;
svm.save( "my_people_detector.yml" );
svm->save( "my_people_detector.yml" );
}
void draw_locations( Mat & img, const vector< Rect > & locations, const Scalar & color )
@@ -380,7 +354,7 @@ void test_it( const Size & size )
Scalar reference( 0, 255, 0 );
Scalar trained( 0, 0, 255 );
Mat img, draw;
SVM svm;
Ptr<SVM> svm;
HOGDescriptor hog;
HOGDescriptor my_hog;
my_hog.winSize = size;
@@ -388,7 +362,7 @@ void test_it( const Size & size )
vector< Rect > locations;
// Load the trained SVM.
svm.load( "my_people_detector.yml" );
svm = StatModel::load<SVM>( "my_people_detector.yml" );
// Set the trained svm to my_hog
vector< float > hog_detector;
get_svm_detector( svm, hog_detector );
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40 -88
View File
@@ -1,63 +1,35 @@
#include "opencv2/ml/ml.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/core/utility.hpp"
#include <stdio.h>
#include <string>
#include <map>
using namespace cv;
using namespace cv::ml;
static void help()
{
printf(
"\nThis sample demonstrates how to use different decision trees and forests including boosting and random trees:\n"
"CvDTree dtree;\n"
"CvBoost boost;\n"
"CvRTrees rtrees;\n"
"CvERTrees ertrees;\n"
"CvGBTrees gbtrees;\n"
"Call:\n\t./tree_engine [-r <response_column>] [-c] <csv filename>\n"
"\nThis sample demonstrates how to use different decision trees and forests including boosting and random trees.\n"
"Usage:\n\t./tree_engine [-r <response_column>] [-ts type_spec] <csv filename>\n"
"where -r <response_column> specified the 0-based index of the response (0 by default)\n"
"-c specifies that the response is categorical (it's ordered by default) and\n"
"-ts specifies the var type spec in the form ord[n1,n2-n3,n4-n5,...]cat[m1-m2,m3,m4-m5,...]\n"
"<csv filename> is the name of training data file in comma-separated value format\n\n");
}
static int count_classes(CvMLData& data)
static void train_and_print_errs(Ptr<StatModel> model, const Ptr<TrainData>& data)
{
cv::Mat r = cv::cvarrToMat(data.get_responses());
std::map<int, int> rmap;
int i, n = (int)r.total();
for( i = 0; i < n; i++ )
bool ok = model->train(data);
if( !ok )
{
float val = r.at<float>(i);
int ival = cvRound(val);
if( ival != val )
return -1;
rmap[ival] = 1;
printf("Training failed\n");
}
return (int)rmap.size();
}
static void print_result(float train_err, float test_err, const CvMat* _var_imp)
{
printf( "train error %f\n", train_err );
printf( "test error %f\n\n", test_err );
if (_var_imp)
else
{
cv::Mat var_imp = cv::cvarrToMat(_var_imp), sorted_idx;
cv::sortIdx(var_imp, sorted_idx, CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
printf( "variable importance:\n" );
int i, n = (int)var_imp.total();
int type = var_imp.type();
CV_Assert(type == CV_32F || type == CV_64F);
for( i = 0; i < n; i++)
{
int k = sorted_idx.at<int>(i);
printf( "%d\t%f\n", k, type == CV_32F ? var_imp.at<float>(k) : var_imp.at<double>(k));
}
printf( "train error: %f\n", model->calcError(data, false, noArray()) );
printf( "test error: %f\n\n", model->calcError(data, true, noArray()) );
}
printf("\n");
}
int main(int argc, char** argv)
@@ -69,14 +41,14 @@ int main(int argc, char** argv)
}
const char* filename = 0;
int response_idx = 0;
bool categorical_response = false;
std::string typespec;
for(int i = 1; i < argc; i++)
{
if(strcmp(argv[i], "-r") == 0)
sscanf(argv[++i], "%d", &response_idx);
else if(strcmp(argv[i], "-c") == 0)
categorical_response = true;
else if(strcmp(argv[i], "-ts") == 0)
typespec = argv[++i];
else if(argv[i][0] != '-' )
filename = argv[i];
else
@@ -88,52 +60,32 @@ int main(int argc, char** argv)
}
printf("\nReading in %s...\n\n",filename);
CvDTree dtree;
CvBoost boost;
CvRTrees rtrees;
CvERTrees ertrees;
CvGBTrees gbtrees;
const double train_test_split_ratio = 0.5;
CvMLData data;
Ptr<TrainData> data = TrainData::loadFromCSV(filename, 0, response_idx, response_idx+1, typespec);
CvTrainTestSplit spl( 0.5f );
if ( data.read_csv( filename ) == 0)
if( data.empty() )
{
data.set_response_idx( response_idx );
if(categorical_response)
data.change_var_type( response_idx, CV_VAR_CATEGORICAL );
data.set_train_test_split( &spl );
printf("======DTREE=====\n");
dtree.train( &data, CvDTreeParams( 10, 2, 0, false, 16, 0, false, false, 0 ));
print_result( dtree.calc_error( &data, CV_TRAIN_ERROR), dtree.calc_error( &data, CV_TEST_ERROR ), dtree.get_var_importance() );
if( categorical_response && count_classes(data) == 2 )
{
printf("======BOOST=====\n");
boost.train( &data, CvBoostParams(CvBoost::DISCRETE, 100, 0.95, 2, false, 0));
print_result( boost.calc_error( &data, CV_TRAIN_ERROR ), boost.calc_error( &data, CV_TEST_ERROR ), 0 ); //doesn't compute importance
}
printf("======RTREES=====\n");
rtrees.train( &data, CvRTParams( 10, 2, 0, false, 16, 0, true, 0, 100, 0, CV_TERMCRIT_ITER ));
print_result( rtrees.calc_error( &data, CV_TRAIN_ERROR), rtrees.calc_error( &data, CV_TEST_ERROR ), rtrees.get_var_importance() );
printf("======ERTREES=====\n");
ertrees.train( &data, CvRTParams( 18, 2, 0, false, 16, 0, true, 0, 100, 0, CV_TERMCRIT_ITER ));
print_result( ertrees.calc_error( &data, CV_TRAIN_ERROR), ertrees.calc_error( &data, CV_TEST_ERROR ), ertrees.get_var_importance() );
printf("======GBTREES=====\n");
if (categorical_response)
gbtrees.train( &data, CvGBTreesParams(CvGBTrees::DEVIANCE_LOSS, 100, 0.1f, 0.8f, 5, false));
else
gbtrees.train( &data, CvGBTreesParams(CvGBTrees::SQUARED_LOSS, 100, 0.1f, 0.8f, 5, false));
print_result( gbtrees.calc_error( &data, CV_TRAIN_ERROR), gbtrees.calc_error( &data, CV_TEST_ERROR ), 0 ); //doesn't compute importance
printf("ERROR: File %s can not be read\n", filename);
return 0;
}
else
printf("File can not be read");
data->setTrainTestSplitRatio(train_test_split_ratio);
printf("======DTREE=====\n");
Ptr<DTrees> dtree = DTrees::create(DTrees::Params( 10, 2, 0, false, 16, 0, false, false, Mat() ));
train_and_print_errs(dtree, data);
if( (int)data->getClassLabels().total() <= 2 ) // regression or 2-class classification problem
{
printf("======BOOST=====\n");
Ptr<Boost> boost = Boost::create(Boost::Params(Boost::GENTLE, 100, 0.95, 2, false, Mat()));
train_and_print_errs(boost, data);
}
printf("======RTREES=====\n");
Ptr<RTrees> rtrees = RTrees::create(RTrees::Params(10, 2, 0, false, 16, Mat(), false, 0, TermCriteria(TermCriteria::MAX_ITER, 100, 0)));
train_and_print_errs(rtrees, data);
return 0;
}
@@ -4,29 +4,29 @@
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace cv::ml;
int main()
int main(int, char**)
{
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(4, 1, CV_32FC1, labels);
int labels[4] = {1, -1, -1, -1};
Mat labelsMat(4, 1, CV_32SC1, labels);
float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);
// Set up SVM's parameters
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
SVM::Params params;
params.svmType = SVM::C_SVC;
params.kernelType = SVM::LINEAR;
params.termCrit = TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6);
// Train the SVM
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
Ptr<SVM> svm = StatModel::train<SVM>(trainingDataMat, ROW_SAMPLE, labelsMat, params);
Vec3b green(0,255,0), blue (255,0,0);
// Show the decision regions given by the SVM
@@ -34,30 +34,30 @@ int main()
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1,2) << j,i);
float response = SVM.predict(sampleMat);
float response = svm->predict(sampleMat);
if (response == 1)
image.at<Vec3b>(i,j) = green;
else if (response == -1)
image.at<Vec3b>(i,j) = blue;
image.at<Vec3b>(i,j) = blue;
}
// Show the training data
int thickness = -1;
int lineType = 8;
circle( image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType);
circle( image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType );
circle( image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType );
circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType );
circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType );
// Show support vectors
thickness = 2;
lineType = 8;
int c = SVM.get_support_vector_count();
Mat sv = svm->getSupportVectors();
for (int i = 0; i < c; ++i)
for (int i = 0; i < sv.rows; ++i)
{
const float* v = SVM.get_support_vector(i);
const float* v = sv.ptr<float>(i);
circle( image, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
}
@@ -8,6 +8,7 @@
#define FRAC_LINEAR_SEP 0.9f // Fraction of samples which compose the linear separable part
using namespace cv;
using namespace cv::ml;
using namespace std;
static void help()
@@ -30,7 +31,7 @@ int main()
//--------------------- 1. Set up training data randomly ---------------------------------------
Mat trainData(2*NTRAINING_SAMPLES, 2, CV_32FC1);
Mat labels (2*NTRAINING_SAMPLES, 1, CV_32FC1);
Mat labels (2*NTRAINING_SAMPLES, 1, CV_32SC1);
RNG rng(100); // Random value generation class
@@ -71,16 +72,15 @@ int main()
labels.rowRange(NTRAINING_SAMPLES, 2*NTRAINING_SAMPLES).setTo(2); // Class 2
//------------------------ 2. Set up the support vector machines parameters --------------------
CvSVMParams params;
params.svm_type = SVM::C_SVC;
SVM::Params params;
params.svmType = SVM::C_SVC;
params.C = 0.1;
params.kernel_type = SVM::LINEAR;
params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6);
params.kernelType = SVM::LINEAR;
params.termCrit = TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6);
//------------------------ 3. Train the svm ----------------------------------------------------
cout << "Starting training process" << endl;
CvSVM svm;
svm.train(trainData, labels, Mat(), Mat(), params);
Ptr<SVM> svm = StatModel::train<SVM>(trainData, ROW_SAMPLE, labels, params);
cout << "Finished training process" << endl;
//------------------------ 4. Show the decision regions ----------------------------------------
@@ -89,7 +89,7 @@ int main()
for (int j = 0; j < I.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1,2) << i, j);
float response = svm.predict(sampleMat);
float response = svm->predict(sampleMat);
if (response == 1) I.at<Vec3b>(j, i) = green;
else if (response == 2) I.at<Vec3b>(j, i) = blue;
@@ -117,11 +117,11 @@ int main()
//------------------------- 6. Show support vectors --------------------------------------------
thick = 2;
lineType = 8;
int x = svm.get_support_vector_count();
Mat sv = svm->getSupportVectors();
for (int i = 0; i < x; ++i)
for (int i = 0; i < sv.rows; ++i)
{
const float* v = svm.get_support_vector(i);
const float* v = sv.ptr<float>(i);
circle( I, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thick, lineType);
}
@@ -20,9 +20,7 @@ using namespace std;
// Global variables
Mat frame; //current frame
Mat fgMaskMOG; //fg mask generated by MOG method
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
int keyboard; //input from keyboard
@@ -63,11 +61,9 @@ int main(int argc, char* argv[])
//create GUI windows
namedWindow("Frame");
namedWindow("FG Mask MOG");
namedWindow("FG Mask MOG 2");
//create Background Subtractor objects
pMOG = createBackgroundSubtractorMOG(); //MOG approach
pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
if(strcmp(argv[1], "-vid") == 0) {
@@ -109,7 +105,6 @@ void processVideo(char* videoFilename) {
exit(EXIT_FAILURE);
}
//update the background model
pMOG->apply(frame, fgMaskMOG);
pMOG2->apply(frame, fgMaskMOG2);
//get the frame number and write it on the current frame
stringstream ss;
@@ -121,7 +116,6 @@ void processVideo(char* videoFilename) {
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = waitKey( 30 );
@@ -146,7 +140,6 @@ void processImages(char* fistFrameFilename) {
//read input data. ESC or 'q' for quitting
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
//update the background model
pMOG->apply(frame, fgMaskMOG);
pMOG2->apply(frame, fgMaskMOG2);
//get the frame number and write it on the current frame
size_t index = fn.find_last_of("/");
@@ -166,7 +159,6 @@ void processImages(char* fistFrameFilename) {
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = waitKey( 30 );
+1 -1
View File
@@ -17,7 +17,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
set(the_target "example_${project}_${name}")
add_executable(${the_target} ${srcs})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
set_target_properties(${the_target} PROPERTIES
OUTPUT_NAME "${project}-example-${name}"
+5 -5
View File
@@ -47,21 +47,21 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
set(the_target "example_${project}_${name}")
add_executable(${the_target} ${srcs})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS})
if(HAVE_CUDA AND NOT ANDROID)
target_link_libraries(${the_target} ${CUDA_CUDA_LIBRARY})
ocv_target_link_libraries(${the_target} ${CUDA_CUDA_LIBRARY})
endif()
if(HAVE_opencv_nonfree)
target_link_libraries(${the_target} opencv_nonfree)
ocv_target_link_libraries(${the_target} opencv_nonfree)
endif()
if(HAVE_opencv_cudacodec)
target_link_libraries(${the_target} opencv_cudacodec)
ocv_target_link_libraries(${the_target} opencv_cudacodec)
endif()
if(HAVE_opencv_ocl)
target_link_libraries(${the_target} opencv_ocl)
ocv_target_link_libraries(${the_target} opencv_ocl)
endif()
set_target_properties(${the_target} PROPERTIES
+2 -2
View File
@@ -8,10 +8,10 @@ if(HAVE_opencv_nonfree)
endif()
add_executable(${the_target} ${sources} ${headers})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS})
if(HAVE_opencv_nonfree)
target_link_libraries(${the_target} opencv_nonfree)
ocv_target_link_libraries(${the_target} opencv_nonfree)
endif()
set_target_properties(${the_target} PROPERTIES
-85
View File
@@ -1,85 +0,0 @@
#!/usr/bin/env python
import numpy as np
import cv2
import video
from common import nothing, clock, draw_str
MHI_DURATION = 0.5
DEFAULT_THRESHOLD = 32
MAX_TIME_DELTA = 0.25
MIN_TIME_DELTA = 0.05
def draw_motion_comp(vis, (x, y, w, h), angle, color):
cv2.rectangle(vis, (x, y), (x+w, y+h), (0, 255, 0))
r = min(w/2, h/2)
cx, cy = x+w/2, y+h/2
angle = angle*np.pi/180
cv2.circle(vis, (cx, cy), r, color, 3)
cv2.line(vis, (cx, cy), (int(cx+np.cos(angle)*r), int(cy+np.sin(angle)*r)), color, 3)
if __name__ == '__main__':
import sys
try:
video_src = sys.argv[1]
except:
video_src = 0
cv2.namedWindow('motempl')
visuals = ['input', 'frame_diff', 'motion_hist', 'grad_orient']
cv2.createTrackbar('visual', 'motempl', 2, len(visuals)-1, nothing)
cv2.createTrackbar('threshold', 'motempl', DEFAULT_THRESHOLD, 255, nothing)
cam = video.create_capture(video_src, fallback='synth:class=chess:bg=../cpp/lena.jpg:noise=0.01')
ret, frame = cam.read()
h, w = frame.shape[:2]
prev_frame = frame.copy()
motion_history = np.zeros((h, w), np.float32)
hsv = np.zeros((h, w, 3), np.uint8)
hsv[:,:,1] = 255
while True:
ret, frame = cam.read()
frame_diff = cv2.absdiff(frame, prev_frame)
gray_diff = cv2.cvtColor(frame_diff, cv2.COLOR_BGR2GRAY)
thrs = cv2.getTrackbarPos('threshold', 'motempl')
ret, motion_mask = cv2.threshold(gray_diff, thrs, 1, cv2.THRESH_BINARY)
timestamp = clock()
cv2.updateMotionHistory(motion_mask, motion_history, timestamp, MHI_DURATION)
mg_mask, mg_orient = cv2.calcMotionGradient( motion_history, MAX_TIME_DELTA, MIN_TIME_DELTA, apertureSize=5 )
seg_mask, seg_bounds = cv2.segmentMotion(motion_history, timestamp, MAX_TIME_DELTA)
visual_name = visuals[cv2.getTrackbarPos('visual', 'motempl')]
if visual_name == 'input':
vis = frame.copy()
elif visual_name == 'frame_diff':
vis = frame_diff.copy()
elif visual_name == 'motion_hist':
vis = np.uint8(np.clip((motion_history-(timestamp-MHI_DURATION)) / MHI_DURATION, 0, 1)*255)
vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
elif visual_name == 'grad_orient':
hsv[:,:,0] = mg_orient/2
hsv[:,:,2] = mg_mask*255
vis = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
for i, rect in enumerate([(0, 0, w, h)] + list(seg_bounds)):
x, y, rw, rh = rect
area = rw*rh
if area < 64**2:
continue
silh_roi = motion_mask [y:y+rh,x:x+rw]
orient_roi = mg_orient [y:y+rh,x:x+rw]
mask_roi = mg_mask [y:y+rh,x:x+rw]
mhi_roi = motion_history[y:y+rh,x:x+rw]
if cv2.norm(silh_roi, cv2.NORM_L1) < area*0.05:
continue
angle = cv2.calcGlobalOrientation(orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION)
color = ((255, 0, 0), (0, 0, 255))[i == 0]
draw_motion_comp(vis, rect, angle, color)
draw_str(vis, (20, 20), visual_name)
cv2.imshow('motempl', vis)
prev_frame = frame.copy()
if 0xFF & cv2.waitKey(5) == 27:
break
cv2.destroyAllWindows()
+1 -1
View File
@@ -17,7 +17,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
set(the_target "example_${project}_${name}")
add_executable(${the_target} ${srcs})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS})
set_target_properties(${the_target} PROPERTIES
OUTPUT_NAME "${project}-example-${name}"
+8 -8
View File
@@ -11,15 +11,15 @@
using namespace std;
using namespace cv;
#define M_MOG 1
#define M_MOG2 2
#define M_KNN 3
int main(int argc, const char** argv)
{
CommandLineParser cmd(argc, argv,
"{ c camera | false | use camera }"
"{ f file | 768x576.avi | input video file }"
"{ t type | mog | method's type (mog, mog2) }"
"{ t type | mog2 | method's type (knn, mog2) }"
"{ h help | false | print help message }"
"{ m cpu_mode | false | press 'm' to switch OpenCL<->CPU}");
@@ -41,7 +41,7 @@ int main(int argc, const char** argv)
return EXIT_FAILURE;
}
int m = method == "mog" ? M_MOG : M_MOG2;
int m = method == "mog2" ? M_MOG2 : M_KNN;
VideoCapture cap;
if (useCamera)
@@ -59,13 +59,13 @@ int main(int argc, const char** argv)
cap >> frame;
fgimg.create(frame.size(), frame.type());
Ptr<BackgroundSubtractorMOG> mog = createBackgroundSubtractorMOG();
Ptr<BackgroundSubtractorKNN> knn = createBackgroundSubtractorKNN();
Ptr<BackgroundSubtractorMOG2> mog2 = createBackgroundSubtractorMOG2();
switch (m)
{
case M_MOG:
mog->apply(frame, fgmask, 0.01f);
case M_KNN:
knn->apply(frame, fgmask);
break;
case M_MOG2:
@@ -86,8 +86,8 @@ int main(int argc, const char** argv)
//update the model
switch (m)
{
case M_MOG:
mog->apply(frame, fgmask, 0.01f);
case M_KNN:
knn->apply(frame, fgmask);
break;
case M_MOG2: