《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(三)使用多边形将轮廓包围
8.3 使用多邊形將輪廓包圍
8.3.1 將輪廓包圍的多邊形函數
1.返回外部邊界:boundingRect()函數
(1)作用:返回指定點集最外面的邊界矩形(四個頂點)
(2)函數原型:Rect boundingRect(InputArray points)
2.尋找最小包圍矩形:minAreaRect()函數
(1)作用:返回指定點集可旋轉的最小面積的包圍矩形(四個頂點)
(2)函數原型:RotatedRect minAreaRect(InputArray points)
3.尋找最小包圍圓形:minEnclosingCircle()函數
(1)作用:利用一種迭代算法,返回指定點集的最小面積的包圍圓形(圓心,半徑)
(2)函數原型:void minEnclosingCircle(InputArray points, Point2f& center, float& radius)
(3)參數說明:輸入二維點集,輸出圓心,輸出半徑
4.用橢圓擬合二維點集:fitEllipse()函數
(1)作用:橢圓擬合二維點集
(2)函數原型:RotatedRect fitEllipse(InputArray points)
5.逼近多邊形曲線:approxPolyDP()函數
(1)作用:用指定精度逼近多邊形曲線
(2)函數原型:void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
(3)參數說明:
??1)輸入的二維點集
??2)多邊形逼近的結果
??3)逼近的精度,為原始曲線和近似曲線間的最大值
??4)取真時,近似的曲線為封閉曲線,取假時不封閉
8.3.2 綜合示例
1.隨機生成彩色點,調用多邊形包圍函數
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;int main()
{//初始化變量和隨機值Mat image(600, 600, CV_8UC3);Mat dstImage1, dstImage2, dstImage3, dstImage4;RNG& rng = theRNG();//循環,按下ESC鍵程序退出,否則一直更新while (1){//參數初始化int count = rng.uniform(3, 103);//隨機生成點的數量vector<Point> points;//點值//隨機生成點坐標for (int i = 0; i < count; i++){Point point;point.x = rng.uniform(image.rows / 4, image.rows * 3 / 4);point.y = rng.uniform(image.cols / 4, image.cols * 3 / 4);points.push_back(point);}//繪制出隨機顏色的點image = Scalar::all(0);for (int i = 0; i < count; i++){circle(image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, LINE_AA);}//【1】對指定點集尋找邊界矩形Rect rect = boundingRect(Mat(points));//繪制邊界矩形image.copyTo(dstImage1);rectangle(dstImage1, rect, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//顯示窗口imshow("【1】邊界矩形窗口", dstImage1);//【2】對指定點集尋找最小面積的包圍矩形RotatedRect box1 = minAreaRect(Mat(points));Point2f vertex2[4];box1.points(vertex2);//繪制最小面積的包圍矩形image.copyTo(dstImage2);for (int i = 0; i < 4; i++){line(dstImage2, vertex2[i], vertex2[(i + 1) % 4], Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);}//顯示窗口imshow("【2】最小面積包圍矩形窗口", dstImage2);//【3】對指定點集尋找最小面積的包圍圓形Point2f center;float radius;minEnclosingCircle(Mat(points),center,radius);//繪制最小面積的圓形image.copyTo(dstImage3);circle(dstImage3, center, cvRound(radius), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//顯示窗口imshow("【3】最小面積包圍圓形窗口",dstImage3);//【4】橢圓擬合指定點集RotatedRect box2 = fitEllipse(Mat(points));//繪制橢圓image.copyTo(dstImage4);ellipse(dstImage4, box2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//顯示窗口imshow("【4】橢圓形擬合窗口", dstImage4);char key = (char)waitKey();if(key == 27) break; }return 0;
}
運行效果:
2.載入圖像,調用多邊形包圍函數
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
//定義輔助宏
#define WINDOW_NAME1 "【原始圖窗口】"
#define WINDOW_NAME2 "【效果圖窗口】"
//全局變量
Mat g_srcImage, g_grayImage;
int g_nThresh = 50;//閾值
int g_nMaxThresh = 255;//閾值最大值
RNG g_rng(12345);//隨機數生成器
//全局函數
void on_ContoursChange(int, void*);int main()
{ //【1】載入原圖g_srcImage = imread("Google.jpg");if (!g_srcImage.data){printf("載入原圖失敗~!\n");return false;}//【2】創建原始圖窗口并顯示namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);imshow(WINDOW_NAME1, g_srcImage);//【3】得到原圖的灰度圖像并進行平滑cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));//【4】設置滾動條并調用一次回調函數createTrackbar("閾值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);on_ContoursChange(0, 0);waitKey(0);return 0;
}
void on_ContoursChange(int, void*)
{//定義一些參數Mat threshold_output;vector<vector<Point>> contours;vector<Vec4i> hierarchy;//使用Threshold檢測邊緣threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);//找出輪廓findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//多邊形逼近輪廓+獲取矩形和圓形邊界框vector<vector<Point>> contours_poly(contours.size());vector<Rect> boundRect(contours.size());vector<Point2f> center(contours.size());vector<float> radius(contours.size());//一個循環,遍歷所有部分,進行本程序最核心的操作for (int i = 0; i < contours.size(); i++){approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//用指定精度逼近多邊形曲線boundRect[i] = boundingRect(Mat(contours_poly[i]));//計算點集的最外面矩形邊界minEnclosingCircle(contours_poly[i], center[i], radius[i]);//對給定點集尋找最小面積的包圍圓形}//繪制多邊形輪廓+包圍的矩形框+圓形框Mat dstImage = Mat::zeros(threshold_output.size(), CV_8UC3);for (int i = 0; i < contours.size(); i++){Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//隨即設置顏色drawContours(dstImage, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());//繪制輪廓rectangle(dstImage, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//繪制矩形circle(dstImage, center[i], (int)radius[i], color, 2, 8, 0);}//顯示效果圖窗口namedWindow(WINDOW_NAME2,WINDOW_AUTOSIZE);imshow(WINDOW_NAME2, dstImage);
}
運行效果:
總結
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(三)使用多边形将轮廓包围的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《OpenCV3编程入门》学习笔记8 图
- 下一篇: 饮雪狂兽性格