OpenCV凸包凸缺陷檢測
阿新 • • 發佈:2019-01-30
左邊原圖,右邊結果。
右圖中,藍色線為凸包,凸缺陷的起始點為黑色點,凸缺陷的起始點為綠色點,凸缺陷的最深點為紅色點(即邊緣點到凸包距離最大點)。
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); }