一、概述
案例:檢測圖像輪廓並繪制輪廓的外界矩形和圓
相關函數介紹:
approxPolyDP(contourMat, approxCurve, 10, true);//找出輪廓的多邊形擬合曲線 第一個參數 InputArray curve:輸入的點集 第二個參數OutputArray approxCurve:輸出的點集,當前點集是能最小包容指定點集的。畫出來即是一個多邊形。 第三個參數double epsilon:指定的精度,也即是原始曲線與近似曲線之間的最大距離。 第四個參數bool closed:若為true,則說明近似曲線是閉合的;反之,若為false,則斷開
boundingRect(InputArray points)得到輪廓周圍最小矩形左上交點坐標和右下角點坐標,繪制一個矩形
minAreaRect(InputArray points)得到一個旋轉的矩形,返回旋轉矩形
minEnclosingCircle(InputArray points, //得到最小區域圓形 Point2f& center, // 圓心位置 float& radius)// 圓的半徑
fitEllipse(InputArray points)得到最小橢圓
操作步驟:
1.加載圖像
2.轉灰度圖像
3.二值化圖像
4.發現輪廓
5.准備輪廓數據approxPolyDP、boundingRect、minEnclosingCircle、fitEllipse、minAreaRect
6.繪制輪廓rectangle、circle
二、代碼示例
//1.載入圖像 Mat src = imread(filePath); if(src.empty()){ return; } Mat src_clone = src.clone(); imshow("src",src); //轉灰度圖圖像 Mat gray; cvtColor(src,gray,COLOR_BGR2GRAY); //均值濾波輕微去噪聲 blur(gray,gray,Size(3,3),Point(-1,-1)); // imshow("gray",gray); //圖像二值化 threshold(gray,gray,100,200,THRESH_BINARY); // imshow("threshold",gray); //發現輪廓 vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(gray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0)); RNG rng(123456); //准備數據 vector<vector<Point>> contours_ploy(contours.size()); vector<Rect> ploy_rects(contours.size()); vector<Point2f> ccs(contours.size()); vector<float> radius(contours.size()); vector<RotatedRect> minRects(contours.size()); vector<RotatedRect> myellipse(contours.size()); for(size_t i =0;i<contours.size();i++){ approxPolyDP(Mat(contours[i]),contours_ploy[i],3,true); ploy_rects[i] = boundingRect(contours_ploy[i]); minEnclosingCircle(contours_ploy[i],ccs[i],radius[i]); if(contours_ploy[i].size()>5){ myellipse[i] = fitEllipse(contours_ploy[i]); minRects[i] = minAreaRect(contours_ploy[i]); } } //繪制輪廓外界圖形 Point2f pts[4]; for(size_t t =0;t<contours.size();t++){ Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)); rectangle(src_clone,ploy_rects[t],color,2,LINE_4); circle(src_clone,ccs[t],radius[t],color,2,LINE_4); // if (contours_ploy[t].size() > 5) { // ellipse(src_clone, myellipse[t], color, 1, 8); // minRects[t].points(pts); // for (int r = 0; r < 4; r++) { // line(src_clone, pts[r], pts[(r + 1) % 4], color, 1, 8); // } // } } imshow("src_clone",src_clone);
三、示例圖片(ps:在實際自己運行的時候需要調整閾值以達到最有效果)