Skip to content
Snippets Groups Projects
Commit 3581efbc authored by Thomas Boy's avatar Thomas Boy
Browse files

added the generation of background tool

parent 8534f328
Branches
No related tags found
No related merge requests found
/*
This file is part of BGSLibrary.
./bgs_demo -i test45/ -a 100 -o test45/results/
based on original demo.cpp
*/
BGSLibrary is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
//cpp c
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <ctime>
BGSLibrary is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BGSLibrary. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <opencv2/opencv.hpp>
#define PROCESS_CENTER_VERSION_MAJOR 0
#define PROCESS_CENTER_VERSION_MINOR 6
//opencv
#include <opencv2/opencv.hpp>
//bgslibrary
#include "package_bgs/bgslibrary.h"
//my class
#include "package_bgs/Tapter.h"
#include "package_bgs/ttoolbox.h"
using namespace cv;
using namespace std;
int main(int argc, char **argv)
char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
/* Background Subtraction Methods */
IBGS *bgs;
//bgs = new FrameDifference;
//bgs = new StaticFrameDifference;
//bgs = new WeightedMovingMean;
//bgs = new WeightedMovingVariance;
//bgs = new MixtureOfGaussianV1; // only on OpenCV 2.x
//bgs = new MixtureOfGaussianV2;
//bgs = new AdaptiveBackgroundLearning;
//bgs = new AdaptiveSelectiveBackgroundLearning;
//bgs = new GMG; // only on OpenCV 2.x
//bgs = new KNN; // only on OpenCV 3.x
//bgs = new DPAdaptiveMedian;
//bgs = new DPGrimsonGMM;
//bgs = new DPZivkovicAGMM;
//bgs = new DPMean;
//bgs = new DPWrenGA;
//bgs = new DPPratiMediod;
//bgs = new DPEigenbackground;
//bgs = new DPTexture;
//bgs = new T2FGMM_UM;
//bgs = new T2FGMM_UV;
//bgs = new T2FMRF_UM;
//bgs = new T2FMRF_UV;
//bgs = new FuzzySugenoIntegral;
//bgs = new FuzzyChoquetIntegral;
//bgs = new MultiLayer;
//bgs = new PixelBasedAdaptiveSegmenter;
//bgs = new LBSimpleGaussian;
//bgs = new LBFuzzyGaussian;
//bgs = new LBMixtureOfGaussians;
bgs = new LBAdaptiveSOM;
//bgs = new LBFuzzyAdaptiveSOM;
//bgs = new LBP_MRF;
//bgs = new VuMeter;
//bgs = new KDE;
//bgs = new IndependentMultimodal;
//bgs = new MultiCue;
//bgs = new SigmaDelta;
//bgs = new SuBSENSE;
//bgs = new LOBSTER;
//bgs = new PAWCS;
//bgs = new TwoPoints;
//bgs = new ViBe;
int frameNumber = 1;
int key = 0;
while (key != 'q')
{
std::stringstream ss;
ss << frameNumber;
std::string fileName = "dataset/frames/" + ss.str() + ".png";
std::cout << "reading " << fileName << std::endl;
cv::Mat img_input = cv::imread(fileName, CV_LOAD_IMAGE_COLOR);
if (img_input.empty())
break;
cv::imshow("input", img_input);
cv::Mat img_mask;
cv::Mat img_bkgmodel;
bgs->process(img_input, img_mask, img_bkgmodel);
// by default, "bgs->process(.)" automatically shows the foreground mask image
// or set "bgs->setShowOutput(false)" to disable
//if(!img_mask.empty())
// cv::imshow("Foreground", img_mask);
// do something
key = cvWaitKey(33);
frameNumber++;
}
cvWaitKey(0);
delete bgs;
cvDestroyAllWindows();
return 0;
char ** itr = std::find(begin, end, option);
if (itr != end && ++itr != end)
{
return *itr;
}
return 0;
}
bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
return std::find(begin, end, option) != end;
}
int main(int argc, char * argv[])
{
std::cout << "using produce bk " <<PROCESS_CENTER_VERSION_MAJOR <<"."<< PROCESS_CENTER_VERSION_MINOR << endl;
std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
//!** parse programm input****************/
if(cmdOptionExists(argv, argv+argc, "-h"))
{
cout <<" error: please use command as\n./bgs_demo -i pathToInputDir -a amountOfJpgFiles -c exactCenterConfFile.xml -o outPutPath"<<endl;
return EXIT_FAILURE;
}
if(!cmdOptionExists(argv, argv+argc, "-i")||!cmdOptionExists(argv, argv+argc, "-a")||!cmdOptionExists(argv, argv+argc, "-o") )
{
cout <<" error: please use command as\n./bgs_demo -i pathToInputDir -a amountOfJpgFiles -c exactCenterConfFile.xml -o outPutPath"<<endl;
return EXIT_FAILURE;
}
char *testInputDir = getCmdOption(argv, argv + argc, "-i");
string inputDir(".");
if (testInputDir)
{
//test dir exists
inputDir = string(testInputDir);
}
int amountFiles = -1;
char *testFileAmount = getCmdOption(argv, argv + argc, "-a");
if (testFileAmount)
{
string s(testFileAmount);
stringstream foo(s);
foo >> amountFiles;
}
char *centerFile = getCmdOption(argv, argv + argc, "-c");
string centerFileString(".");
if (centerFile)
{
//test dir exists
centerFileString = string(centerFile);
}
char *testOutputDir = getCmdOption(argv, argv + argc, "-o");
string outputDir(".");
if (testOutputDir)
{
//test dir exists
outputDir = string(testOutputDir);
}
cout <<"args: -i "<<inputDir<<" -a "<<amountFiles << " -c" << centerFileString<<" -o " << outputDir;
//!**** end parse input***********/
//./program -i pathToInputDir -a amountOfJpgFiles -o outPutPath
//pathToInputDir
//----should have
// centerFile.xml
// -data/
// #which include all jpg and tt files
// first file mus be: 0000000000.jpg
// -bk.jpg
// #is the neutral bk file for training the bgs method
//
// VideoCapture capture;
// if (argc > 1)
// {
// std::cout << "Openning: " << argv[1] << std::endl;
// capture.open(argv[1]);
// }
// else
// capture.open(0);
// if (!capture.isOpened())
// {
// std::cerr << "Cannot initialize video!" << std::endl;
// return -1;
// }
/* Background Subtraction Methods */
//IBGS *bgs;
//bgs = new FrameDifference;
//bgs = new StaticFrameDifference;
//bgs = new WeightedMovingMean;
//bgs = new WeightedMovingVariance;
//bgs = new MixtureOfGaussianV1; // only on OpenCV 2.x
//bgs = new MixtureOfGaussianV2;
//bgs = new AdaptiveBackgroundLearning;
//bgs = new AdaptiveSelectiveBackgroundLearning;
//bgs = new GMG; // only on OpenCV 2.x
//bgs = new KNN; // only on OpenCV 3.x
//bgs = new DPAdaptiveMedian;
//bgs = new DPGrimsonGMM;
//bgs = new DPZivkovicAGMM;
//bgs = new DPMean;
//bgs = new DPWrenGA;
//bgs = new DPPratiMediod;
//bgs = new DPEigenbackground;
//bgs = new DPTexture;
//bgs = new T2FGMM_UM;
//bgs = new T2FGMM_UV;
//bgs = new T2FMRF_UM;
//bgs = new T2FMRF_UV;
//bgs = new FuzzySugenoIntegral;
//bgs = new FuzzyChoquetIntegral;
//bgs = new MultiLayer;
//bgs = new PixelBasedAdaptiveSegmenter;
//bgs = new LBSimpleGaussian;
//bgs = new LBFuzzyGaussian;
//bgs = new LBMixtureOfGaussians;
//bgs = new LBAdaptiveSOM;
//bgs = new LBFuzzyAdaptiveSOM;
//bgs = new LBP_MRF;
//bgs = new VuMeter;
//bgs = new KDE;
//bgs = new IndependentMultimodal;
//bgs = new MultiCue;
//bgs = new SigmaDelta;
//bgs = new SuBSENSE;
//bgs = new LOBSTER;
//bgs = new PAWCS;
//bgs = new TwoPoints;
//bgs = new ViBe;
//bgs = new Tapter;
Tapter *bgs = new Tapter;
// bgs->setPathOut(outputDir);
// bgs->setInitialFrameCounter(0);
// bgs->setFlagWrite(0);
// bgs->setFlagWriteDBGpic(0);
//see paper https://dl.acm.org/citation.cfm?id=2321600
//https://ieeexplore.ieee.org/document/4527178/
//was in benchmark on top https://www.researchgate.net/publication/259340906_A_comprehensive_review_of_background_subtraction_algorithms_evaluated_with_synthetic_and_real_videos
//my own adapter to use the model
int i= 0;
cv::Mat img_input;
//init the random number generator
srand (time(NULL));
clock_t beginAll = clock();
//! we read the center config file for cut out the ROI
//TODO merge this config with the Tapter.xml ??
//circle param
int circleCenterX = 880;
int circleCenterY = 750;
int circleRadius = 700;
cv::String configFileNameCenter(centerFileString);
//read the config
cout << "parameter of centerConfigFile.xml"<<endl;
FileStorage fsCen;
fsCen.open(configFileNameCenter, FileStorage::READ);
if (!fsCen.isOpened())
{
cout << "error during open " <<centerFileString << " will abort\n ";
return EXIT_FAILURE;
}
circleCenterX = (int) fsCen["circleCenterX"];
cout <<"circleCenterX: "<< circleCenterX<<endl;
circleCenterY = (int) fsCen["circleCenterY"];
cout <<"circleCenterY: "<< circleCenterY<<endl;
circleRadius = (int) fsCen["circleRadius"];
cout <<"circleRadius: "<< circleRadius<<endl;
fsCen.release();
// //first the static pic**********
// //std::string fileName = getFileName(begin);
// std::string staticFile = inputDir+"/bk.jpg";
// cout <<"a) load first static background pic :"<< staticFile<<endl;
// img_input = imread(staticFile.c_str(), CV_LOAD_IMAGE_COLOR);
// if(img_input.data )
// {
// //we cut out a smaller ROI
// img_input = TToolBox::cropImageCircle(img_input,circleCenterX,circleCenterY,circleRadius);
// cv::Mat img_mask;
// cv::Mat img_bkgmodel;
// bgs->process(img_input, img_mask, img_bkgmodel);
// }
// else
// {
// cout<<"error loading file: "<< staticFile<<", will abort"<<endl;
// return EXIT_FAILURE;
// }
std::string fileName;
//! we train with first x on random draws
//int amountTrainingSteps = 2;
// //we open the config file and readin
// cv::String configFileName("./config/Tapter.xml");
// {//read the config
// FileStorage fs;
// fs.open(configFileName, FileStorage::READ);
// if (!fs.isOpened())
// {
// cout << "error during open " << configFileName << " will abort " <<endl;
// return EXIT_FAILURE;
// }
// //param
// amountTrainingSteps = (int) fs["trainingSteps"];
// //cout <<"amountTrainingSteps: "<< amountTrainingSteps<< endl;
// fs.release();
// }
cout <<"a) we choose two random file "<< fileName<<endl;
//int j=255;
vector<Mat> picsMask;
vector<Mat> picsOrigin;
int maxTrain = 10;
vector<string> myRandomTrainList; //we save all draws in a list which will save to the results
for(i=0;i<maxTrain;i++)
{
//random index
int index = rand() % amountFiles; //TODO: double check no double draw ??
fileName = inputDir + TToolBox::getFileName(index);
myRandomTrainList.push_back(fileName);
cout <<"\t"<<i <<"\t of \t"<<maxTrain<<" rnd file :"<< fileName<<endl;
img_input = imread(fileName.c_str(), CV_LOAD_IMAGE_COLOR);
if(img_input.data )
{
//we cut out a smaller ROI
img_input = TToolBox::cropImageCircle(img_input,circleCenterX,circleCenterY,circleRadius);
//cv::imshow("input", img_input);
cv::Mat img_mask;
cv::Mat img_bkgmodel;
// //adapter learning rate
// if(j>62)
// bgs->setLearningRate(j);
bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
if(i>=(maxTrain-2))
{
picsMask.push_back(img_mask.clone());
picsOrigin.push_back(img_input.clone());
}
// //we save the bk gmodel
// std::string bkTestFileName = inputDir + "bk_"+TToolBox::mNzero(i)+".jpg";
// imwrite(bkTestFileName.c_str(),img_bkgmodel);
}
else
{
cout<<"error loading file: "<< fileName<<", will abort"<<endl;
return EXIT_FAILURE;
}
}
cout <<"b) we calc the two polygones of the points"<< fileName<<endl;
if(picsMask.empty())
{
cout<<"error no pics loaded"<<endl;
return EXIT_FAILURE;
}
else
cout<<"pics.size(): "<<picsMask.size()<<endl;
int frameCounter = 0;
//vector<vector<vector<Point>>> polyGones;
vector<RotatedRect> rectanglesPicA;//we will save the rectangles for each polygone which was selected
vector<RotatedRect> rectanglesPicB;
for(frameCounter=0;frameCounter<2;frameCounter++)
{
Mat img_mask = picsMask[frameCounter];
//! step 3) we make we apply a edge detection
//TODO make this in a function, how many times is this listed ??
//TODO read from tapter config
//TODO all parameter from applyCannyEdgeAndCalcCountours also !!
double threshholdMin = 150;
double threshholdMax = 200;
int apertureSize = 3;
std::vector<vector<Point> > contours = TToolBox::applyCannyEdgeAndCalcCountours(img_mask,threshholdMin,threshholdMax,apertureSize);
// //TODO: we need to order the points to get a nice polygon, otherwise not usefull
// //we also try to find the aproximate polygon*****************
//// vector<Point> aproxiCurve;
//// // //see https://docs.opencv.org/3.4/d3/d63/classcv_1_1Mat.html#a167a8e0a3a3d86e84b70e33483af4466
//// // if(aproxiCurve::checkVector(10,CV_32F)==-1)
//// // cout<<"error wrong format of vector"<<endl;
//// //calc 0.1 percent of arc length of convex hull
//// double epsilon = 0.1 * cv::arcLength(hullComplete,true);
//// //see https://docs.opencv.org/2.4.13.2/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#approxpolydp
//// cv::approxPolyDP(allContourPoints,aproxiCurve,epsilon,false);
////#ifdef MC_SHOW_STEP_ANALYSE
//// if(aproxiCurve.size()>=2)//we only draw if we have at least a line
//// {
//// Mat imgPolyApr = Mat::zeros( img_input.size(), CV_8UC3 );
//// imgPolyApr = Scalar(255,255,255); //fille the picture
//// Scalar colorC( 0,0,255,255 );//red
//// //for(imgPolyApr)
//// polylines(imgPolyApr, aproxiCurve, true, colorC, 1, 8);
//// cv::String outpath3= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/";
//// std::ostringstream convert3;
//// convert3 << outpath3 << frameCounter <<"_appr_poly.jpg";
//// cv::imwrite(convert3.str().c_str(), imgPolyApr);
//// }
//// else
//// cout<<"approximate poly has not enough points will skip file: "<<frameCounter<<endl;
////#endif
//! step 4) we make a selection out of all counters with area sizes******************************
vector<vector<Point> > contourSelection;
//we exlcude very small one and very big ones
//we calc all min rotated rectangles for all contour from candy egde detect
vector<RotatedRect> minRect( contours.size() );
//calc boxes around the contours
for( size_t i = 0; i < contours.size(); i++ )
minRect[i] = minAreaRect( Mat(contours[i]) ); //may use boundingRect ?? to use fix non rotated rectangles ?
vector<Point2f> recCenterPoints;
float areaMinThreshold = 150;
float areaMaxThreshold = 15000; //TODO apply moving filter ??, an more adaptive approach
//iterate all rectangles
for( size_t i = 0; i< minRect.size(); i++ )
{
Point2f rect_points[4];
//get all points of the retange
minRect[i].points( rect_points );
//construct contour based on rectangle points because contour != rectangle with points
vector<Point> contourRect;
for(int j=0;j<4;j++)
contourRect.push_back(rect_points[j]);
//calc the area of the contour
double area0 = contourArea(contourRect);
//over stepp all small areas
if(area0<areaMinThreshold||area0>areaMaxThreshold)
{
cout<<i<<":area0:"<<area0<<" dismissed "<<endl;
//skipe if the area is too small
continue;
}
else
{
cout<<i<<":area0:"<<area0<<" choose "<<endl;
//we add the rectangles to the list
if(frameCounter==0)
rectanglesPicA.push_back(minRect[i]);
if(frameCounter==1)
rectanglesPicB.push_back(minRect[i]);
//get the center of this rectangle
Point2f center = minRect[i].center;
recCenterPoints.push_back(center);
//we also add the this contour to a selection
contourSelection.push_back(contours[i]);
}
}//end iterate all min rectangle
// //! step 5) we calc the moments from the contour selection
// vector<Moments> mu(contourSelection.size() );
// for( size_t i = 0; i < contourSelection.size(); i++ )
// {
// mu[i] = moments( contourSelection[i], false );
// }
// // Get the mass centers:
// vector<Point2f> massCenters( contourSelection.size() );
// for( size_t i = 0; i < contourSelection.size(); i++ )
// {
// massCenters[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
// }
// //! step 6) calc convex hull of all points of the contour selection *********
// //TODO produce center of convex hull of all polygones
// //TODO double check if ne contour sharing a center point ? nearby ??
// //we merge all points
// vector<Point> allContourPoints;
// for (size_t cC = 0; cC < contourSelection.size(); ++cC)
// for(size_t cP =0; cP < contourSelection[cC].size(); cP++)
// {
// Point currentContourPixel = contourSelection[cC][cP];
// allContourPoints.push_back(currentContourPixel);
// }
// // calc the hull ******************
// vector<Point> conHull(allContourPoints.size());
// convexHull( Mat(allContourPoints), conHull, false );
// // Point roiCenter;
// // float roiRadius;
// //calc the min circle around
// //minEnclosingCircle(conHull,roiCenter,roiRadius);
// //we calc the mass center of the convex hull
// ///we calc the mass center of the convex hull
// Moments muConvexHull;
// Point2f muConvexHullMassCenter(0.0,0.0);
// if(!conHull.empty())
// {
// muConvexHull = moments(conHull, true );
// muConvexHullMassCenter= Point2f( muConvexHull.m10/muConvexHull.m00 , muConvexHull.m01/muConvexHull.m00 );
// }
//#ifdef MC_SHOW_STEP_ANALYSE
// if(!conHull.empty())//if we any elements, we process further
// {
// Mat imgConvexHull = Mat::zeros( img_input.size(), CV_8UC3 );
// imgConvexHull = Scalar(255,255,255); //fille the picture
// Scalar colorB( 0,0,255,255 );//red
// polylines(imgConvexHull, hullComplete, true, colorB, 1, 8);
// //draw circle around
// //circle( imgConvexHull, roiCenter, (int) roiRadius, colorB, 2, 8, 0 );
// //we draw it
// cv::String outpath2= outputDir;
// std::ostringstream convert2;
// convert2 << outpath2 <<TToolBox::mNzero(frameCounter) <<"_convex_hull.jpg";
// cv::imwrite(convert2.str().c_str(), imgConvexHull);
// }
// else
// cout<<"convex hull has no points will skip file: "<<i<<endl;
//#endif
// //! step 8: we write down all our results in yml file
// std::string nameOutPutFileData = outputDir + TToolBox::mNzero(frameCounter) + ".yml";
// FileStorage fs(nameOutPutFileData.c_str(), FileStorage::WRITE);
// fs << "masscenters" << massCenters;
// fs << "polygonselection"<< contourSelection;
// fs << "convexhull"<<conHull;
// fs << "masscenterconvexhull"<<muConvexHullMassCenter;
// fs.release();
// //! we write from time to time a dbg picture
// if(frameCounter%everyPic==0)
// {
// Scalar colorRed( 0,0,255,255 );//red
// RNG rng(4344234);
// Mat imgDebugPaint2 = Mat::zeros( img_input.size(), CV_8UC3 );
// imgDebugPaint2 = Scalar(255,255,255); //fill the picture white
// //we write all polyies of the selection and the mass centers with a random color
// for( size_t i = 0; i< contourSelection.size(); i++ )
// {
// //random color
// Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
// //contour
// drawContours( imgDebugPaint2, contourSelection, i, color, 1, LINE_AA);
// //draw the center
// circle( imgDebugPaint2, massCenters[i], 4, color, -1, 8, 0 );
// }
// //we write the convex hull
// if(!conHull.empty())
// {
// //the poly
// polylines(imgDebugPaint2, conHull, true, colorRed, 1, 8);
// //the center
// circle( imgDebugPaint2,muConvexHullMassCenter, 4, colorRed, -1, 8, 0 );
// }
// //we make a copy
// Mat imgOverlay2 = img_input.clone();
// //we add a overlay of our paitings
// addWeighted( imgDebugPaint2, 0.7, imgOverlay2, 0.3, 0.0, imgOverlay2);
// //we write the file down
// std::string nameOutPutFileDBGpic = outputDir + TToolBox::mNzero(frameCounter) + ".jpg";
// imwrite(nameOutPutFileDBGpic.c_str(),imgOverlay2);
// }
}//end for iterate frame
if(rectanglesPicA.empty()||rectanglesPicB.empty())
cout<<"error no retangles found in pics "<<endl;
Mat picA = picsOrigin[0].clone();
Mat picB = picsOrigin[1].clone();
//now we iterate all rectangles in picA and will produce pictures
for(size_t i=0;i<rectanglesPicA.size();i++)
{
std::string filenName = outputDir + "bk_candidate_a_" + TToolBox::mNzero(i) + ".jpg";
cout << "process picA i"<<i<<" name" <<filenName << endl;
//get the points
RotatedRect rectA= rectanglesPicA[i];
Point2f rectApoints[4];
//get all points of the retange
rectA.points( rectApoints );
//@see https://docs.opencv.org/3.4.0/db/dd6/classcv_1_1RotatedRect.html#a69d648b086f26dbce0029facae9bfb2d
//The points array for storing rectangle vertices.
//The order is bottomLeft, topLeft, topRight, bottomRight.
Point2f corner = rectApoints[1];
//we should add some offset
int offset = 50; //TODO double check offset
Point2f cornerOffset= Point2f((float)( corner.x-offset), (float) (corner.y-offset));
Rect rect = rectA.boundingRect();
//TODO check if out of our area
Rect rectOffset = Rect((float) (cornerOffset.x),(float) (cornerOffset.y),(float)(rect.width + offset) ,(float) (rect.height+offset )) ;
Mat imageRoi = picB(rectOffset);
// std::string filenNameROI = outputDir + "bk_test_a_roi_" + TToolBox::mNzero(i) + ".jpg";
// imwrite(filenNameROI.c_str(),imageRoi);
//imageRoi = Scalar( 255, 0, 0); //fill blue)
// std::cout << "rect size: " << rect.size() << std::endl;
// std::cout << "tempResult cols,rows: " << picB.cols << ", " << picB.rows << endl;
cv::Rect rectROI(cornerOffset.x,cornerOffset.y, imageRoi.cols, imageRoi.rows);
imageRoi.copyTo(picA(rectROI));
cout << "."<<endl;
imwrite(filenName.c_str(),picA);
}
//now we iterate all rectangles and will produce pictures
for(size_t i=0;i<rectanglesPicB.size();i++)
{
std::string filenName = outputDir + "bk_candidate_b_" + TToolBox::mNzero(i) + ".jpg";
cout << "process picB i"<<i<<" name" <<filenName << endl;
//get the points
RotatedRect rectB= rectanglesPicB[i];
Point2f rectBpoints[4];
//get all points of the retange
rectB.points( rectBpoints );
//@see https://docs.opencv.org/3.4.0/db/dd6/classcv_1_1RotatedRect.html#a69d648b086f26dbce0029facae9bfb2d
//The points array for storing rectangle vertices.
//The order is bottomLeft, topLeft, topRight, bottomRight.
Point2f corner = rectBpoints[1];
//we should add some offset
int offset = 50; //TODO double check offset
Point2f cornerOffset= Point2f((float)( corner.x-offset), (float) (corner.y-offset));
Rect rect = rectB.boundingRect();
//TODO check if out of our area
Rect rectOffset = Rect((float) (cornerOffset.x),(float)(cornerOffset.y),(float)(rect.width+offset) ,(float) (rect.height+offset)) ;
Mat imageRoi = picA(rectOffset);
// std::string filenNameROI = outputDir + "bk_test_a_roi_" + TToolBox::mNzero(i) + ".jpg";
// imwrite(filenNameROI.c_str(),imageRoi);
//imageRoi = Scalar( 255, 0, 0); //fill blue)
// std::cout << "rect size: " << rect.size() << std::endl;
// std::cout << "tempResult cols,rows: " << picB.cols << ", " << picB.rows << endl;
cv::Rect rectROI(cornerOffset.x,cornerOffset.y, imageRoi.cols, imageRoi.rows);
imageRoi.copyTo(picB(rectROI));
cout << "."<<endl;
imwrite(filenName.c_str(),picB);
}
// //we calc the time which we used for a picture
// clock_t end = clock();
// double elapsedSecs = double(end - begin) / CLOCKS_PER_SEC;
// //we calc the time which was used for all picture
// clock_t endAll = clock();
// double elapsedSecTotal = double(endAll - beginAll) / CLOCKS_PER_SEC;
// cout <<"process single pic:\t"<<elapsedSecs<<" s - \t\t"<<(int)(elapsedSecTotal/60)<<" min -\t"<<(int)(elapsedSecTotal/60/60)<<" h"<<endl;
delete bgs;
// capture.release();
cvDestroyAllWindows();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment