• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <opencv2/opencv.hpp>
2 #include <vector>
3 #include <map>
4 #include <iostream>
5 
6 using namespace std;
7 using namespace cv;
8 
9 
help()10 static void help()
11 {
12     cout << "\n This program demonstrates how to use BLOB to detect and filter region \n"
13         "Usage: \n"
14         "  ./detect_blob <image1(../data/detect_blob.png as default)>\n"
15         "Press a key when image window is active to change descriptor";
16 }
17 
18 
Legende(SimpleBlobDetector::Params & pAct)19 static String Legende(SimpleBlobDetector::Params &pAct)
20 {
21     String s = "";
22     if (pAct.filterByArea)
23     {
24         String inf = static_cast<ostringstream*>(&(ostringstream() << pAct.minArea))->str();
25         String sup = static_cast<ostringstream*>(&(ostringstream() << pAct.maxArea))->str();
26         s = " Area range [" + inf + " to  " + sup + "]";
27     }
28     if (pAct.filterByCircularity)
29     {
30         String inf = static_cast<ostringstream*>(&(ostringstream() << pAct.minCircularity))->str();
31         String sup = static_cast<ostringstream*>(&(ostringstream() << pAct.maxCircularity))->str();
32         if (s.length() == 0)
33             s = " Circularity range [" + inf + " to  " + sup + "]";
34         else
35             s += " AND Circularity range [" + inf + " to  " + sup + "]";
36     }
37     if (pAct.filterByColor)
38     {
39         String inf = static_cast<ostringstream*>(&(ostringstream() << (int)pAct.blobColor))->str();
40         if (s.length() == 0)
41             s = " Blob color " + inf;
42         else
43             s += " AND Blob color " + inf;
44     }
45     if (pAct.filterByConvexity)
46     {
47         String inf = static_cast<ostringstream*>(&(ostringstream() << pAct.minConvexity))->str();
48         String sup = static_cast<ostringstream*>(&(ostringstream() << pAct.maxConvexity))->str();
49         if (s.length() == 0)
50             s = " Convexity range[" + inf + " to  " + sup + "]";
51         else
52             s += " AND  Convexity range[" + inf + " to  " + sup + "]";
53     }
54     if (pAct.filterByInertia)
55     {
56         String inf = static_cast<ostringstream*>(&(ostringstream() << pAct.minInertiaRatio))->str();
57         String sup = static_cast<ostringstream*>(&(ostringstream() << pAct.maxInertiaRatio))->str();
58         if (s.length() == 0)
59             s = " Inertia ratio range [" + inf + " to  " + sup + "]";
60         else
61             s += " AND  Inertia ratio range [" + inf + " to  " + sup + "]";
62     }
63     return s;
64 }
65 
66 
67 
main(int argc,char * argv[])68 int main(int argc, char *argv[])
69 {
70     vector<String> fileName;
71     Mat img(600, 800, CV_8UC1);
72     if (argc == 1)
73     {
74         fileName.push_back("../data/detect_blob.png");
75     }
76     else if (argc == 2)
77     {
78         fileName.push_back(argv[1]);
79     }
80     else
81     {
82         help();
83         return(0);
84     }
85     img = imread(fileName[0], IMREAD_COLOR);
86     if (img.rows*img.cols <= 0)
87     {
88         cout << "Image " << fileName[0] << " is empty or cannot be found\n";
89         return(0);
90     }
91 
92     SimpleBlobDetector::Params pDefaultBLOB;
93     // This is default parameters for SimpleBlobDetector
94     pDefaultBLOB.thresholdStep = 10;
95     pDefaultBLOB.minThreshold = 10;
96     pDefaultBLOB.maxThreshold = 220;
97     pDefaultBLOB.minRepeatability = 2;
98     pDefaultBLOB.minDistBetweenBlobs = 10;
99     pDefaultBLOB.filterByColor = false;
100     pDefaultBLOB.blobColor = 0;
101     pDefaultBLOB.filterByArea = false;
102     pDefaultBLOB.minArea = 25;
103     pDefaultBLOB.maxArea = 5000;
104     pDefaultBLOB.filterByCircularity = false;
105     pDefaultBLOB.minCircularity = 0.9f;
106     pDefaultBLOB.maxCircularity = (float)1e37;
107     pDefaultBLOB.filterByInertia = false;
108     pDefaultBLOB.minInertiaRatio = 0.1f;
109     pDefaultBLOB.maxInertiaRatio = (float)1e37;
110     pDefaultBLOB.filterByConvexity = false;
111     pDefaultBLOB.minConvexity = 0.95f;
112     pDefaultBLOB.maxConvexity = (float)1e37;
113     // Descriptor array for BLOB
114     vector<String> typeDesc;
115     // Param array for BLOB
116     vector<SimpleBlobDetector::Params> pBLOB;
117     vector<SimpleBlobDetector::Params>::iterator itBLOB;
118     // Color palette
119     vector< Vec3b >  palette;
120     for (int i = 0; i<65536; i++)
121     {
122         palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand()));
123     }
124     help();
125 
126 
127     // This descriptor are going to be detect and compute BLOBS with 6 differents params
128     // Param for first BLOB detector we want all
129     typeDesc.push_back("BLOB");    // see http://docs.opencv.org/trunk/d0/d7a/classcv_1_1SimpleBlobDetector.html
130     pBLOB.push_back(pDefaultBLOB);
131     pBLOB.back().filterByArea = true;
132     pBLOB.back().minArea = 1;
133     pBLOB.back().maxArea = float(img.rows*img.cols);
134     // Param for second BLOB detector we want area between 500 and 2900 pixels
135     typeDesc.push_back("BLOB");
136     pBLOB.push_back(pDefaultBLOB);
137     pBLOB.back().filterByArea = true;
138     pBLOB.back().minArea = 500;
139     pBLOB.back().maxArea = 2900;
140     // Param for third BLOB detector we want only circular object
141     typeDesc.push_back("BLOB");
142     pBLOB.push_back(pDefaultBLOB);
143     pBLOB.back().filterByCircularity = true;
144     // Param for Fourth BLOB detector we want ratio inertia
145     typeDesc.push_back("BLOB");
146     pBLOB.push_back(pDefaultBLOB);
147     pBLOB.back().filterByInertia = true;
148     pBLOB.back().minInertiaRatio = 0;
149     pBLOB.back().maxInertiaRatio = (float)0.2;
150     // Param for fifth BLOB detector we want ratio inertia
151     typeDesc.push_back("BLOB");
152     pBLOB.push_back(pDefaultBLOB);
153     pBLOB.back().filterByConvexity = true;
154     pBLOB.back().minConvexity = 0.;
155     pBLOB.back().maxConvexity = (float)0.9;
156     // Param for six BLOB detector we want blob with gravity center color equal to 0 bug #4321 must be fixed
157     typeDesc.push_back("BLOB");
158     pBLOB.push_back(pDefaultBLOB);
159     pBLOB.back().filterByColor = true;
160     pBLOB.back().blobColor = 0;
161 
162     itBLOB = pBLOB.begin();
163     vector<double> desMethCmp;
164     Ptr<Feature2D> b;
165     String label;
166     // Descriptor loop
167     vector<String>::iterator itDesc;
168     for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++)
169     {
170         vector<KeyPoint> keyImg1;
171         if (*itDesc == "BLOB")
172         {
173             b = SimpleBlobDetector::create(*itBLOB);
174             label = Legende(*itBLOB);
175             itBLOB++;
176         }
177         try
178         {
179             // We can detect keypoint with detect method
180             vector<KeyPoint>  keyImg;
181             vector<Rect>  zone;
182             vector<vector <Point> >  region;
183             Mat     desc, result(img.rows, img.cols, CV_8UC3);
184             if (b.dynamicCast<SimpleBlobDetector>() != NULL)
185             {
186                 Ptr<SimpleBlobDetector> sbd = b.dynamicCast<SimpleBlobDetector>();
187                 sbd->detect(img, keyImg, Mat());
188                 drawKeypoints(img, keyImg, result);
189                 int i = 0;
190                 for (vector<KeyPoint>::iterator k = keyImg.begin(); k != keyImg.end(); k++, i++)
191                     circle(result, k->pt, (int)k->size, palette[i % 65536]);
192             }
193             namedWindow(*itDesc + label, WINDOW_AUTOSIZE);
194             imshow(*itDesc + label, result);
195             imshow("Original", img);
196             waitKey();
197         }
198         catch (Exception& e)
199         {
200             cout << "Feature : " << *itDesc << "\n";
201             cout << e.msg << endl;
202         }
203     }
204     return 0;
205 }
206