我是靠谱客的博主 醉熏鸡,这篇文章主要介绍凹点检测研究,现在分享给大家,希望可以做个参考。

复制代码
1
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include"myFuc.h" RNG rng; int bSums(Mat &src); int main() { Mat src = imread("bw_0034.png"); if (!src.data){ printf("error!n"); return false; } Mat Clonesrc = Mat::zeros(src.size(), CV_8UC3); Mat drawing = Mat::zeros(src.size(), CV_8UC3); Mat draw_Hull = Mat::zeros(src.size(), CV_8UC1); Mat MN; cvtColor(src, src, COLOR_RGB2GRAY); Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); morphologyEx(src, src, MORPH_OPEN, element, Point(-1, -1), 1); imshow("【开运算后】", src); Mat dst = src.clone(); vector<vector<Point> > contours; vector<Vec4i> hierarchy; findContours(src, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));//找出图像的轮廓 vector<vector<Point> >hull(contours.size()); vector<vector<int>> hullsI(contours.size()); vector<vector<Vec4i>> defects(contours.size()); for (size_t i = 0; i < contours.size(); i++) { convexHull(Mat(contours[i]), hull[i], false); // find int type hull convexHull(Mat(contours[i]), hullsI[i], false); // get convexity defects myconvexityDefects(Mat(contours[i]), hullsI[i], defects[i]); cout << "一共" << hull[i].size() << endl; drawContours(Clonesrc, contours, i, Scalar(255, 255, 255), FILLED, 8, vector<Vec4i>(), 0, Point()); cout << "轮廓:" << i << " " << endl; //cout << "中第:" << contours[i] //vector<Point>MMMat(contours[i].size()); // //MMMat = hull[i] - contours[i]; //Mat points = contours[i].getMat(); //int npoints = points.checkVector(2, CV_32S); for (size_t j = 0; j <hull[i].size(); j++) { cout << "点:" << j << "= "; //Scalar color = Scalar(rng.uniform(0, 255)); Scalar color = Scalar(j + 50, 0, 0); circle(Clonesrc, hull[i][j], 1, color, 2); cout << hull[i][j].x << "," << hull[i][j].y << " "; //circle(Clonesrc, hullsI[i][j], 1, Scalar(255, 0, 100), 2); cout << hullsI[i][j] << endl; } cout << "有缺陷的区域" << defects[i].size() << endl; vector<Vec4i>::iterator d = defects[i].begin(); int depth = 0; while (d != defects[i].end()) { Vec4i& v = (*d); int faridx = v[2]; Point ptFar(contours[i][faridx]); /*cout << "点:" << j << "= "; cout << defects[i][j] << " " << endl;*/ int startidx = v[0]; Point ptStart(contours[i][startidx]); // point of the contour where the defect begins int endidx = v[1]; Point ptEnd(contours[i][endidx]); // point of the contour where the defect ends depth = v[3] / 256; cout << ptStart.x << "," << ptStart.y << " "; cout << ptFar.x << "," << ptFar.y << " "; cout << ptEnd.x << "," << ptEnd.y << " "; cout << depth << endl; if (depth>0) { circle(drawing, ptFar, 1, Scalar(0, 0, 255), 2); drawContours(drawing, contours, i, Scalar(255, 255, 255), FILLED, 8, vector<Vec4i>(), 0, Point()); char tam[100]; sprintf_s(tam, "%d", depth); putText(drawing, tam, Point(ptFar.x-3, ptFar.y-20), FONT_HERSHEY_SIMPLEX, 0.4, Scalar(255, 0, 255), 1); } d++; } drawContours(draw_Hull, hull, i, Scalar(255, 255, 255), FILLED, 8, vector<Vec4i>(), 0, Point()); } MN = draw_Hull - dst; imshow("【凸集0】", MN); vector<vector<Point> > Contours; vector<Vec4i> Hierarchy; findContours(MN, Contours, Hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));//找出图像的轮廓 Mat drawing0 = Mat::zeros(MN.size(), CV_8UC1); int AA = 0; for (unsigned int i = 0; i < Contours.size(); i++) { Scalar color = Scalar(255, 255, 255); drawContours(drawing0, Contours, i, color, FILLED, 8, vector<Vec4i>(), 0, Point()); AA = bSums(drawing0); cout << "第" << i << "个凸集:" << AA << endl; drawing0 = Mat::zeros(MN.size(), CV_8UC1); } imshow("【凸集1】", drawing0); imshow("【效果图】", Clonesrc); imshow("【凸包缺陷及最远点图】", drawing); Mat element1 = getStructuringElement(MORPH_RECT, Size(2, 2), Point(-1, -1)); morphologyEx(MN, MN, MORPH_OPEN, element1, Point(-1, -1), 1); vector<vector<Point>> KContours; vector<Vec4i> KHierarchy; findContours(MN, KContours, KHierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); Mat drawing1 = Mat::zeros(MN.size(), CV_8UC1); for (unsigned int i = 0; i < KContours.size(); i++) { Scalar color = Scalar(255, 255, 255); drawContours(drawing0,KContours, i, color, FILLED, 8, vector<Vec4i>(), 0, Point()); drawContours(drawing1, KContours, i, color, FILLED, 8, vector<Vec4i>(), 0, Point()); AA = bSums(drawing0); cout << "第" << i << "个凸集:" << AA << endl; drawing0 = Mat::zeros(MN.size(), CV_8UC1); } imshow("【凸集2】", drawing1); //int mdepth = 0; //int depth = 0; //Mat drawing = Mat::zeros(src.size(), CV_8UC3); //for (unsigned int i = 0; i < contours.size(); i++) //{ // Scalar color1 = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); // Scalar color = Scalar(255, 0, 0); // drawContours(drawing, contours, i, color1, FILLED, 8, vector<Vec4i>(), 0, Point()); // drawContours(drawing, hull, i, color, FILLED, 8, vector<Vec4i>(), 0, Point()); // vector<Vec4i>::iterator d = defects[i].begin(); // vector<Point>keypoint; // while (d != defects[i].end()) // { // Vec4i& v = (*d); // int startidx = v[0]; // Point ptStart(contours[i][startidx]); // point of the contour where the defect begins // int endidx = v[1]; // Point ptEnd(contours[i][endidx]); // point of the contour where the defect ends // int faridx = v[2]; // Point ptFar(contours[i][faridx]);// the farthest from the convex hull point within the defect // } //} waitKey(0); return 0; } int bSums(Mat &src) { int counter = 0; //迭代器访问像素点 Mat_<uchar>::iterator it = src.begin<uchar>(); Mat_<uchar>::iterator itend = src.end<uchar>(); for (; it != itend; ++it) { if ((*it)>0) counter += 1;//二值化后,像素点是0或者255 } return counter; }

