From 6b9e273f92daea694664057f125f277a8f46d8d7 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Tue, 5 May 2015 12:06:16 +0200 Subject: [PATCH 01/14] Essai examleBlob et MSER --- samples/cpp/BLOB_MSER.cpp | 215 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 samples/cpp/BLOB_MSER.cpp diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp new file mode 100644 index 000000000..0b1a19c02 --- /dev/null +++ b/samples/cpp/BLOB_MSER.cpp @@ -0,0 +1,215 @@ +#include +#include +#include + +using namespace std; +using namespace cv; + +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; + }; + + + +int main(int argc, char *argv[]) +{ + vector fileName; + if (argc == 1) + { + fileName.push_back("../data/forme.jpg"); + } + else if (argc == 2) + { + fileName.push_back(argv[1]); + } + else + { + help(); + return(0); + } + Mat imgOrig = imread(fileName[0], IMREAD_UNCHANGED),img; + if (imgOrig.rows*imgOrig.cols <= 0) + { + cout << "Image " << fileName[0] << " is empty or cannot be found\n"; + return(0); + } + GaussianBlur(imgOrig,img,Size(11,11),5,5); + SimpleBlobDetector::Params pDefaultBLOB; + // This is default parameters for SimpleBlobDetector + pDefaultBLOB.thresholdStep = 10; + pDefaultBLOB.minThreshold = 1; + 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.8f; + 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(); + MSERParams pDefaultMSER; + // Descriptor array (BLOB or MSER) + vector typeDesc; + // Param array for BLOB + vector pBLOB; + vector::iterator itBLOB; + // Param array for MSER + vector pMSER; + + // Color palette + vector palette; + for (int i=0;i<65536;i++) + palette.push_back(Vec3b(rand(),rand(),rand())); + help(); + // This descriptor are going to be detect and compute 4 BLOBS with 4 differents params + 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 = img.rows*img.cols; + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByArea = true; + pBLOB.back().maxArea = img.rows*img.cols; + pBLOB.back().filterByCircularity = true; + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByInertia = true; + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByColor = true; + pBLOB.back().blobColor = 60; + typeDesc.push_back("MSER"); + itBLOB=pBLOB.begin(); + vector desMethCmp; + Ptr b; + + // Descriptor loop + vector::iterator itDesc; + for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++) + { + vector keyImg1; + if (*itDesc == "BLOB"){ + b = SimpleBlobDetector::create(*itBLOB); + itBLOB++; + } + if (*itDesc == "MSER"){ + b = MSER::create(); + } + try { + // We can detect keypoint with detect method + vector keyImg; + vector zone; + vector> region; + Mat desc, result; + int nb = img.channels(); + if (img.channels() == 3) + { + img.copyTo(result); + } + else + { + vector plan; + plan.push_back(img); + plan.push_back(img); + plan.push_back(img); + merge(plan, result); + } + 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; + + for (vector::iterator r = zone.begin(); r != zone.end();r++,i++) + { + rectangle(result, *r, palette[i % 65536],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++) + { + + result.at(itp->y, itp->x) = Vec3b(0,0,0); + } + } + 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++) + { + + result.at(itp->y, itp->x) += palette[i % 65536]; + } + } + } + namedWindow(*itDesc , WINDOW_AUTOSIZE); + imshow(*itDesc, result); + imshow("Original", img); + FileStorage fs(*itDesc + "_" + fileName[0] + ".xml", FileStorage::WRITE); + fs<<*itDesc< Date: Wed, 6 May 2015 16:50:22 +0200 Subject: [PATCH 02/14] Example BLOB_MSER --- samples/cpp/BLOB_MSER.cpp | 113 +++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp index 0b1a19c02..b0206a1d2 100644 --- a/samples/cpp/BLOB_MSER.cpp +++ b/samples/cpp/BLOB_MSER.cpp @@ -9,7 +9,7 @@ static void help() { cout << "\n This program demonstrates how to use BLOB and MSER to detect region \n" "Usage: \n" - " ./BLOB_MSER \n" + " ./BLOB_MSER \n" "Press a key when image window is active to change descriptor"; } @@ -45,6 +45,53 @@ struct MSERParams 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() << 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; +} + int main(int argc, char *argv[]) @@ -52,7 +99,7 @@ int main(int argc, char *argv[]) vector fileName; if (argc == 1) { - fileName.push_back("../data/forme.jpg"); + fileName.push_back("../data/BLOB_MSER.bmp"); } else if (argc == 2) { @@ -69,11 +116,13 @@ int main(int argc, char *argv[]) cout << "Image " << fileName[0] << " is empty or cannot be found\n"; return(0); } - GaussianBlur(imgOrig,img,Size(11,11),5,5); + GaussianBlur(imgOrig,img,Size(11,11),0.1,0.1); + SimpleBlobDetector::Params pDefaultBLOB; + MSERParams pDefaultMSER; // This is default parameters for SimpleBlobDetector pDefaultBLOB.thresholdStep = 10; - pDefaultBLOB.minThreshold = 1; + pDefaultBLOB.minThreshold = 10; pDefaultBLOB.maxThreshold = 220; pDefaultBLOB.minRepeatability = 2; pDefaultBLOB.minDistBetweenBlobs = 10; @@ -83,7 +132,7 @@ int main(int argc, char *argv[]) pDefaultBLOB.minArea = 25; pDefaultBLOB.maxArea = 5000; pDefaultBLOB.filterByCircularity = false; - pDefaultBLOB.minCircularity = 0.8f; + pDefaultBLOB.minCircularity = 0.9f; pDefaultBLOB.maxCircularity = std::numeric_limits::max(); pDefaultBLOB.filterByInertia = false; pDefaultBLOB.minInertiaRatio = 0.1f; @@ -91,7 +140,6 @@ int main(int argc, char *argv[]) pDefaultBLOB.filterByConvexity = false; pDefaultBLOB.minConvexity = 0.95f; pDefaultBLOB.maxConvexity = std::numeric_limits::max(); - MSERParams pDefaultMSER; // Descriptor array (BLOB or MSER) vector typeDesc; // Param array for BLOB @@ -99,35 +147,58 @@ int main(int argc, char *argv[]) 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(rand(),rand(),rand())); help(); + typeDesc.push_back("MSER"); + pMSER.push_back(pDefaultMSER); + pMSER.back().minArea = 1; + pMSER.back().maxArea = img.rows*img.cols; + + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByColor = true; + pBLOB.back().blobColor = 255; // 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 = 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().maxArea = img.rows*img.cols; - pBLOB.back().filterByCircularity = 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; - typeDesc.push_back("BLOB"); + pBLOB.back().minInertiaRatio = 0; + pBLOB.back().maxInertiaRatio = 0.2; + // Param for Fourth BLOB detector we want ratio inertia + typeDesc.push_back("BLOB"); pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByColor = true; - pBLOB.back().blobColor = 60; - typeDesc.push_back("MSER"); - itBLOB=pBLOB.begin(); + pBLOB.back().filterByConvexity = true; + pBLOB.back().minConvexity = 0.; + pBLOB.back().maxConvexity = 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++) @@ -135,11 +206,14 @@ int main(int argc, char *argv[]) vector keyImg1; if (*itDesc == "BLOB"){ b = SimpleBlobDetector::create(*itBLOB); + label=Legende(*itBLOB); + itBLOB++; } if (*itDesc == "MSER"){ - b = MSER::create(); - } + b = MSER::create(itMSER->delta, itMSER->minArea,itMSER->maxArea,itMSER->maxVariation,itMSER->minDiversity,itMSER->maxEvolution, + itMSER->areaThreshold,itMSER->minMargin,itMSER->edgeBlurSize); + } try { // We can detect keypoint with detect method vector keyImg; @@ -167,7 +241,6 @@ int main(int argc, char *argv[]) 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) { @@ -194,12 +267,12 @@ int main(int argc, char *argv[]) for (vector ::iterator itp = region[i].begin(); itp != region[i].end(); itp++) { - result.at(itp->y, itp->x) += palette[i % 65536]; + result.at(itp->y, itp->x) = Vec3b(0,255,255); } } } - namedWindow(*itDesc , WINDOW_AUTOSIZE); - imshow(*itDesc, result); + namedWindow(*itDesc+label , WINDOW_AUTOSIZE); + imshow(*itDesc + label, result); imshow("Original", img); FileStorage fs(*itDesc + "_" + fileName[0] + ".xml", FileStorage::WRITE); fs<<*itDesc< Date: Thu, 7 May 2015 11:52:06 +0200 Subject: [PATCH 03/14] example BLOB_MSER and fixed bug in blobdetector --- modules/features2d/src/blobdetector.cpp | 4 +- samples/cpp/BLOB_MSER.cpp | 65 +++++++++++-------------- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/modules/features2d/src/blobdetector.cpp b/modules/features2d/src/blobdetector.cpp index daf1d3644..e53eff35a 100644 --- a/modules/features2d/src/blobdetector.cpp +++ b/modules/features2d/src/blobdetector.cpp @@ -266,6 +266,8 @@ void SimpleBlobDetectorImpl::findBlobs(InputArray _image, InputArray _binaryImag continue; } + if(moms.m00 == 0.0) + continue; center.location = Point2d(moms.m10 / moms.m00, moms.m01 / moms.m00); if (params.filterByColor) @@ -286,8 +288,6 @@ void SimpleBlobDetectorImpl::findBlobs(InputArray _image, InputArray _binaryImag center.radius = (dists[(dists.size() - 1) / 2] + dists[dists.size() / 2]) / 2.; } - if(moms.m00 == 0.0) - continue; centers.push_back(center); diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp index b0206a1d2..41412baba 100644 --- a/samples/cpp/BLOB_MSER.cpp +++ b/samples/cpp/BLOB_MSER.cpp @@ -110,13 +110,12 @@ int main(int argc, char *argv[]) help(); return(0); } - Mat imgOrig = imread(fileName[0], IMREAD_UNCHANGED),img; - if (imgOrig.rows*imgOrig.cols <= 0) + Mat img = imread(fileName[0], IMREAD_GRAYSCALE); + if (img.rows*img.cols <= 0) { cout << "Image " << fileName[0] << " is empty or cannot be found\n"; return(0); } - GaussianBlur(imgOrig,img,Size(11,11),0.1,0.1); SimpleBlobDetector::Params pDefaultBLOB; MSERParams pDefaultMSER; @@ -154,15 +153,23 @@ int main(int argc, char *argv[]) for (int i=0;i<65536;i++) palette.push_back(Vec3b(rand(),rand(),rand())); help(); + typeDesc.push_back("MSER"); pMSER.push_back(pDefaultMSER); - pMSER.back().minArea = 1; - pMSER.back().maxArea = img.rows*img.cols; - + pMSER.back().delta=0; + pMSER.back().minArea = 25; + pMSER.back().maxArea = 80000; + pMSER.back().maxVariation= 0.5; + pMSER.back().minDiversity=0.8; // variation de taille entre deux seuillages ? + pMSER.back().areaThreshold= 200; + pMSER.back().maxEvolution = 1.01; + pMSER.back().minMargin=0.003; + pMSER.back().edgeBlurSize= 5; typeDesc.push_back("BLOB"); pBLOB.push_back(pDefaultBLOB); pBLOB.back().filterByColor = true; - pBLOB.back().blobColor = 255; + 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 @@ -211,28 +218,20 @@ int main(int argc, char *argv[]) itBLOB++; } if (*itDesc == "MSER"){ - b = MSER::create(itMSER->delta, itMSER->minArea,itMSER->maxArea,itMSER->maxVariation,itMSER->minDiversity,itMSER->maxEvolution, - itMSER->areaThreshold,itMSER->minMargin,itMSER->edgeBlurSize); + b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity, itMSER->maxEvolution, + itMSER->areaThreshold, itMSER->minMargin, itMSER->edgeBlurSize); + b.dynamicCast()->setPass2Only(true); + //b = MSER::create(); } try { // We can detect keypoint with detect method vector keyImg; vector zone; vector> region; - Mat desc, result; + Mat desc, result(img.rows,img.cols,CV_8UC3); int nb = img.channels(); - if (img.channels() == 3) - { - img.copyTo(result); - } - else - { - vector plan; - plan.push_back(img); - plan.push_back(img); - plan.push_back(img); - merge(plan, result); - } + + if (b.dynamicCast() != NULL) { Ptr sbd = b.dynamicCast(); @@ -245,32 +244,24 @@ int main(int argc, char *argv[]) if (b.dynamicCast() != NULL) { Ptr sbd = b.dynamicCast(); - sbd->detectRegions(img, region, zone); + sbd->detectRegions(img, region, zone); int i = 0; for (vector::iterator r = zone.begin(); r != zone.end();r++,i++) { - rectangle(result, *r, palette[i % 65536],2); + // we draw a white rectangle which include all region pixels + rectangle(result, *r, Vec3b(255, 255, 255), 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++) - { - - result.at(itp->y, itp->x) = Vec3b(0,0,0); - } - } - 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++) - { - - result.at(itp->y, itp->x) = Vec3b(0,255,255); - } + // 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); From 9e97d7b4db0fb0cb0e12b9793e02f7e7225e652a Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 9 May 2015 08:44:18 +0200 Subject: [PATCH 04/14] Etude de MSER --- samples/cpp/BLOB_MSER.cpp | 222 +++++++++++++++++++++++++++++++++----- 1 file changed, 198 insertions(+), 24 deletions(-) diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp index 41412baba..c1854bae5 100644 --- a/samples/cpp/BLOB_MSER.cpp +++ b/samples/cpp/BLOB_MSER.cpp @@ -1,10 +1,13 @@ #include #include +#include #include 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" @@ -65,7 +68,7 @@ String Legende(SimpleBlobDetector::Params &pAct) } if (pAct.filterByColor) { - String inf = static_cast(&(ostringstream() << pAct.blobColor))->str(); + String inf = static_cast(&(ostringstream() << (int)pAct.blobColor))->str(); if (s.length() == 0) s = " Blob color " + inf; else @@ -96,11 +99,14 @@ String Legende(SimpleBlobDetector::Params &pAct) int main(int argc, char *argv[]) { + 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]); @@ -110,7 +116,7 @@ int main(int argc, char *argv[]) help(); return(0); } - Mat img = imread(fileName[0], IMREAD_GRAYSCALE); + img = imread(fileName[0], IMREAD_UNCHANGED); if (img.rows*img.cols <= 0) { cout << "Image " << fileName[0] << " is empty or cannot be found\n"; @@ -151,20 +157,17 @@ int main(int argc, char *argv[]) // Color palette vector palette; for (int i=0;i<65536;i++) - palette.push_back(Vec3b(rand(),rand(),rand())); + palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); help(); - typeDesc.push_back("MSER"); +/* typeDesc.push_back("MSER"); pMSER.push_back(pDefaultMSER); - pMSER.back().delta=0; - pMSER.back().minArea = 25; - pMSER.back().maxArea = 80000; - pMSER.back().maxVariation= 0.5; - pMSER.back().minDiversity=0.8; // variation de taille entre deux seuillages ? - pMSER.back().areaThreshold= 200; - pMSER.back().maxEvolution = 1.01; - pMSER.back().minMargin=0.003; - pMSER.back().edgeBlurSize= 5; + 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; @@ -176,7 +179,7 @@ int main(int argc, char *argv[]) pBLOB.push_back(pDefaultBLOB); pBLOB.back().filterByArea = true; pBLOB.back().minArea = 1; - pBLOB.back().maxArea = img.rows*img.cols; + 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); @@ -192,13 +195,13 @@ int main(int argc, char *argv[]) pBLOB.push_back(pDefaultBLOB); pBLOB.back().filterByInertia = true; pBLOB.back().minInertiaRatio = 0; - pBLOB.back().maxInertiaRatio = 0.2; + 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 = 0.9; + pBLOB.back().maxConvexity = (float)0.9; itBLOB = pBLOB.begin(); @@ -218,9 +221,17 @@ int main(int argc, char *argv[]) itBLOB++; } if (*itDesc == "MSER"){ - b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity, itMSER->maxEvolution, - itMSER->areaThreshold, itMSER->minMargin, itMSER->edgeBlurSize); - b.dynamicCast()->setPass2Only(true); + 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 { @@ -229,7 +240,6 @@ int main(int argc, char *argv[]) vector zone; vector> region; Mat desc, result(img.rows,img.cols,CV_8UC3); - int nb = img.channels(); if (b.dynamicCast() != NULL) @@ -246,11 +256,11 @@ int main(int argc, char *argv[]) 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, 255, 255), 2); + rectangle(result, *r, Vec3b(255, 0, 0), 2); } i=0; for (vector>::iterator itr = region.begin(); itr != region.end(); itr++, i++) @@ -277,3 +287,167 @@ int main(int argc, char *argv[]) } return 0; } + + + + +void Example_MSER(vector &fileName) +{ + Mat img(600, 800, CV_8UC1); + fileName.push_back("SyntheticImage.bmp"); + map val; + int fond = 255; + img = Scalar(fond); + val[fond] = 1; + Point p[] = { Point(img.cols / 4, img.rows / 4), Point(3 * img.cols / 4, img.rows / 4) }; + for (int j = 0; j<1; j++) + { + for (int i = 1; i(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"; + for (map::iterator it = val.begin(); it != val.end(); it++) + { + cout << "h" << it->first << "=\t" << hist.at(it->first, 0) << "\t" << cumHist.at(it->first, 0) << "\t\t"; + if (it->first <= 254 && it->first >= 1) + { + cout << (cumHist.at(it->first + 1, 0) - cumHist.at(it->first - 1, 0)) / cumHist.at(it->first, 0); + } + cout << endl; + } + 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); + map::iterator it = val.end(); + for (it--; it != val.begin(); it--) + { + cout << "h" << it->first << "=\t" << hist.at(it->first, 0) << "\t" << cumHist.at(it->first, 0) << "\t\t"; + if (it->first <= 254 && it->first >= 1) + { + cout << (cumHist.at(it->first - 1, 0) - cumHist.at(it->first + 1, 0)) / cumHist.at(it->first, 0); + } + 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 = 1; + pMSER.back().minArea = 1; + pMSER.back().maxArea = 180000; + pMSER.back().maxVariation = 500; + 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); + b.dynamicCast()->setPass2Only(itMSER->pass2Only); + } + else + { + b = MSER::create(itMSER->delta, itMSER->minArea, itMSER->maxArea, itMSER->maxVariation, itMSER->minDiversity); + } + } + 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 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 << keyImg; + waitKey(); + } + catch (Exception& e) + { + cout << "Feature : " << *itDesc << "\n"; + cout << e.msg << endl; + } + } + return; + } From e7fcffeeadcdb2d5c77051455736ce4fc5bae790 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Mon, 11 May 2015 12:48:18 +0200 Subject: [PATCH 05/14] =?UTF-8?q?Exxemple=20MSER=20et=20BLOB=20s=C3=A9par?= =?UTF-8?q?=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/cpp/BLOB_MSER.cpp | 114 ++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 47 deletions(-) diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp index c1854bae5..69446c669 100644 --- a/samples/cpp/BLOB_MSER.cpp +++ b/samples/cpp/BLOB_MSER.cpp @@ -293,38 +293,52 @@ int main(int argc, char *argv[]) void Example_MSER(vector &fileName) { - Mat img(600, 800, CV_8UC1); + Mat img(800, 800, CV_8UC1); fileName.push_back("SyntheticImage.bmp"); map val; - int fond = 255; + int fond = 0; img = Scalar(fond); val[fond] = 1; - Point p[] = { Point(img.cols / 4, img.rows / 4), Point(3 * img.cols / 4, img.rows / 4) }; - for (int j = 0; j<1; j++) - { - for (int i = 1; i &fileName) cumHist.at(i, 0) = cumHist.at(i - 1, 0) + hist.at(i, 0); imwrite(fileName[0], img); cout << "****************Maximal region************************\n"; - for (map::iterator it = val.begin(); it != val.end(); it++) + 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++) { - cout << "h" << it->first << "=\t" << hist.at(it->first, 0) << "\t" << cumHist.at(it->first, 0) << "\t\t"; - if (it->first <= 254 && it->first >= 1) + if (cumHist.at(i, 0)>0) { - cout << (cumHist.at(it->first + 1, 0) - cumHist.at(it->first - 1, 0)) / cumHist.at(it->first, 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); - map::iterator it = val.end(); - for (it--; it != val.begin(); it--) + 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--) { - cout << "h" << it->first << "=\t" << hist.at(it->first, 0) << "\t" << cumHist.at(it->first, 0) << "\t\t"; - if (it->first <= 254 && it->first >= 1) + if (cumHist.at(i, 0)>0) { - cout << (cumHist.at(it->first - 1, 0) - cumHist.at(it->first + 1, 0)) / cumHist.at(it->first, 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); @@ -380,10 +400,10 @@ void Example_MSER(vector &fileName) typeDesc.push_back("MSER"); pMSER.push_back(pDefaultMSER); - pMSER.back().delta = 1; + pMSER.back().delta = 1000; pMSER.back().minArea = 1; pMSER.back().maxArea = 180000; - pMSER.back().maxVariation = 500; + pMSER.back().maxVariation = 1.701; pMSER.back().minDiversity = 0; pMSER.back().pass2Only = true; itMSER = pMSER.begin(); @@ -400,11 +420,11 @@ void Example_MSER(vector &fileName) { 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.dynamicCast()->setPass2Only(itMSER->pass2Only); } } try { @@ -421,21 +441,21 @@ void Example_MSER(vector &fileName) 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+=2) { - 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); - } } } + 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); From 06b0fa6fc226f5d4c382a59404973192abbe3074 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Wed, 13 May 2015 18:03:58 +0200 Subject: [PATCH 06/14] BLOB_MSER avec opengl --- samples/cpp/BLOB_MSER.cpp | 100 +++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/samples/cpp/BLOB_MSER.cpp b/samples/cpp/BLOB_MSER.cpp index 69446c669..37c00237d 100644 --- a/samples/cpp/BLOB_MSER.cpp +++ b/samples/cpp/BLOB_MSER.cpp @@ -1,11 +1,30 @@ #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() @@ -96,10 +115,84 @@ String Legende(SimpleBlobDetector::Params &pAct) } +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); @@ -339,6 +432,11 @@ void Example_MSER(vector &fileName) } + + + + + int channel = 1; int histSize = 256 ; float range[] = { 0, 256 }; From 68e9d19743047b9a9cb4fc37fe0e645eac895f67 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 16 May 2015 18:59:22 +0200 Subject: [PATCH 07/14] 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 37c00237d..000000000 --- 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 000000000..934817db2 --- /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 : "< Date: Sat, 16 May 2015 19:29:12 +0200 Subject: [PATCH 08/14] trailing whitespace and some bracket --- samples/cpp/detect_mser.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index 934817db2..8631cb7e2 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -34,7 +34,7 @@ static void help() " ./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 { @@ -158,7 +158,7 @@ static void onMouse(int event, int x, int y, int flags, void*) prevPhi = -1000; } if (prevTheta != -1000) - { + { if (x - prevTheta<0) { thetaObs +=(float)0.02; @@ -179,23 +179,33 @@ static void onMouse(int event, int x, int y, int flags, void*) 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); + } + 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; + } } @@ -360,17 +370,15 @@ Mat MakeSyntheticImage() 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 - + // 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++) @@ -478,7 +486,7 @@ int main(int argc, char *argv[]) plan.push_back(img); merge(plan,result); } - try + try { // We can detect regions using detectRegions method vector keyImg; @@ -518,7 +526,3 @@ int main(int argc, char *argv[]) } return 0; } - - - - From 187ab0ca6147ff75da5e08537f5fb93f8e0e6b84 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 16 May 2015 19:59:59 +0200 Subject: [PATCH 09/14] include cvconfig.h to use constant HAVE_OPENGL --- samples/cpp/detect_mser.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index 8631cb7e2..c2d69a93c 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -1,9 +1,11 @@ #include #include "opencv2/core/opengl.hpp" +#include #include #include #include +#ifdef HAVE_OPENGL #ifdef WIN32 #define WIN32_LEAN_AND_MEAN 1 #define NOMINMAX 1 @@ -20,7 +22,7 @@ #include #include #endif - +#endif using namespace std; @@ -107,6 +109,7 @@ float obsX = (float)0, obsY = (float)0, obsZ = (float)-10, tx = (float)0, ty = ( float thetaObs = (float)-1.570, phiObs = (float)1.570, rObs = (float)10; int prevX=-1,prevY=-1,prevTheta=-1000,prevPhi=-1000; +#ifdef HAVE_OPENGL struct DrawData { @@ -208,9 +211,11 @@ static void onMouse(int event, int x, int y, int flags, void*) } } +#endif void DrawOpenGLMSER(Mat img, Mat result) { +#ifdef HAVE_OPENGL Mat imgGray; if (img.type() != CV_8UC1) cvtColor(img, imgGray, COLOR_BGR2GRAY); @@ -323,6 +328,7 @@ void DrawOpenGLMSER(Mat img, Mat result) } setOpenGlDrawCallback("OpenGL", 0, 0); destroyAllWindows(); +#endif } Mat MakeSyntheticImage() From 546f70a6f0b4bdac59417bbdbf0a1cde0277f20f Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 16 May 2015 21:01:31 +0200 Subject: [PATCH 10/14] some warnings and errors --- samples/cpp/detect_mser.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index c2d69a93c..36f543d4f 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -34,7 +34,7 @@ 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"; } @@ -70,7 +70,7 @@ struct MSERParams int edgeBlurSize; }; -String Legende(MSERParams &pAct) +static String Legende(MSERParams &pAct) { String s=""; String inf = static_cast(&(ostringstream() << pAct.minArea))->str(); @@ -118,9 +118,8 @@ struct DrawData ogl::Buffer indices; }; -void draw(void* userdata); -void draw(void* userdata) +static void draw(void* userdata) { DrawData* data = static_cast(userdata); glMatrixMode(GL_MODELVIEW); @@ -213,7 +212,7 @@ static void onMouse(int event, int x, int y, int flags, void*) } #endif -void DrawOpenGLMSER(Mat img, Mat result) +static void DrawOpenGLMSER(Mat img, Mat result) { #ifdef HAVE_OPENGL Mat imgGray; @@ -331,7 +330,7 @@ void DrawOpenGLMSER(Mat img, Mat result) #endif } -Mat MakeSyntheticImage() +static Mat MakeSyntheticImage() { Mat img(800, 800, CV_8UC1); map val; @@ -497,7 +496,7 @@ int main(int argc, char *argv[]) // We can detect regions using detectRegions method vector keyImg; vector zone; - vector> region; + vector > region; Mat desc; if (b.dynamicCast() != NULL) @@ -507,7 +506,7 @@ int main(int argc, char *argv[]) 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++, i++) { for (vector ::iterator itp = region[i].begin(); itp != region[i].end(); itp ++) { From 268283ff16c928c9bbd64cc25274ca33389b5042 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Sat, 16 May 2015 22:54:53 +0200 Subject: [PATCH 11/14] suppress android and mac warnings --- samples/cpp/detect_mser.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index 36f543d4f..2538c81b1 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -1,6 +1,6 @@ #include #include "opencv2/core/opengl.hpp" -#include +#include "cvconfig.h" #include #include @@ -212,9 +212,9 @@ static void onMouse(int event, int x, int y, int flags, void*) } #endif +#ifdef HAVE_OPENGL static void DrawOpenGLMSER(Mat img, Mat result) { -#ifdef HAVE_OPENGL Mat imgGray; if (img.type() != CV_8UC1) cvtColor(img, imgGray, COLOR_BGR2GRAY); @@ -327,8 +327,8 @@ static void DrawOpenGLMSER(Mat img, Mat result) } setOpenGlDrawCallback("OpenGL", 0, 0); destroyAllWindows(); -#endif } +#endif static Mat MakeSyntheticImage() { @@ -526,7 +526,9 @@ int main(int argc, char *argv[]) cout << "Feature : " << *itDesc << "\n"; cout << e.msg << endl; } - DrawOpenGLMSER(img,result); +#ifdef HAVE_OPENGL + DrawOpenGLMSER(img, result); +#endif waitKey(); } return 0; From a6a0fc5b216651e17a7fae92df0a3d53fa40968b Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Thu, 21 May 2015 14:01:11 +0200 Subject: [PATCH 12/14] replace "cvconfig.h" it with "opencv2/cvconfig.h". --- samples/cpp/detect_mser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index 2538c81b1..796cfa804 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -1,6 +1,6 @@ #include #include "opencv2/core/opengl.hpp" -#include "cvconfig.h" +#include "opencv2/cvconfig.h" #include #include From b116d6c6e87fa3413a174c29917ba801064eb8bc Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Thu, 21 May 2015 14:57:49 +0200 Subject: [PATCH 13/14] use ifndef HAVE_GTK --- samples/cpp/detect_mser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index 796cfa804..aa3c59e9f 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -1,6 +1,10 @@ #include #include "opencv2/core/opengl.hpp" +#ifndef HAVE_GTK +#include "cvconfig.h" +#else #include "opencv2/cvconfig.h" +#endif #include #include From b20401348347742ab7e20761d0f686b7bdb1f3e0 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Thu, 21 May 2015 20:22:57 +0200 Subject: [PATCH 14/14] back to #include "opencv2/cvconfig.h" --- samples/cpp/detect_mser.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/cpp/detect_mser.cpp b/samples/cpp/detect_mser.cpp index aa3c59e9f..796cfa804 100644 --- a/samples/cpp/detect_mser.cpp +++ b/samples/cpp/detect_mser.cpp @@ -1,10 +1,6 @@ #include #include "opencv2/core/opengl.hpp" -#ifndef HAVE_GTK -#include "cvconfig.h" -#else #include "opencv2/cvconfig.h" -#endif #include #include