OpenCV凸包凸缺陷检测

左边原图,右边结果。

右图中,蓝色线为凸包,凸缺陷的起始点为黑色点,凸缺陷的起始点为绿色点,凸缺陷的最深点为红色点(即边缘点到凸包距离最大点)。

void convexityDefects(InputArray contour, InputArray convexhull, OutputArray convexityDefects)
      convexityDefects 是存储 Vec4i 的向量(vector<varname>),函数计算成功后向量的大小是轮廓凸缺陷的数量,向量每个元素Vec4i存储了4个整型数据,

因为Vec4i对[]实现了重载,所以可以使用 _vectername[i][0] 来访问向量 _vactername 的第i个元素的第一个分量。再说 Vec4i 中存储的四个整形数据,OpenCV 使用这四个元素表示凸缺陷,

Vec4i 第一个元素 start_index,表示缺陷在轮廓上的开始处,他的值是开始点在函数第一个参数 contour 中的下标索引;

Vec4i 第二个元素 end_index, 顾名思义其对应的值就是缺陷结束处在 contour 中的下标索引;

Vec4i 第三个元素 farthest_pt_index, 是缺陷上距离 轮廓凸包(convexhull)最远的点;

Vec4i最后的元素 fixpt_depth,fixpt_depth/256  表示了 轮廓上以 farthest_pt_index 为下标的点到 轮廓凸包的(convexhull)的距离,以像素为单位。


#include 
#include 
#include 
#include 
#include 
using namespace std;


int main()
{
	IplImage *src = cvLoadImage("C:\\Users\\kai\\Pictures\\sample\\1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
	//"C:\\Users\\kai\\Pictures\\rock2.bmp" "C:\\Users\\kai\\Pictures\\sample\\1.bmp"
	IplImage *dst = cvCreateImage(cvGetSize(src), 8, 3); //cvZero(dst);
	cvSet(dst/*图片*/, CV_RGB(255, 255, 255)/*白色*/, NULL/*如果c++可以省略*/);
	//Mat drawing(threshold_output.size(), CV_8UC3, Scalar(255, 255, 255));//初始化一个背景为白色矩阵

	CvMemStorage *storage = cvCreateMemStorage();
	CvSeq *contour = NULL, *hull = NULL;

	CvContourScanner scanner = cvStartFindContours(src, storage);
	while ((contour = cvFindNextContour(scanner)) != NULL){
		cvDrawContours(dst, contour, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0);

		cout << cvCheckContourConvexity(contour) << endl;

		hull = cvConvexHull2(contour, 0, CV_CLOCKWISE, 0);

		CvPoint pt0 = **(CvPoint**)cvGetSeqElem(hull, hull->total - 1);
		for (int i = 0; itotal; ++i){
			CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull, i);
			cvLine(dst, pt0, pt1, CV_RGB(0, 0, 255));
			pt0 = pt1;
		}

		CvSeq *defect = cvConvexityDefects(contour, hull);

		for (int i = 0; itotal; ++i){
			CvConvexityDefect df = *(CvConvexityDefect*)cvGetSeqElem(defect, i);
			cvCircle(dst, *df.start, 2, CV_RGB(0, 0, 0), -1);
			cvCircle(dst, *df.end, 2, CV_RGB(0, 255, 0), -1);
			cvCircle(dst, *df.depth_point, 2, CV_RGB(255, 0, 0), -1);
		}

		cvShowImage("dst", dst);

	}
	cvWaitKey();
	cvEndFindContours(&scanner);
}

猜你喜欢

转载自blog.csdn.net/wukai0909/article/details/78145946