我是靠谱客的博主 醉熏鸡,最近开发中收集的这篇文章主要介绍凹点检测研究,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#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

先马一下,过段时间分析


最后

以上就是醉熏鸡为你收集整理的凹点检测研究的全部内容,希望文章能够帮你解决凹点检测研究所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部