diff --git a/Demo.cpp b/Demo.cpp index 0a522cc9674d4f12157aa65340e34bb089e4fb67..bda103b06bef73448f5a46112fe1b69d11b790b1 100644 --- a/Demo.cpp +++ b/Demo.cpp @@ -24,21 +24,8 @@ based on original demo.cpp #include "package_bgs/Tapter.h" #include "package_bgs/ttoolbox.h" -//std::string mNzero(int i) -//{ -// std::ostringstream convert; -// convert << i ; -// std::string numberString = convert.str(); -// std::string newNumberString = std::string(10 - numberString.length(), '0') + numberString; -// return newNumberString; -//} -//std::string getFileName(int i) -//{ -// //cv::String inputPath= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/data/"; -// std::string fileName = "/data/"+ mNzero(i) + ".jpg"; -// return fileName; -//} - +using namespace cv; +using namespace std; char* getCmdOption(char ** begin, char ** end, const std::string & option) { @@ -186,10 +173,10 @@ int main(int argc, char * argv[]) Tapter *bgs = new Tapter; - bgs->setPathOut(outputDir); - bgs->setInitialFrameCounter(0); - bgs->setFlagWrite(0); - bgs->setFlagWriteDBGpic(0); + // bgs->setPathOut(outputDir); + // bgs->setInitialFrameCounter(0); + // bgs->setFlagWrite(0); + // bgs->setFlagWriteDBGpic(0); //see paper https://dl.acm.org/citation.cfm?id=2321600 @@ -200,7 +187,7 @@ int main(int argc, char * argv[]) int i= 0; cv::Mat img_input; - int begin = 0; + //int begin = 0; int steps = amountFiles; //init the random number generator srand (time(NULL)); @@ -234,27 +221,27 @@ int main(int argc, char * argv[]) 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); + // //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); + // 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; -// } + // } + // else + // { + // cout<<"error loading file: "<< staticFile<<", will abort"<<endl; + // return EXIT_FAILURE; + // } std::string fileName; @@ -283,7 +270,7 @@ int main(int argc, char * argv[]) { //random index - int index = rand() % steps + begin; //TODO: double check no double draw ?? + int index = rand() % amountFiles; //TODO: double check no double draw ?? fileName = inputDir + TToolBox::getFileName(index); myRandomTrainList.push_back(fileName); @@ -300,15 +287,15 @@ int main(int argc, char * argv[]) cv::Mat img_mask; cv::Mat img_bkgmodel; -// //adapter learning rate -// if(j>62) -// bgs->setLearningRate(j); + // //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 -// //we save the bk gmodel -// std::string bkTestFileName = inputDir + "bk_"+TToolBox::mNzero(i)+".jpg"; -// imwrite(bkTestFileName.c_str(),img_bkgmodel); + // //we save the bk gmodel + // std::string bkTestFileName = inputDir + "bk_"+TToolBox::mNzero(i)+".jpg"; + // imwrite(bkTestFileName.c_str(),img_bkgmodel); } else { @@ -319,63 +306,275 @@ int main(int argc, char * argv[]) cout <<"c) we produce train the background with random choosen files"<< fileName<<endl; - bgs->setInitialFrameCounter(0); - bgs->setFlagWrite(1); - bgs->setFlagWriteDBGpic(1); int everyPic=60; - for(i=begin;i<begin+steps;i++) + int frameCounter=0; + for(frameCounter=0;i<amountFiles;frameCounter++) { + //measure time consumption clock_t begin = clock(); - fileName = inputDir + TToolBox::getFileName(i); + fileName = inputDir + TToolBox::getFileName(frameCounter); cout <<"\t"<<i<<"\tof \t"<<amountFiles<<" load file :"<< fileName<<endl; //cv::imwrite(convert.str().c_str(), img_output); + //we open the file img_input = imread(fileName.c_str(), CV_LOAD_IMAGE_COLOR); if(img_input.data ) { - //we cut out a smaller ROI + //! we cut out a smaller ROI, + //! step 1) img_input = TToolBox::cropImageCircle(img_input,circleCenterX,circleCenterY,circleRadius); - //cv::imshow("input", img_input); + //! normal bgs processing + //! step 2) + cv::Mat img_mask; + cv::Mat img_bkgmodel; + + bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image + + //! 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() ); - //we write just every xx pic a dbg picture, will speed up - if(i%everyPic==0) + //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; + + //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 { - bgs->setFlagWrite(1); + 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) { - bgs->setFlagWrite(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); + } - cv::Mat img_mask; - cv::Mat img_bkgmodel; - bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image - } + }//end if the loaded picture has data else { cout<<"error loading file: "<< fileName<<", will abort"<<endl; return EXIT_FAILURE; } + //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; } - // clock_t endAll = clock(); - // double elapsed_secs = double(endAll - beginAll) / CLOCKS_PER_SEC; - // cout <<"process"<<amountFiles<<" took:\t"<<(int)(elapsed_secs/60)<<" min"<<endl; - // //we write the random file list + //finishing time + clock_t endAll = clock(); + double elapsed = double(endAll - beginAll) / CLOCKS_PER_SEC; + cout <<"process : "<<amountFiles<<" files took:\t"<<(int)(elapsed/60)<<" min -\t"<<(int)(elapsed/60/60)<<" h \n in total"<<endl; + //we write the random file list //format output file std::string nameOutRandomFile = outputDir + "randlist.yml"; diff --git a/package_bgs/Tapter.cpp b/package_bgs/Tapter.cpp index 4c485ca6dd938b385f5cba4d3cc19a33e1c231d2..6d2425af5f13eeb785a889d05e045276f77b64e8 100644 --- a/package_bgs/Tapter.cpp +++ b/package_bgs/Tapter.cpp @@ -23,12 +23,12 @@ Tapter::Tapter() : { std::cout << "Tapter()" << std::endl; setup("./config/Tapter.xml"); - frameCounter = 0; - //inputPath = "."; - //centerFile = "."; - outputPath = "."; - flagWrite = -1; - writeDbgPic = -1; +// frameCounter = 0; +// //inputPath = "."; +// //centerFile = "."; +// outputPath = "."; +// flagWrite = -1; +// writeDbgPic = -1; } @@ -38,31 +38,31 @@ Tapter::~Tapter() std::cout << "~Tapter()" << std::endl; } -void Tapter::setFlagWrite(short flag) -{ - flagWrite = flag; -} +//void Tapter::setFlagWrite(short flag) +//{ +// flagWrite = flag; +//} -void Tapter::setFlagWriteDBGpic(short flag) -{ - writeDbgPic = flag; -} +//void Tapter::setFlagWriteDBGpic(short flag) +//{ +// writeDbgPic = flag; +//} -void Tapter::setPathOut(std::string outPath) -{ - outputPath = outPath; -} +//void Tapter::setPathOut(std::string outPath) +//{ +// outputPath = outPath; +//} -void Tapter::setLearningRate(int rate) -{ - learningRate = rate; +//void Tapter::setLearningRate(int rate) +//{ +// learningRate = rate; -} -void Tapter::setInitialFrameCounter(int counter) -{ - frameCounter = counter; -} +//} +//void Tapter::setInitialFrameCounter(int counter) +//{ +// frameCounter = counter; +//} void Tapter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel) { @@ -103,322 +103,6 @@ void Tapter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img img_foreground.copyTo(img_output); img_background.copyTo(img_bgmodel); - //also more************************ - - /// we apply a edge detection - //TODO make this in a function, how many times is this listed ?? - double threshholdMin = 150; - double threshholdMax = 200; - int apertureSize = 3; - - vector<vector<Point> > contours = applyCannyEdgeAndCalcCountours(img_output,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 - - - ///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; - - //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 - - ///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 ); - } - - //! 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 moments from the contour selection - 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= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/"; - std::ostringstream convert2; - convert2 << outpath2 << frameCounter <<"_convex_hull.jpg"; - cv::imwrite(convert2.str().c_str(), imgConvexHull); - } - else - cout<<"convex hull has no points will skip file: "<<frameCounter<<endl; - -#endif - - if(flagWrite) - { - //format output file - std::string nameOutPutFileData = outputPath + TToolBox::mNzero(frameCounter) + ".yml"; - - FileStorage fs(nameOutPutFileData.c_str(), FileStorage::WRITE); - fs << "masscenters" << massCenters; - fs << "polygonselection"<< contourSelection; - fs << "convexhull"<<conHull; - fs << "masscenterconvexhull"<<muConvexHullMassCenter; - - //fs << "masscenters" << "["; -// for( size_t i = 0; i < massCenters.size(); i++ ) -// { -// Point2f p = massCenters[i]; -// fs << "{:" << "x" << (float) p.x << "y" << (float) p.y << "}"; -// } -// fs << "]"; - - fs.release(); - - } - - if(writeDbgPic) - { - 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 = outputPath + TToolBox::mNzero(frameCounter) + ".jpg"; - imwrite(nameOutPutFileDBGpic.c_str(),imgOverlay2); - - } - -#ifdef MC_SHOW_STEP_ANALYSE - - if(contourSelection.size()>=0)//we only draw if we have at least a countour left - { - RNG rng(4344234); - Mat imgContourSelection = Mat::zeros( img_input.size(), CV_8UC3 ); - imgContourSelection = Scalar(255,255,255); //fille the picture - - - 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( imgContourSelection, contourSelection, i, color, 1, LINE_AA); - } - - Scalar colorD( 0,0,255,255 );//red - //we draw all mass centers - for( int i = 0; i< contourSelection.size(); i++ ) - { - circle( imgContourSelection, massCenters[i], 4, colorD, -1, 8, 0 ); - } - - cout <<"\t"<<frameCounter<<" #countoursSelection:"<<contourSelection.size()<<"\t#massCenters: "<<massCenters.size()<<endl; - for(int i=0;i<massCenters.size();i++) - cout<<"mc["<<i<<"]:"<<massCenters[i].x<<";"<<massCenters[i].y<<endl; - - //TODO double check countor[index] and index == i !!! is not matching - //TODO -// //we draw in red the center of the minRect -// for( size_t i = 0; i< recCenterPoints.size(); i++ ) -// { -// Point center = recCenterPoints.at(i); - -// //the center -// circle( imgContourSelection, center, 2, colorD, -1, 8, 0 ); -// } - -// //iterate all rectangles -// for( size_t i = 0; i< minRect.size(); i++ ) -// { -// Point2f recPoints[4]; -// RotatedRect rec=minRect[i]; - -// //get all points of the rect -// rec.points(recPoints); - -// //vector<Point2f> recContour; -// //we add for corners -// for(int j=0;j<4;j++) -// { -//// recContour.push_back(recPoints[j]); -// //the edges -// //circle( imgContourSelection, recPoints[j], 3, colorD, -1, 8, 0 ); - -// //the lines -// line(imgContourSelection,recPoints[j],recPoints[(j+1)%4],colorD,1,8); - -// //the center -// //circle( imgContourSelection, center, 2, color, -1, 8, 0 ); -// } -// //polylines(imgContourSelection, recContour, true, colorD, 1, 8); - -// } - - - cv::String outpath4= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/"; - std::ostringstream convert4; - convert4 << outpath4 << frameCounter <<"_contour_selection.jpg"; - cv::imwrite(convert4.str().c_str(), imgContourSelection); - } - else - cout<<"error no contour in selective list left, skip frame: "<<frameCounter<<endl; - - - - //******** - //we also the "normal" output the file - cv::String outpath= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/"; - std::ostringstream convert; - convert << outpath << frameCounter++ << ".jpg"; - cv::imwrite(convert.str().c_str(), img_output); - //**** end -#else - frameCounter++; -#endif - - delete frame; firstTime = false; @@ -452,55 +136,4 @@ void Tapter::loadConfig() cvReleaseFileStorage(&fs); } -vector<vector<Point> > Tapter::applyCannyEdgeAndCalcCountours(Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize) -{ - Mat imgCannyEdge; - vector<vector<Point> > contours; - vector<Vec4i> hierarchy; - - //! 2 make a copy - Mat imgBinary = imgSource.clone(); - //imgMarkBinary = Scalar(255,255,255); //fill white - - //! 3 apply binary filter not reduce noise - //method to threshold important changes - int binaryThreshold = 80; - imgBinary = imgSource > binaryThreshold; - - - //! 4 smooth with gaussian filter to suppress no connected lines - //add a gaussian filter //see http://docs.opencv.org/2.4/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html - Mat imgSmoothed = imgBinary.clone(); - int exclusPara3 = 3; - cv::GaussianBlur(imgBinary,imgSmoothed,Size(exclusPara3,exclusPara3),0); //0 = BORDER_CONSTANT - - //! 5 we make the canny edge detect - // Detect edges using canny - Canny( imgSmoothed, imgCannyEdge, threshholdMin, threshholdMax, apertureSize ); - - // Find contours, use RETR_EXTERNAL ignore inner child structures, TREE more usefull ? - findContours( imgCannyEdge, contours, hierarchy, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); - -#ifdef MC_SHOW_STEP_ANALYSE - // Draw contours on extra mat - Mat imgContour = Mat::zeros( imgCannyEdge.size(), CV_8UC3 ); - imgContour = Scalar(255,255,255); //fille the picture - RNG rng(232323); - for( size_t i = 0; i< contours.size(); i++ ) - { - //random color - Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - //contour - drawContours( imgContour, contours, i, color, 1, LINE_AA, hierarchy, 0, Point() ); - } - cv::String outpath= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/"; - std::ostringstream convert; - convert << outpath << frameCounter <<"_countour_canny_edge.jpg"; - cv::imwrite(convert.str().c_str(), imgContour); - -#endif - - // return minRect; - return contours; -} diff --git a/package_bgs/Tapter.h b/package_bgs/Tapter.h index ccc08db6781dbed3010877a098d58fb0027daa06..ae4ef5eca2114f95390f6a17c7900d7049a3cece 100644 --- a/package_bgs/Tapter.h +++ b/package_bgs/Tapter.h @@ -49,12 +49,12 @@ namespace bgslibrary int trainingLearningRate; int trainingSteps; - int frameCounter; // - std::string inputPath; -// std::string centerFile; - short flagWrite; - short writeDbgPic; - std::string outputPath; +// int frameCounter; // +// std::string inputPath; +//// std::string centerFile; +// short flagWrite; +// short writeDbgPic; +// std::string outputPath; public: Tapter(); @@ -65,16 +65,16 @@ namespace bgslibrary // void setPaths(std::string inPath,std::string outPath); void setPathOut(std::string outPath); - //! 1 is on - //! other no write - void setFlagWrite(short flag); +// //! 1 is on +// //! other no write +// void setFlagWrite(short flag); - //! set learning rate - void setLearningRate(int rate); +// //! set learning rate +// void setLearningRate(int rate); - //! 1 is on - //! other no write - void setFlagWriteDBGpic(short flag); +// //! 1 is on +// //! other no write +// void setFlagWriteDBGpic(short flag); void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel); @@ -82,7 +82,6 @@ namespace bgslibrary void saveConfig(); void loadConfig(); - vector<vector<Point> > applyCannyEdgeAndCalcCountours(cv::Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize); }; } diff --git a/package_bgs/ttoolbox.cpp b/package_bgs/ttoolbox.cpp index d6bfd1e56c77ae551cc1e870ea0d118ec1b58e38..073b4637a8b675da2370a54400e8ca277852316d 100644 --- a/package_bgs/ttoolbox.cpp +++ b/package_bgs/ttoolbox.cpp @@ -14,6 +14,59 @@ std::string TToolBox::getFileName(int i) return fileName; } +std::vector<std::vector<cv::Point>> TToolBox::applyCannyEdgeAndCalcCountours(cv::Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize) +{ + cv::Mat imgCannyEdge; + std::vector<std::vector<cv::Point> > contours; + std::vector<cv::Vec4i> hierarchy; + + //! 2 make a copy + cv::Mat imgBinary = imgSource.clone(); + //imgMarkBinary = Scalar(255,255,255); //fill white + + //! 3 apply binary filter not reduce noise + //method to threshold important changes + int binaryThreshold = 80; //TODO as parameter + imgBinary = imgSource > binaryThreshold; + + + //! 4 smooth with gaussian filter to suppress no connected lines + //add a gaussian filter //see http://docs.opencv.org/2.4/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html + cv::Mat imgSmoothed = imgBinary.clone(); + int exclusPara3 = 3; //TODO as parameter + cv::GaussianBlur(imgBinary,imgSmoothed,cv::Size(exclusPara3,exclusPara3),0); //0 = BORDER_CONSTANT + + //! 5 we make the canny edge detect + // Detect edges using canny + cv::Canny( imgSmoothed, imgCannyEdge, threshholdMin, threshholdMax, apertureSize ); + + // Find contours, use RETR_EXTERNAL ignore inner child structures, TREE more usefull ? + cv::findContours( imgCannyEdge, contours, hierarchy, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); + +#ifdef MC_SHOW_STEP_ANALYSE + // Draw contours on extra mat + Mat imgContour = Mat::zeros( imgCannyEdge.size(), CV_8UC3 ); + imgContour = Scalar(255,255,255); //fille the picture + RNG rng(232323); + for( size_t i = 0; i< contours.size(); i++ ) + { + //random color + Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); + //contour + drawContours( imgContour, contours, i, color, 1, LINE_AA, hierarchy, 0, Point() ); + } + + cv::String outpath= "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/result/"; + std::ostringstream convert; + convert << outpath << frameCounter <<"_countour_canny_edge.jpg"; + cv::imwrite(convert.str().c_str(), imgContour); + +#endif + + // return minRect; + return contours; +} + cv::Mat TToolBox::cropImageCircle(cv::Mat image, int x, int y, int r) { diff --git a/package_bgs/ttoolbox.h b/package_bgs/ttoolbox.h index cc0a80c9ad8a07e0a5867eba3812947963430805..75bea2cc14d3f00401cd107aa2fed7f05bfc225a 100644 --- a/package_bgs/ttoolbox.h +++ b/package_bgs/ttoolbox.h @@ -33,6 +33,10 @@ public: //! will fill rest outer bound black static cv::Mat cropImageCircle(cv::Mat image, int x, int y, int r); + //! canny edge detect + static std::vector<std::vector<cv::Point>> applyCannyEdgeAndCalcCountours(cv::Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize); + + }; #endif // TTOOLBOX_H