OpenCv-C++下的輪廓周圍繪製矩形框和圓形框
阿新 • • 發佈:2018-11-30
目前我正在學習OpenCv下的輪廓周圍繪製矩形框和圓形框,將個人學習記錄放到這裡。
參考連結:https://blog.csdn.net/lanyuelvyun/article/details/76614872
https://blog.csdn.net/qq_31647835/article/details/81055711
下面介紹幾個相關函式:
findContours():不用說了,找到影象的輪廓點
approxPolyDP():減少輪廓點集裡的個數
boundingRect():得到包覆此輪廓的最小正矩形
minEnclosingCircle():最小包圍圓形
minAreaRect():帶旋轉的矩形
#include<opencv2/opencv.hpp> #include<iostream> #include<math.h> using namespace cv; using namespace std; Mat src, dst, gray_src; void polyPD(int, void*); int threshold_value = 100; int threshold_max = 255; int main(int argc, char** argv) { src = imread("D:/test/hot-ball.png"); if (!src.data) { cout << "圖片未找到" << endl; return -1; } cvtColor(src, gray_src, CV_BGR2GRAY); namedWindow("output title", CV_WINDOW_AUTOSIZE); createTrackbar("Move", "output title", &threshold_value, threshold_max, polyPD); polyPD(0, 0); imshow("input title", src); waitKey(0); return 0; } void polyPD(int, void *) { Mat bin_out; vector<vector<Point>> contours;//定義影象輪廓點集 vector<Vec4i> hieracy; //二值化操作 threshold(gray_src, bin_out, threshold_value, threshold_max, THRESH_BINARY); //找到影象輪廓點 findContours(bin_out, contours, hieracy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(-1, -1)); 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()); dst = Mat::zeros(src.size(), src.type()); RNG rng(12345); for (size_t i = 0; i < contours.size(); i++) {//對影象輪廓點進行多邊形擬合 Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //繪製熱氣球輪廓 //drawContours(dst, contours,(int)i, color,1,8,hieracy,0,Point(-1,-1)); approxPolyDP(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]; //畫直線需要4個點 for (size_t k = 0; k < contours.size(); k++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //rectangle(drawImg, ploy_rects[t], color, 2, 8); //circle(drawImg, ccs[t], radius[t], color, 2, 8); if (contours_ploy[k].size() > 5) { ellipse(dst,myellipse[k], color, 1, 8);//繪製橢圓 minRects[k].points(pts); for (int r = 0; r < 4; r++) { line(dst,pts[r], pts[(r + 1) % 4], color, 1, 8); } } } imshow("output title", dst); return; } /* approxPolyDP(): InputArray curve:一般是由影象的輪廓點組成的點集 OutputArray approxCurve:表示輸出的多邊形點集 double epsilon:主要表示輸出的精度,就是兩個輪廓點之間的最大距離數,5,6,7... bool closed:表示輸出的多邊形是否封閉 */ /*THRESH_TRIANGLE,THRESH_OTSU,自動尋找閾值 不清楚閾值使用哪些數字時,可以THRESH_OTSU||THRESH_BINARY這樣寫; vector<Point2f> 圓心; */ /* 當得到物件的輪廓後,可用boundingRect()得到包覆此輪廓的最小正矩形boundingRect(); 帶旋轉的矩形minAreaRect(); 最小包圍圓形 minEnclosingCircle() */
程式碼執行結果:
輸入圖片:
二值化後繪製的輪廓: