From 68e9d19743047b9a9cb4fc37fe0e645eac895f67 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 16 May 2015 18:59:22 +0200 Subject: [PATCH] An example how to use features2d for MSER. Data results are visualized in 3D using openglwith mouse or keyboard --- samples/cpp/BLOB_MSER.cpp | 571 ------------------------------------ samples/cpp/detect_mser.cpp | 524 +++++++++++++++++++++++++++++++++ 2 files changed, 524 insertions(+), 571 deletions(-) delete mode 100644 samples/cpp/BLOB_MSER.cpp create mode 100644 samples/cpp/detect_mser.cpp diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp deleted file mode 100644 index 37c00237da..0000000000 --- a/samples/cpp/BLOB_MSER.cpp +++ /dev/null @@ -1,571 +0,0 @@ -#include -#include "opencv2/core/opengl.hpp" - -#include -#include -#include -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN 1 -#define NOMINMAX 1 -#include -#endif -#if defined(_WIN64) -#include -#endif - -#if defined(__APPLE__) -#include -#include -#else -#include -#include -#endif - -using namespace std; -using namespace cv; - - -void Example_MSER(vector &fileName); - -static void help() -{ - cout << "\n This program demonstrates how to use BLOB and MSER to detect region \n" - "Usage: \n" - " ./BLOB_MSER \n" - "Press a key when image window is active to change descriptor"; -} - -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) - { - delta = _delta; - minArea = _min_area; - maxArea = _max_area; - maxVariation = _max_variation; - minDiversity = _min_diversity; - maxEvolution = _max_evolution; - areaThreshold = _area_threshold; - minMargin = _min_margin; - edgeBlurSize = _edge_blur_size; - pass2Only = false; - } - - int delta; - int minArea; - int maxArea; - double maxVariation; - double minDiversity; - bool pass2Only; - - int maxEvolution; - double areaThreshold; - double minMargin; - int edgeBlurSize; - }; - -String Legende(SimpleBlobDetector::Params &pAct) -{ - String s=""; - if (pAct.filterByArea) - { - String inf = static_cast(&(ostringstream() << pAct.minArea))->str(); - String sup = static_cast(&(ostringstream() << pAct.maxArea))->str(); - s = " Area range [" + inf + " to " + sup + "]"; - } - if (pAct.filterByCircularity) - { - String inf = static_cast(&(ostringstream() << pAct.minCircularity))->str(); - String sup = static_cast(&(ostringstream() << pAct.maxCircularity))->str(); - if (s.length()==0) - s = " Circularity range [" + inf + " to " + sup + "]"; - else - s += " AND Circularity range [" + inf + " to " + sup + "]"; - } - if (pAct.filterByColor) - { - String inf = static_cast(&(ostringstream() << (int)pAct.blobColor))->str(); - if (s.length() == 0) - s = " Blob color " + inf; - else - s += " AND Blob color " + inf; - } - if (pAct.filterByConvexity) - { - String inf = static_cast(&(ostringstream() << pAct.minConvexity))->str(); - String sup = static_cast(&(ostringstream() << pAct.maxConvexity))->str(); - if (s.length() == 0) - s = " Convexity range[" + inf + " to " + sup + "]"; - else - s += " AND Convexity range[" + inf + " to " + sup + "]"; - } - if (pAct.filterByInertia) - { - String inf = static_cast(&(ostringstream() << pAct.minInertiaRatio))->str(); - String sup = static_cast(&(ostringstream() << pAct.maxInertiaRatio))->str(); - if (s.length() == 0) - s = " Inertia ratio range [" + inf + " to " + sup + "]"; - else - s += " AND Inertia ratio range [" + inf + " to " + sup + "]"; - } - return s; -} - - -const int win_width = 800; -const int win_height = 640; - -struct DrawData - { - ogl::Arrays arr; - ogl::Texture2D tex; - ogl::Buffer indices; - }; - -void draw(void* userdata); - -void draw(void* userdata) - { - DrawData* data = static_cast(userdata); - - glRotated(0.6, 0, 1, 0); - - ogl::render(data->arr, data->indices, ogl::TRIANGLES); - } - -int main(int argc, char *argv[]) -{ - -Mat imgcol = imread("../data/lena.jpg"); -namedWindow("OpenGL", WINDOW_OPENGL); -//resizeWindow("OpenGL", win_width, win_height); - -Mat_ vertex(1, 4); -vertex << Vec3f(-1, 1,0), Vec3f(-1, -1,0), Vec3f(1, -1,1), Vec3f(1, 1,-1); - -Mat_ texCoords(1, 4); -texCoords << Vec2f(0, 0), Vec2f(0, 1), Vec2f(1, 1), Vec2f(1, 0); - -Mat_ indices(1, 6); -indices << 0, 1, 2,2, 3, 0; - -DrawData *data = new DrawData; - -data->arr.setVertexArray(vertex); -data->arr.setTexCoordArray(texCoords); -data->indices.copyFrom(indices); -data->tex.copyFrom(imgcol); - -glMatrixMode(GL_PROJECTION); -glLoadIdentity(); -gluPerspective(45.0, (double)win_width / win_height, 0.1, 100.0); - -glMatrixMode(GL_MODELVIEW); -glLoadIdentity(); -gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0); - -glEnable(GL_TEXTURE_2D); -data->tex.bind(); - -glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); - -glDisable(GL_CULL_FACE); - -setOpenGlDrawCallback("OpenGL", draw, data); - -for (;;) - { - updateWindow("OpenGL"); - int key = waitKey(40); - if ((key & 0xff) == 27) - break; - } - -setOpenGlDrawCallback("OpenGL", 0, 0); -destroyAllWindows(); - - - - - - - vector fileName; - Example_MSER(fileName); - Mat img(600,800,CV_8UC1); - if (argc == 1) - { - fileName.push_back("../data/BLOB_MSER.bmp"); - } - else if (argc == 2) - { - fileName.push_back(argv[1]); - } - else - { - help(); - return(0); - } - img = imread(fileName[0], IMREAD_UNCHANGED); - if (img.rows*img.cols <= 0) - { - cout << "Image " << fileName[0] << " is empty or cannot be found\n"; - return(0); - } - - SimpleBlobDetector::Params pDefaultBLOB; - MSERParams pDefaultMSER; - // This is default parameters for SimpleBlobDetector - pDefaultBLOB.thresholdStep = 10; - pDefaultBLOB.minThreshold = 10; - pDefaultBLOB.maxThreshold = 220; - pDefaultBLOB.minRepeatability = 2; - pDefaultBLOB.minDistBetweenBlobs = 10; - pDefaultBLOB.filterByColor = false; - pDefaultBLOB.blobColor = 0; - pDefaultBLOB.filterByArea = false; - pDefaultBLOB.minArea = 25; - pDefaultBLOB.maxArea = 5000; - pDefaultBLOB.filterByCircularity = false; - pDefaultBLOB.minCircularity = 0.9f; - pDefaultBLOB.maxCircularity = std::numeric_limits::max(); - pDefaultBLOB.filterByInertia = false; - pDefaultBLOB.minInertiaRatio = 0.1f; - pDefaultBLOB.maxInertiaRatio = std::numeric_limits::max(); - pDefaultBLOB.filterByConvexity = false; - pDefaultBLOB.minConvexity = 0.95f; - pDefaultBLOB.maxConvexity = std::numeric_limits::max(); - // Descriptor array (BLOB or MSER) - vector typeDesc; - // Param array for BLOB - vector pBLOB; - vector::iterator itBLOB; - // Param array for MSER - vector pMSER; - vector::iterator itMSER; - - // Color palette - vector palette; - for (int i=0;i<65536;i++) - palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); - help(); - -/* typeDesc.push_back("MSER"); - pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 1; - pMSER.back().minArea = 1; - pMSER.back().maxArea = 180000; - pMSER.back().maxVariation= 500; - pMSER.back().minDiversity = 0; - pMSER.back().pass2Only = false;*/ - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByColor = true; - pBLOB.back().blobColor = 0; - - // This descriptor are going to be detect and compute 4 BLOBS with 4 differents params - // Param for first BLOB detector we want all - typeDesc.push_back("BLOB"); // see http://docs.opencv.org/trunk/d0/d7a/classcv_1_1SimpleBlobDetector.html - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByArea = true; - pBLOB.back().minArea = 1; - pBLOB.back().maxArea = int(img.rows*img.cols); - // Param for second BLOB detector we want area between 500 and 2900 pixels - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByArea = true; - pBLOB.back().minArea = 500; - pBLOB.back().maxArea = 2900; - // Param for third BLOB detector we want only circular object - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByCircularity = true; - // Param for Fourth BLOB detector we want ratio inertia - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByInertia = true; - pBLOB.back().minInertiaRatio = 0; - pBLOB.back().maxInertiaRatio = (float)0.2; - // Param for Fourth BLOB detector we want ratio inertia - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByConvexity = true; - pBLOB.back().minConvexity = 0.; - pBLOB.back().maxConvexity = (float)0.9; - - - itBLOB = pBLOB.begin(); - itMSER = pMSER.begin(); - vector desMethCmp; - Ptr b; - String label; - // Descriptor loop - vector::iterator itDesc; - for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++) - { - vector keyImg1; - if (*itDesc == "BLOB"){ - b = SimpleBlobDetector::create(*itBLOB); - label=Legende(*itBLOB); - - itBLOB++; - } - 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); - b.dynamicCast()->setPass2Only(itMSER->pass2Only); - } - else - { - b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity); - } - //b = MSER::create(); - //b = MSER::create(); - } - try { - // We can detect keypoint with detect method - vector keyImg; - vector zone; - vector> region; - Mat desc, result(img.rows,img.cols,CV_8UC3); - - - if (b.dynamicCast() != NULL) - { - Ptr sbd = b.dynamicCast(); - sbd->detect(img, keyImg, Mat()); - drawKeypoints(img,keyImg,result); - int i=0; - for (vector::iterator k=keyImg.begin();k!=keyImg.end();k++,i++) - circle(result,k->pt,k->size,palette[i%65536]); - } - if (b.dynamicCast() != NULL) - { - Ptr sbd = b.dynamicCast(); - sbd->detectRegions(img, region, zone); - int i = 0; - result=Scalar(0,0,0); - for (vector::iterator r = zone.begin(); r != zone.end();r++,i++) - { - // we draw a white rectangle which include all region pixels - rectangle(result, *r, Vec3b(255, 0, 0), 2); - } - i=0; - for (vector>::iterator itr = region.begin(); itr != region.end(); itr++, i++) - { - for (vector ::iterator itp = region[i].begin(); itp != region[i].end(); itp++) - { - // all pixels belonging to region are red - result.at(itp->y, itp->x) = Vec3b(0,0,128); - } - } - } - namedWindow(*itDesc+label , WINDOW_AUTOSIZE); - imshow(*itDesc + label, result); - imshow("Original", img); - FileStorage fs(*itDesc + "_" + fileName[0] + ".xml", FileStorage::WRITE); - fs<<*itDesc< &fileName) -{ - Mat img(800, 800, CV_8UC1); - fileName.push_back("SyntheticImage.bmp"); - 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++) - { - rectangle(img, Rect(p0, Size(width[i], width[i])), Scalar(color[i]), 1); - p0 += Point((width[i] - width[i + 1]) / 2, (width[i] - width[i + 1]) / 2); - floodFill(img, p0, Scalar(color[i])); - - } - p0 = Point(200, 600); - for (int i = 0; i<13; i++) - { - circle(img, p0, width[i] / 2, Scalar(color[i]), 1); - floodFill(img, p0, Scalar(color[i])); - - } - for (int i = 0; i<13; i++) - color1[i] = 255 - color1[i]; - p0 = Point(410, 10); - for (int i = 0; i<13; i++) - { - rectangle(img, Rect(p0, Size(width[i], width[i])), Scalar(color[i]), 1); - p0 += Point((width[i] - width[i + 1]) / 2, (width[i] - width[i + 1]) / 2); - floodFill(img, p0, Scalar(color[i])); - - } - - p0 = Point(600, 600); - for (int i = 0; i<13; i++) - { - circle(img, p0, width[i]/2,Scalar(color[i]), 1); - floodFill(img, p0 , Scalar(color[i])); - - } - - - - - - - int channel = 1; - int histSize = 256 ; - float range[] = { 0, 256 }; - const float* histRange[] = { range }; - Mat hist; - // we compute the histogram from the 0-th and 1-st channels - - calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, histRange, true, false); - Mat cumHist(hist.size(), hist.type()); - cumHist.at(0, 0) = hist.at(0, 0); - for (int i = 1; i < hist.rows; i++) - cumHist.at(i, 0) = cumHist.at(i - 1, 0) + hist.at(i, 0); - imwrite(fileName[0], img); - cout << "****************Maximal region************************\n"; - cout << "i\th\t\tsh\t\tq\n"; - cout << 0 << "\t" << hist.at(0, 0) << "\t\t" << cumHist.at(0, 0) << "\t\t\n"; - for (int i = 1; i < hist.rows-1 ; i++) - { - if (cumHist.at(i, 0)>0) - { - cout << i << "\t" << hist.at(i, 0) << "\t\t" << cumHist.at(i, 0) << "\t\t" << (cumHist.at(i + 1, 0) - cumHist.at(i, 0)) / cumHist.at(i, 0); - } - else - cout << i << "\t" << hist.at(i, 0) << "\t\t" << cumHist.at(i, 0) << "\t\t"; - cout << endl; - } - cout << 255 << "\t" << hist.at(255, 0) << "\t\t" << cumHist.at(255, 0) << "\t\t\n"; - cout << "****************Minimal region************************\n"; - cumHist.at(255, 0) = hist.at(255, 0); - for (int i = 254; i >= 0; i--) - cumHist.at(i, 0) = cumHist.at(i + 1, 0) + hist.at(i, 0); - cout << "Minimal region\ni\th\t\tsh\t\tq\n"; - cout << 255-255 << "\t" << hist.at(255, 0) << "\t\t" << cumHist.at(255, 0) << "\t\t\n"; - for (int i = 254; i>=0; i--) - { - if (cumHist.at(i, 0)>0) - { - cout << 255 - i << "\t" << i << "\t" << hist.at(i, 0) << "\t\t" << cumHist.at(i, 0) << "\t\t" << (cumHist.at(i + 1, 0) - cumHist.at(i, 0)) / cumHist.at(i, 0); - } - else - cout << 255 - i << "\t" << i << "\t" << hist.at(i, 0) << "\t\t" << cumHist.at(i, 0) << "\t\t"; - cout << endl; - } - // img = imread("C:/Users/laurent_2/Pictures/basketball1.png", IMREAD_GRAYSCALE); - - MSERParams pDefaultMSER; - // Descriptor array (BLOB or MSER) - vector typeDesc; - // Param array for BLOB - // Param array for MSER - vector pMSER; - vector::iterator itMSER; - - // Color palette - vector palette; - for (int i = 0; i<65536; i++) - palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); - help(); - - typeDesc.push_back("MSER"); - pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 1000; - pMSER.back().minArea = 1; - pMSER.back().maxArea = 180000; - pMSER.back().maxVariation = 1.701; - pMSER.back().minDiversity = 0; - pMSER.back().pass2Only = true; - itMSER = pMSER.begin(); - vector desMethCmp; - Ptr b; - String label; - // Descriptor loop - vector::iterator itDesc; - for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++) - { - vector keyImg1; - 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); - } - else - { - b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity); - b.dynamicCast()->setPass2Only(itMSER->pass2Only); - } - } - try { - // We can detect keypoint with detect method - vector keyImg; - vector zone; - vector> region; - Mat desc, result(img.rows, img.cols, CV_8UC3); - int nb = img.channels(); - - if (b.dynamicCast() != NULL) - { - Ptr sbd = b.dynamicCast(); - sbd->detectRegions(img, region, zone); - int i = 0; - result = Scalar(0, 0, 0); - for (vector>::iterator itr = region.begin(); itr != region.end(); itr++, i++) - { - for (vector ::iterator itp = region[i].begin(); itp != region[i].end(); itp+=2) - { - // all pixels belonging to region are red - result.at(itp->y, itp->x) = Vec3b(0, 0, 128); - } - } - i = 0; - for (vector::iterator r = zone.begin(); r != zone.end(); r++, i++) - { - // we draw a white rectangle which include all region pixels - rectangle(result, *r, Vec3b(255, 0, 0), 2); - } - } - namedWindow(*itDesc + label, WINDOW_AUTOSIZE); - imshow(*itDesc + label, result); - imshow("Original", img); - FileStorage fs(*itDesc + "_" + fileName[0] + ".xml", FileStorage::WRITE); - fs << *itDesc << keyImg; - waitKey(); - } - catch (Exception& e) - { - cout << "Feature : " << *itDesc << "\n"; - cout << e.msg << endl; - } - } - return; - } diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp new file mode 100644 index 0000000000..934817db20 --- /dev/null +++ b/samples/cpp/detect_mser.cpp @@ -0,0 +1,524 @@ +#include +#include "opencv2/core/opengl.hpp" + +#include +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN 1 +#define NOMINMAX 1 +#include +#endif +#if defined(_WIN64) +#include +#endif + +#if defined(__APPLE__) +#include +#include +#else +#include +#include +#endif + + + +using namespace std; +using namespace cv; + + +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 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) + { + delta = _delta; + minArea = _min_area; + maxArea = _max_area; + maxVariation = _max_variation; + minDiversity = _min_diversity; + maxEvolution = _max_evolution; + areaThreshold = _area_threshold; + minMargin = _min_margin; + edgeBlurSize = _edge_blur_size; + pass2Only = false; + } + + int delta; + int minArea; + int maxArea; + double maxVariation; + double minDiversity; + bool pass2Only; + + int maxEvolution; + double areaThreshold; + double minMargin; + int edgeBlurSize; +}; + +String Legende(MSERParams &pAct) +{ + String s=""; + String inf = static_cast(&(ostringstream() << pAct.minArea))->str(); + String sup = static_cast(&(ostringstream() << pAct.maxArea))->str(); + s = " Area[" + inf + "," + sup + "]"; + + 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; +} + + +const int win_width = 800; +const int win_height = 640; +bool rotateEnable=true; +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; + +struct DrawData + + { + ogl::Arrays arr; + ogl::Texture2D tex; + ogl::Buffer indices; + }; + +void draw(void* userdata); + +void draw(void* userdata) +{ + DrawData* data = static_cast(userdata); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(obsX, obsY, obsZ, 0, 0, .0, .0, 10.0, 0.0); + glTranslatef(tx,ty,0); + keyPressed = false; + ogl::render(data->arr, data->indices, ogl::TRIANGLES); +} + +static void onMouse(int event, int x, int y, int flags, void*) +{ + if (event == EVENT_RBUTTONDOWN) + { + prevX = x; + prevY = y; + } + if (event == EVENT_RBUTTONUP) + { + prevX = -1; + prevY = -1; + } + if (prevX != -1) + { + tx += float((x - prevX) / 100.0); + ty -= float((y - prevY) / 100.0); + prevX = x; + prevY = y; + } + if (event == EVENT_LBUTTONDOWN) + { + prevTheta = x; + prevPhi = y; + } + if (event == EVENT_LBUTTONUP) + { + prevTheta = -1000; + prevPhi = -1000; + } + if (prevTheta != -1000) + { + if (x - prevTheta<0) + { + thetaObs +=(float)0.02; + } + else if (x - prevTheta>0) + { + thetaObs -= (float)0.02; + } + if (y - prevPhi<0) + { + phiObs -= (float)0.02; + } + else if (y - prevPhi>0) + { + phiObs += (float)0.02; + } + prevTheta = x; + prevPhi = y; + } + if (event==EVENT_MOUSEWHEEL) + if (getMouseWheelDelta(flags)>0) + rObs += (float)0.1; + else + rObs -= (float)0.1; + float pi = (float)acos(-1.0); + if (thetaObs>pi) + { + thetaObs = -2 * pi + thetaObs; + } + if (thetaObs<-pi) + thetaObs = 2 * pi + thetaObs; + if (phiObs>pi / 2) + phiObs = pi / 2 - (float)0.0001; + if (phiObs<-pi / 2) + phiObs = -pi / 2 + (float)0.00001; + if (rObs<0) + rObs = 0; + +} + +void DrawOpenGLMSER(Mat img, Mat result) +{ + Mat imgGray; + if (img.type() != CV_8UC1) + 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 - 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 ; + } + } + + DrawData *data = new DrawData; + + data->arr.setVertexArray(vertex); + data->arr.setTexCoordArray(texCoords); + data->indices.copyFrom(indices); + data->tex.copyFrom(result); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (double)win_width / win_height, 0.0, 1000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + data->tex.bind(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glDisable(GL_CULL_FACE); + setOpenGlDrawCallback("OpenGL", draw, data); + + for (;;) + { + updateWindow("OpenGL"); + int key = waitKey(40); + if ((key & 0xff) == 27) + break; + if (key == 0x20) + rotateEnable = !rotateEnable; + float pi = (float)acos(-1); + + switch (key) { + case '5': + obsX = 0, obsY = 0, obsZ = -10; + thetaObs = -pi/2, phiObs = pi/2, rObs = 10; + tx=0;ty=0; + break; + case '4': + thetaObs += (float)0.1; + break; + case '6': + thetaObs -= (float)0.1; + break; + case '2': + phiObs -= (float).1; + break; + case '8': + phiObs += (float).1; + break; + case '+': + rObs -= (float).1; + break; + case '-': + rObs += (float).1; + break; + } + if (thetaObs>pi) + { + thetaObs = -2 * pi + thetaObs; + } + if (thetaObs<-pi) + thetaObs = 2 * pi + thetaObs; + if (phiObs>pi / 2) + phiObs = pi / 2 - (float)0.0001; + if (phiObs<-pi / 2) + phiObs = -pi / 2 + (float)0.00001; + if (rObs<0) + rObs = 0; + obsX = rObs*cos(thetaObs)*cos(phiObs); + obsY = rObs*sin(thetaObs)*cos(phiObs); + obsZ = rObs*sin(phiObs); + } + setOpenGlDrawCallback("OpenGL", 0, 0); + destroyAllWindows(); +} + +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++) + { + rectangle(img, Rect(p0, Size(width[i], width[i])), Scalar(color[i]), 1); + p0 += Point((width[i] - width[i + 1]) / 2, (width[i] - width[i + 1]) / 2); + floodFill(img, p0, Scalar(color[i])); + + } + int color2[] = { 81, 181, 161, 141, 121, 101, 91, 111, 171, 151, 141, 101, 221 }; + color = color2; + p0 = Point(200, 600); + for (int i = 0; i<13; i++) + { + circle(img, p0, width[i] / 2, Scalar(color[i]), 1); + floodFill(img, p0, Scalar(color[i])); + + } + int color3[] = { 175,75,95,115,135,155,165,145,85,105,115,156 }; + color = color3; + p0 = Point(410, 10); + for (int i = 0; i<13; i++) + { + rectangle(img, Rect(p0, Size(width[i], width[i])), Scalar(color[i]), 1); + p0 += Point((width[i] - width[i + 1]) / 2, (width[i] - width[i + 1]) / 2); + floodFill(img, p0, Scalar(color[i])); + + } + int color4[] = { 173,73,93,113,133,153,163,143,83,103,114,154 }; + color = color4; + + p0 = Point(600, 600); + for (int i = 0; i<13; i++) + { + circle(img, p0, width[i] / 2, Scalar(color[i]), 1); + floodFill(img, p0, Scalar(color[i])); + + } + int histSize = 256; + float range[] = { 0, 256 }; + const float* histRange[] = { range }; + Mat hist; + // we compute the histogram + + calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, histRange, true, false); + cout << "****************Maximal region************************\n"; + for (int i = 0; i < hist.rows ; i++) + { + if (hist.at(i, 0)!=0) + { + cout << "h" << i << "=\t" << hist.at(i, 0) << "\n"; + } + } + + return img; +} + +int main(int argc, char *argv[]) +{ + vector fileName; + Mat imgOrig,img; + Size blurSize(5,5); + if (argc==2) + { + fileName.push_back(argv[1]); + imgOrig = imread(fileName[0], IMREAD_GRAYSCALE); blur(imgOrig, img, blurSize); + + } + else + { + fileName.push_back("SyntheticImage.bmp"); + imgOrig = MakeSyntheticImage(); + 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++) + palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); + help(); + + 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; + 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; + 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; + Ptr b; + String label; + // Descriptor loop + vector::iterator itDesc; + Mat result(img.rows, img.cols, CV_8UC3); + for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++) + { + vector keyImg1; + 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 + { + b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity); + b.dynamicCast()->setPass2Only(itMSER->pass2Only); + label = Legende(*itMSER); + itMSER++; + } + } + if (img.type()==CV_8UC3) + { + img.copyTo(result); + } + else + { + vector plan; + plan.push_back(img); + plan.push_back(img); + plan.push_back(img); + merge(plan,result); + } + try + { + // We can detect regions using detectRegions method + 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 itp = region[i].begin(); itp != region[i].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 : "<