diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index a3c3856d2a..8d62b2b7e4 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #ifdef HAVE_OPENGL #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN 1 @@ -36,17 +39,17 @@ static void help() cout << "\n This program demonstrates how to use MSER to detect extremal regions \n" "Usage: \n" " ./detect_mser \n" - "Press esc key when image window is active to change descriptor parameter\n" + "Press esc key when image window is active to change descriptor parameter\n" "Press 2, 8, 4, 6, +,- or 5 keys in openGL windows to change view or use mouse\n"; } struct MSERParams { MSERParams(int _delta = 5, int _min_area = 60, int _max_area = 14400, - double _max_variation = 0.25, double _min_diversity = .2, - int _max_evolution = 200, double _area_threshold = 1.01, - double _min_margin = 0.003, int _edge_blur_size = 5) - { + double _max_variation = 0.25, double _min_diversity = .2, + int _max_evolution = 200, double _area_threshold = 1.01, + double _min_margin = 0.003, int _edge_blur_size = 5) + { delta = _delta; minArea = _min_area; maxArea = _max_area; @@ -57,7 +60,7 @@ struct MSERParams minMargin = _min_margin; edgeBlurSize = _edge_blur_size; pass2Only = false; - } + } int delta; int minArea; @@ -72,30 +75,20 @@ struct MSERParams int edgeBlurSize; }; -static String Legende(MSERParams &pAct) +static String Legende(const MSERParams &pAct) { - String s=""; - String inf = static_cast(ostringstream() << pAct.minArea).str(); - String sup = static_cast(ostringstream() << pAct.maxArea).str(); - s = " Area[" + inf + "," + sup + "]"; + ostringstream ss; + ss << "Area[" << pAct.minArea << "," << pAct.maxArea << "] "; + ss << "del. [" << pAct.delta << "] "; + ss << "var. [" << pAct.maxVariation << "] "; + ss << "div. [" << (int)pAct.minDiversity << "] "; + ss << "pas. [" << (int)pAct.pass2Only << "] "; + ss << "RGb->evo. [" << pAct.maxEvolution << "] "; + ss << "are. [" << (int)pAct.areaThreshold << "] "; + ss << "mar. [" << (int)pAct.minMargin << "] "; + ss << "siz. [" << pAct.edgeBlurSize << "]"; - inf = static_cast(ostringstream() << pAct.delta).str(); - s += " del. [" + inf + "]"; - inf = static_cast(ostringstream() << pAct.maxVariation).str(); - s += " var. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.minDiversity).str(); - s += " div. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.pass2Only).str(); - s += " pas. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.maxEvolution).str(); - s += "RGb-> evo. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.areaThreshold).str(); - s += " are. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.minMargin).str(); - s += " mar. [" + inf + "]"; - inf = static_cast(ostringstream() << (int)pAct.edgeBlurSize).str(); - s += " siz. [" + inf + "]"; - return s; + return ss.str(); } @@ -109,18 +102,28 @@ bool keyPressed=false; Vec4f rotAxis(1,0,1,0); Vec3f zoom(1,0,0); -float obsX = (float)0, obsY = (float)0, obsZ = (float)-10, tx = (float)0, ty = (float)0; -float thetaObs = (float)-1.570, phiObs = (float)1.570, rObs = (float)10; -int prevX=-1,prevY=-1,prevTheta=-1000,prevPhi=-1000; +float obsX = 0.f; +float obsY = 0.f; +float obsZ = -10.f; +float tx = 0.f; +float ty = 0.f; + +float thetaObs = -1.570f; +float phiObs = 1.570f; +float rObs = 10.f; + +int prevX = -1; +int prevY = -1; +int prevTheta = -1000; +int prevPhi = -1000; #ifdef HAVE_OPENGL struct DrawData - - { +{ ogl::Arrays arr; ogl::Texture2D tex; ogl::Buffer indices; - }; +}; static void draw(void* userdata) @@ -167,19 +170,19 @@ static void onMouse(int event, int x, int y, int flags, void*) { if (x - prevTheta<0) { - thetaObs +=(float)0.02; + thetaObs += 0.02f; } else if (x - prevTheta>0) { - thetaObs -= (float)0.02; + thetaObs -= 0.02f; } if (y - prevPhi<0) { - phiObs -= (float)0.02; + phiObs -= 0.02f; } else if (y - prevPhi>0) { - phiObs += (float)0.02; + phiObs += 0.02f; } prevTheta = x; prevPhi = y; @@ -187,9 +190,9 @@ static void onMouse(int event, int x, int y, int flags, void*) if (event==EVENT_MOUSEWHEEL) { if (getMouseWheelDelta(flags)>0) - rObs += (float)0.1; + rObs += 0.1f; else - rObs -= (float)0.1; + rObs -= 0.1f; } float pi = static_cast(CV_PI); if (thetaObs>pi) @@ -202,11 +205,11 @@ static void onMouse(int event, int x, int y, int flags, void*) } if (phiObs>pi / 2) { - phiObs = pi / 2 - (float)0.0001; + phiObs = pi / 2 - 0.0001f; } if (phiObs<-pi / 2) { - phiObs = -pi / 2 + (float)0.00001; + phiObs = -pi / 2 + 0.00001f; } if (rObs<0) { @@ -224,36 +227,37 @@ static void DrawOpenGLMSER(Mat img, Mat result) cvtColor(img, imgGray, COLOR_BGR2GRAY); else imgGray = img; + namedWindow("OpenGL", WINDOW_OPENGL); setMouseCallback("OpenGL", onMouse, NULL); Mat_ vertex(1, img.cols*img.rows); Mat_ texCoords(1, img.cols*img.rows); for (int i = 0, nbPix = 0; i(0, nbPix) = Vec3f(float(2 * (x - 0.5)), float(2 * (0.5 - y)), float(imgGray.at(i, j) / 512.0)); texCoords.at< Vec2f>(0, nbPix) = Vec2f(x, y); - } } + } Mat_ indices(1, (img.rows - 1)*(6 * img.cols)); for (int i = 1, nbPix = 0; i(0, nbPix++) = c ; + indices.at(0, nbPix++) = c; indices.at(0, nbPix++) = c - 1; - indices.at(0, nbPix++) = c- img.cols - 1; - indices.at(0, nbPix++) = c- img.cols - 1; + indices.at(0, nbPix++) = c - img.cols - 1; + indices.at(0, nbPix++) = c - img.cols - 1; indices.at(0, nbPix++) = c - img.cols; - indices.at(0, nbPix++) = c ; - } + indices.at(0, nbPix++) = c; } + } DrawData *data = new DrawData; @@ -279,7 +283,7 @@ static void DrawOpenGLMSER(Mat img, Mat result) setOpenGlDrawCallback("OpenGL", draw, data); for (;;) - { + { updateWindow("OpenGL"); char key = (char)waitKey(40); if (key == 27) @@ -292,27 +296,28 @@ static void DrawOpenGLMSER(Mat img, Mat result) case '5': obsX = 0, obsY = 0, obsZ = -10; thetaObs = -pi/2, phiObs = pi/2, rObs = 10; - tx=0;ty=0; + tx=0; ty=0; break; case '4': - thetaObs += (float)0.1; + thetaObs += 0.1f; break; case '6': - thetaObs -= (float)0.1; + thetaObs -= 0.1f; break; case '2': - phiObs -= (float).1; + phiObs -= 0.1f; break; case '8': - phiObs += (float).1; + phiObs += 0.1f; break; case '+': - rObs -= (float).1; + rObs -= 0.1f; break; case '-': - rObs += (float).1; + rObs += 0.1f; break; } + if (thetaObs>pi) { thetaObs = -2 * pi + thetaObs; @@ -320,9 +325,9 @@ static void DrawOpenGLMSER(Mat img, Mat result) if (thetaObs<-pi) thetaObs = 2 * pi + thetaObs; if (phiObs>pi / 2) - phiObs = pi / 2 - (float)0.0001; + phiObs = pi / 2 - 0.0001f; if (phiObs<-pi / 2) - phiObs = -pi / 2 + (float)0.00001; + phiObs = -pi / 2 + 0.00001f; if (rObs<0) rObs = 0; obsX = rObs*cos(thetaObs)*cos(phiObs); @@ -334,67 +339,59 @@ static void DrawOpenGLMSER(Mat img, Mat result) } #endif -static Mat MakeSyntheticImage() -{ - Mat img(800, 800, CV_8UC1); - map val; - int fond = 0; - img = Scalar(fond); - val[fond] = 1; - int width1[] = { 390, 380, 300, 290, 280, 270, 260, 250, 210, 190, 150, 100, 80, 70 }; - int color1[] = { 80, 180, 160, 140, 120, 100, 90, 110, 170, 150, 140, 100, 220 }; - Point p0(10, 10); - int *width, *color; - - width = width1; - color = color1; - for (int i = 0; i<13; i++) - { +// Add nested rectangles of different widths and colors to an image +static void addNestedRectangles(Mat &img, Point p0, int* width, int *color, int n) { + for (int i = 0; i(i, 0)!=0) { - cout << "h" << i << "=\t" << hist.at(i, 0) << "\n"; + cout << "h" << setw(3) << left << i << "\t=\t" << hist.at(i, 0) << "\n"; } } @@ -403,68 +400,60 @@ static Mat MakeSyntheticImage() int main(int argc, char *argv[]) { - vector fileName; - Mat imgOrig,img; - Size blurSize(5,5); + Mat imgOrig, img; + Size blurSize(5, 5); cv::CommandLineParser parser(argc, argv, "{ help h | | }{ @input | | }"); if (parser.has("help")) { help(); return 0; } + string input = parser.get("@input"); if (!input.empty()) { - fileName.push_back(input); - imgOrig = imread(fileName[0], IMREAD_GRAYSCALE); + imgOrig = imread(input, IMREAD_GRAYSCALE); blur(imgOrig, img, blurSize); } else { - fileName.push_back("SyntheticImage.bmp"); imgOrig = MakeSyntheticImage(); - img=imgOrig; + img = imgOrig; } - MSERParams pDefaultMSER; // Descriptor array MSER vector typeDesc; // Param array for MSER vector pMSER; - vector::iterator itMSER; // Color palette - vector palette; - for (int i = 0; i<65536; i++) + vector palette; + for (int i = 0; i<=numeric_limits::max(); i++) palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); + help(); + MSERParams params; + + params.delta = 10; + params.minArea = 100; + params.maxArea = 5000; + params.maxVariation = 2; + params.minDiversity = 0; + params.pass2Only = true; + typeDesc.push_back("MSER"); - pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 10; - pMSER.back().minArea = 100; - pMSER.back().maxArea = 5000; - pMSER.back().maxVariation = 2; - pMSER.back().minDiversity = 0; - pMSER.back().pass2Only = true; + pMSER.push_back(params); + + params.pass2Only = false; typeDesc.push_back("MSER"); - pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 10; - pMSER.back().minArea = 100; - pMSER.back().maxArea = 5000; - pMSER.back().maxVariation = 2; - pMSER.back().minDiversity = 0; - pMSER.back().pass2Only = false; + pMSER.push_back(params); + + params.delta = 100; typeDesc.push_back("MSER"); - pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 100; - pMSER.back().minArea = 100; - pMSER.back().maxArea = 5000; - pMSER.back().maxVariation = 2; - pMSER.back().minDiversity = 0; - pMSER.back().pass2Only = false; - itMSER = pMSER.begin(); - vector desMethCmp; + pMSER.push_back(params); + + vector::iterator itMSER = pMSER.begin(); Ptr b; String label; // Descriptor loop @@ -473,14 +462,14 @@ int main(int argc, char *argv[]) for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); ++itDesc) { vector keyImg1; - if (*itDesc == "MSER"){ + if (*itDesc == "MSER") + { if (img.type() == CV_8UC3) { b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity, itMSER->maxEvolution, itMSER->areaThreshold, itMSER->minMargin, itMSER->edgeBlurSize); label = Legende(*itMSER); ++itMSER; - } else { @@ -490,6 +479,7 @@ int main(int argc, char *argv[]) ++itMSER; } } + if (img.type()==CV_8UC3) { img.copyTo(result); @@ -505,36 +495,37 @@ int main(int argc, char *argv[]) try { // We can detect regions using detectRegions method - vector keyImg; - vector zone; - vector > region; - Mat desc; + vector keyImg; + vector zone; + vector > region; + Mat desc; if (b.dynamicCast() != NULL) { Ptr sbd = b.dynamicCast(); sbd->detectRegions(img, region, zone); - int i = 0; //result = Scalar(0, 0, 0); int nbPixelInMSER=0; - for (vector >::iterator itr = region.begin(); itr != region.end(); ++itr, ++i) + for (vector >::iterator itr = region.begin(); itr != region.end(); ++itr) { - for (vector ::iterator itp = region[i].begin(); itp != region[i].end(); ++itp) + for (vector ::iterator itp = itr->begin(); itp != itr->end(); ++itp) { // all pixels belonging to region become blue result.at(itp->y, itp->x) = Vec3b(128, 0, 0); nbPixelInMSER++; } } - cout << "Number of MSER region " << region.size()<<" Number of pixels in all MSER region : "<