1. 程式人生 > >OpenCV凸包凸缺陷檢測

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);
}