日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【OpenCV3】图像最大轮廓检测——cvFindBiggestContour()封装

發布時間:2025/3/21 编程问答 72 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OpenCV3】图像最大轮廓检测——cvFindBiggestContour()封装 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

此前在【OpenCV3】圖像輪廓查找與繪制——cv::findContours()與cv::drawContours()詳解》一文中,詳細介紹了圖像輪廓的檢測與繪制,但是在實際的應用中,往往需要檢測目標的最大輪廓,但是OpenCV本身并沒有封裝這樣一個函數,下面就貼上封裝好的接口,供參考使用。

說明:對于最大輪廓的定義,有些以輪廓的點數最多為標準,有的以所包圍的面積最大為標準,這里將兩種都實現一下。

1、C接口的封裝(最多點數)

CvSeq* cvFindBiggestCountour(IplImage *binaryImage) {int polyHull0 = 1;CvPoint offset;offset.x = 0;offset.y = 0;CvMemStorage *tempStorage = cvCreateMemStorage(0);CvSeq *contour;CvSeq *c;int nContours = 0;double largest_length = 0;double len = 0;CvContourScanner scanner;CvSlice slice = CV_WHOLE_SEQ;scanner = cvStartFindContours(binaryImage, tempStorage, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset);while ((c = cvFindNextContour(scanner)) != 0){len = cvContourPerimeter(c);if (len > largest_length){largest_length = len;}}scanner = cvStartFindContours(binaryImage, tempStorage, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset);while ((c = cvFindNextContour(scanner)) != 0){len = cvContourPerimeter(c);double q = largest_length;if (len < q)cvSubstituteContour(scanner, 0);else{CvSeq *newC;if (polyHull0)newC = cvApproxPoly(c, sizeof(CvContour), tempStorage, CV_POLY_APPROX_DP, 2, 0);elsenewC = cvConvexHull2(c, tempStorage, CV_CLOCKWISE, 1);cvSubstituteContour(scanner, newC);}nContours++;}printf("End find contours!\n");contour = cvEndFindContours(&scanner);cvReleaseMemStorage(&tempStorage);cvRelease(&c);return contour; }

2、C接口的封裝(最大面積)

CvSeq* cvFindBiggestCountour(IplImage *binaryImage) {int polyHull0 = 1;CvPoint offset;offset.x = 0;offset.y = 0;CvMemStorage *tempStorage = cvCreateMemStorage(0);CvSeq *contour;CvSeq *c;int nContours = 0;double largest_length = 0;double len = 0;CvContourScanner scanner;CvSlice slice = CV_WHOLE_SEQ;scanner = cvStartFindContours(binaryImage, tempStorage, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset);while ((c = cvFindNextContour(scanner)) != 0){len = cvContourArea(c, slice, 0);if (len > largest_length){largest_length = len;}}scanner = cvStartFindContours(binaryImage, tempStorage, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset);while ((c = cvFindNextContour(scanner)) != 0){len = cvContourArea(c, slice, 0);double q = largest_length;if (len < q)cvSubstituteContour(scanner, 0);else{CvSeq *newC;if (polyHull0)newC = cvApproxPoly(c, sizeof(CvContour), tempStorage, CV_POLY_APPROX_DP, 2, 0);elsenewC = cvConvexHull2(c, tempStorage, CV_CLOCKWISE, 1);cvSubstituteContour(scanner, newC);}nContours++;}printf("End find contours!\n");contour = cvEndFindContours(&scanner);cvReleaseMemStorage(&tempStorage);cvRelease(&c);return contour; }

3、C++接口封裝(最多點數)

std::vector<cv::Point> findBiggestContour(cv::Mat binary_image) {std::vector<std::vector<cv::Point>> contours;int largest_area = 0;int largest_contour_index = 0;cv::findContours(binary_image, contours, cv::noArray(), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);for (int i = 0; i < contours.size(); i++) {int a = contours[i].size(); if (a > largest_area){largest_area = a;largest_contour_index = i; }}return contours[largest_contour_index]; }

4、C++接口封裝(最大面積)

std::vector<cv::Point> findBiggestContour(cv::Mat binary_image) {std::vector<std::vector<cv::Point>> contours;std::vector<cv::Vec4i> hierarchy;int largest_area = 0;int largest_contour_index = 0;cv::findContours(binary_image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);for (int i = 0; i < contours.size(); i++) // iterate through each contour. {double a = contourArea(contours[i], false); // Find the area of contourif (a > largest_area){largest_area = a;largest_contour_index = i; //Store the index of largest contour}}return contours[largest_contour_index]; }

其中C++接口的測試代碼如下

cv::Mat src = cv::imread("Hepburn.png", 1);cv::Mat result = src.clone();cv::Mat gray;cv::cvtColor(src, gray, CV_BGR2GRAY);cv::Mat binary;cv::threshold(gray, binary, 100, 255, cv::THRESH_BINARY);std::vector< std::vector< cv::Point> > contours;std::vector< cv::Point> biggest_contour;std::vector< std::vector< cv::Point> > temp_contours;cv::findContours(binary,contours,cv::noArray(),cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);biggest_contour = findBiggestContour(binary);temp_contours.push_back(biggest_contour);cv::drawContours(result, contours, -1, cv::Scalar(0, 255, 0));cv::drawContours(result, temp_contours, 0, cv::Scalar(0, 0, 255));cv::imshow("src", src);cv::imshow("gray", gray);cv::imshow("binary", binary);cv::imshow("result", result);cv::waitKey(0);return 0;

測試結果如下,其中紅色曲線代表的是最大輪廓:





參考:https://harismoonamkunnu.blogspot.tw/2012/11/opencv-find-biggest-contour.html

總結

以上是生活随笔為你收集整理的【OpenCV3】图像最大轮廓检测——cvFindBiggestContour()封装的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。