contour line: blue color
convex hull line: red color
step 1:
point 1(light blue) represents a start point, point 2(green) is end point, and point 3 (red) is defect size which is defined as the distance between light blue color line and red cicular point.
step 2:
step 3:
step 4:
---------------------------------
Now I am going to show you three different sizes of star logos, which are proportional to their defect sizes.
figure 0 is a large size logo, and its defect size is about 6984.
figure 1 is the medium one, and its defect size is 4403.
figure 2 is the smallest one, and its defect size is 1838.
-----------------------------------
A defect size threshold is applied to limit the number of red points. For example, if the defect size threshold is set to 30,000, then the small defect size areas are neglected accordingly. Only four red points are reserved, and the geographical relationships of these red points respresent significant features of gesture. By utilizing SVM algorithm or k-means clustering method, gesture recognition will be implemented.
------------------------------
In this case, the defect size threshold is set to 10,000.
Good features points(red ones) are extracted well.
1: vector<vector<Point>> contours;
2: vector<Vec4i> hierarchy;
3:
4: RNG rng(clock());
5:
6: findContours(imgBW, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
7:
8: vector<vector<Point>> hull(contours.size());
9:
10: imgSrc.copyTo(imgDst);
11:
12:
13: for (int i = 0; i < contours.size(); i++) {
14:
15:
16: if (isContourConvex(contours[i]) || contours[i].size()<3) continue;
17: convexHull(Mat(contours[i]), hull[i], false);
18: vector<int> convexHull_IntIdx;
19: vector<Vec4i> defects;
20:
21: cout << "contour # " << i << endl;
22: imgMask = Mat::zeros(imgSrc.size(), CV_8UC1);
23: drawContours(imgMask, contours, i, Scalar(255), -1);
24: Mat imgROI;
25: imgSrc.copyTo(imgROI, imgMask);
26: Scalar color1 = Scalar(255, 0, 0);
27: drawContours(imgROI, contours, i, color1, 2, 8, vector<Vec4i>(), 0, Point());
28: Scalar color2 = Scalar(0, 0, 255);
29: drawContours(imgROI, hull, i, color2, 2, 8, vector<Vec4i>(), 0, Point());
30: string name = std::to_string(i);
31: imshow(name, imgROI);
32: waitKey(0);
33:
34: if (contours[i].size() >=3)
35: {
36: convexHull(contours[i], convexHull_IntIdx, true);
37: convexityDefects(contours[i], convexHull_IntIdx, defects);
38: for (int j = 0; j< defects.size(); ++j)
39: {
40: //cout << "defects[j]" << defects[j] << endl;
41: Matx<int, 4, 1> defectVector = defects[j];
42: vector<Point> contours1 = contours[i];
43: Point point1 = contours1[defectVector.val[0]];// start point
44: Point point2 = contours1[defectVector.val[1]];// end point
45: Point point3 = contours1[defectVector.val[2]];// top point
46: float dist = defectVector.val[3];
47: cout << "point1 = " << point1 << endl;
48: cout << "point2 = " << point2 << endl;
49: cout << "point3 = " << point3 << endl;
50: cout << "defect size = " << dist << endl;
51: //printf("dist: %f \n", dist);
52: if ( defectVector.val[3] <= 10000 ) { continue; } // skip defects that are shorter than 100 pixel
53: circle(imgROI, point1, 8, Scalar(255, 255, 0), -1, CV_AA);
54: circle(imgROI, point2, 8, Scalar(0, 255, 0), -1, CV_AA);
55: circle(imgROI, point3, 8, Scalar(0, 0, 255), -1, CV_AA);
56: line(imgROI, point1, point2, Scalar(255, 255, 0), 2, 8);
57: line(imgROI, point2, point3, Scalar(0, 255, 255), 2, 8);
58: line(imgROI, point3, point1, Scalar(255, 0, 255), 2, 8);
59: string name = std::to_string(i);
60: imshow(name, imgROI);
61: waitKey(0);
62: }
63: }
References:
留言列表