#ifndef _MYFUC_H#define _MYFUC_H#include<iostream>#include"opencv2/opencv.hpp"#define CV_SIGN(a) CV_CMP((a),0)#define CV_CMP(a,b) (((a) > (b)) - ((a) < (b)))using namespace std;using namespace cv;void myconvexityDefects(InputArray _points, InputArray _hull, OutputArray _defects);void myconvexHull(InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints);template<typename _Tp>struct CHullCmpPoints{bool operator()(const Point_<_Tp>* p1, const Point_<_Tp>* p2) const{return p1->x < p2->x || (p1->x == p2->x && p1->y < p2->y);}};template<typename _Tp>static int Sklansky_(Point_<_Tp>** array, int start, int end, int* stack, int nsign, int sign2){int incr = end > start ? 1 : -1;// prepare first triangleint pprev = start, pcur = pprev + incr, pnext = pcur + incr;int stacksize = 3;if (start == end ||(array[start]->x == array[end]->x &&array[start]->y == array[end]->y)){stack[0] = start;return 1;}stack[0] = pprev;stack[1] = pcur;stack[2] = pnext;end += incr; // make end = afterendwhile (pnext != end){// check the angle p1,p2,p3_Tp cury = array[pcur]->y;_Tp nexty = array[pnext]->y;_Tp by = nexty - cury;if (CV_SIGN(by) != nsign){_Tp ax = array[pcur]->x - array[pprev]->x;_Tp bx = array[pnext]->x - array[pcur]->x;_Tp ay = cury - array[pprev]->y;_Tp convexity = ay*bx - ax*by; // if >0 then convex angleif (CV_SIGN(convexity) == sign2 && (ax != 0 || ay != 0)){pprev = pcur;pcur = pnext;pnext += incr;stack[stacksize] = pnext;stacksize++;}else{if (pprev == start){pcur = pnext;stack[1] = pcur;pnext += incr;stack[2] = pnext;}else{stack[stacksize - 2] = pnext;pcur = pprev;pprev = stack[stacksize - 4];stacksize--;}}}else{pnext += incr;stack[stacksize - 1] = pnext;}}return --stacksize;}#endif
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include"myFuc.h" void myconvexityDefects(InputArray _points, InputArray _hull, OutputArray _defects) { Mat points = _points.getMat(); int i, j = 0, npoints = points.checkVector(2, CV_32S); CV_Assert(npoints >= 0); if (npoints <= 3) { _defects.release(); return; } Mat hull = _hull.getMat(); int hpoints = hull.checkVector(1, CV_32S); CV_Assert(hpoints > 2); cout << "凸包轮廓点数?" << hpoints << endl; const Point* ptr = points.ptr<Point>(); const int* hptr = hull.ptr<int>(); std::vector<Vec4i> defects; // 1. recognize co-orientation of the contour and its hull bool rev_orientation = ((hptr[1] > hptr[0]) + (hptr[2] > hptr[1]) + (hptr[0] > hptr[2])) != 2; // 2. cycle through points and hull, compute defects int hcurr = hptr[rev_orientation ? 0 : hpoints - 1]; CV_Assert(0 <= hcurr && hcurr < npoints); for (i = 0; i < hpoints; i++) { int hnext = hptr[rev_orientation ? hpoints - i - 1 : i]; CV_Assert(0 <= hnext && hnext < npoints); Point pt0 = ptr[hcurr], pt1 = ptr[hnext]; double dx0 = pt1.x - pt0.x; double dy0 = pt1.y - pt0.y; double scale = dx0 == 0 && dy0 == 0 ? 0. : 1. / std::sqrt(dx0*dx0 + dy0*dy0); int defect_deepest_point = -1; double defect_depth = 0; bool is_defect = false; j = hcurr; for (;;) { // go through points to achieve next hull point j++; j &= j >= npoints ? 0 : -1; if (j == hnext) break; // compute distance from current point to hull edge double dx = ptr[j].x - pt0.x; double dy = ptr[j].y - pt0.y; double dist = fabs(-dy0*dx + dx0*dy) * scale; if (dist > defect_depth) { defect_depth = dist; defect_deepest_point = j; is_defect = true; } } if (is_defect) { int idepth = cvRound(defect_depth * 256); defects.push_back(Vec4i(hcurr, hnext, defect_deepest_point, idepth)); } hcurr = hnext; } Mat(defects).copyTo(_defects); } void myconvexHull(InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints) { Mat points = _points.getMat(); int i, total = points.checkVector(2), depth = points.depth(), nout = 0; int miny_ind = 0, maxy_ind = 0; CV_Assert(total >= 0 && (depth == CV_32F || depth == CV_32S)); if (total == 0) { _hull.release(); return; } returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S; bool is_float = depth == CV_32F; AutoBuffer<Point*> _pointer(total); AutoBuffer<int> _stack(total + 2), _hullbuf(total); Point** pointer = _pointer; Point2f** pointerf = (Point2f**)pointer; Point* data0 = points.ptr<Point>(); int* stack = _stack; int* hullbuf = _hullbuf; CV_Assert(points.isContinuous()); for (i = 0; i < total; i++) pointer[i] = &data0[i]; // sort the point set by x-coordinate, find min and max y if (!is_float) { std::sort(pointer, pointer + total, CHullCmpPoints<int>()); for (i = 1; i < total; i++) { int y = pointer[i]->y; if (pointer[miny_ind]->y > y) miny_ind = i; if (pointer[maxy_ind]->y < y) maxy_ind = i; } } else { std::sort(pointerf, pointerf + total, CHullCmpPoints<float>()); for (i = 1; i < total; i++) { float y = pointerf[i]->y; if (pointerf[miny_ind]->y > y) miny_ind = i; if (pointerf[maxy_ind]->y < y) maxy_ind = i; } } if (pointer[0]->x == pointer[total - 1]->x && pointer[0]->y == pointer[total - 1]->y) { hullbuf[nout++] = 0; } else { // upper half int *tl_stack = stack; int tl_count = !is_float ? Sklansky_(pointer, 0, maxy_ind, tl_stack, -1, 1) : Sklansky_(pointerf, 0, maxy_ind, tl_stack, -1, 1); int *tr_stack = stack + tl_count; int tr_count = !is_float ? Sklansky_(pointer, total - 1, maxy_ind, tr_stack, -1, -1) : Sklansky_(pointerf, total - 1, maxy_ind, tr_stack, -1, -1); // gather upper part of convex hull to output if (!clockwise) { std::swap(tl_stack, tr_stack); std::swap(tl_count, tr_count); } for (i = 0; i < tl_count - 1; i++) hullbuf[nout++] = int(pointer[tl_stack[i]] - data0); for (i = tr_count - 1; i > 0; i--) hullbuf[nout++] = int(pointer[tr_stack[i]] - data0); int stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1; // lower half int *bl_stack = stack; int bl_count = !is_float ? Sklansky_(pointer, 0, miny_ind, bl_stack, 1, -1) : Sklansky_(pointerf, 0, miny_ind, bl_stack, 1, -1); int *br_stack = stack + bl_count; int br_count = !is_float ? Sklansky_(pointer, total - 1, miny_ind, br_stack, 1, 1) : Sklansky_(pointerf, total - 1, miny_ind, br_stack, 1, 1); if (clockwise) { std::swap(bl_stack, br_stack); std::swap(bl_count, br_count); } if (stop_idx >= 0) { int check_idx = bl_count > 2 ? bl_stack[1] : bl_count + br_count > 2 ? br_stack[2 - bl_count] : -1; if (check_idx == stop_idx || (check_idx >= 0 && pointer[check_idx]->x == pointer[stop_idx]->x && pointer[check_idx]->y == pointer[stop_idx]->y)) { // if all the points lie on the same line, then // the bottom part of the convex hull is the mirrored top part // (except the exteme points). bl_count = MIN(bl_count, 2); br_count = MIN(br_count, 2); } } for (i = 0; i < bl_count - 1; i++) hullbuf[nout++] = int(pointer[bl_stack[i]] - data0); for (i = br_count - 1; i > 0; i--) hullbuf[nout++] = int(pointer[br_stack[i]] - data0); } if (!returnPoints) Mat(nout, 1, CV_32S, hullbuf).copyTo(_hull); else { _hull.create(nout, 1, CV_MAKETYPE(depth, 2)); Mat hull = _hull.getMat(); size_t step = !hull.isContinuous() ? hull.step[0] : sizeof(Point); for (i = 0; i < nout; i++) *(Point*)(hull.ptr() + i*step) = data0[hullbuf[i]]; } }

https://blog.csdn.net/boy313918205/article/details/49683105

先马一下,过段时间分析


最后

以上就是醉熏鸡最近收集整理的关于凹点检测研究的全部内容,更多相关凹点检测研究内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部