概述
#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
#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
先马一下,过段时间分析
最后
以上就是醉熏鸡为你收集整理的凹点检测研究的全部内容,希望文章能够帮你解决凹点检测研究所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复