C++版本OpenCv教程(四十五)計算輪廓面積與長度
技術標籤:OpenCV
輪廓面積
輪廓面積是輪廓重要的統計特性之一,通過輪廓面積的大小可以進一步分析每個輪廓隱含的資訊,例如通過輪廓面積區分物體大小識別不同的物體。輪廓面積是指每個輪廓中所有的畫素點圍成區域的面積,單位為畫素。OpenCV 4提供了檢測輪廓面積的**contourArea()**函式,該函式的函式原型在程式碼清單7-15中給出。
double cv::contourArea(InputArray contour,bool oriented = false )
- contour:輪廓的畫素點
- oriented:區域面積是否具有方向的標誌,true表示面積具有方向性,false表示不具有方向性,預設值為不具有方向性的false。
該函式用於統計輪廓畫素點圍成區域的面積,函式的返回值是統計輪廓面積的結果,資料型別為double。函式第一個引數表示輪廓的畫素點,資料型別為vector或者Mat,相鄰的兩個畫素點之間逐一相連構成的多邊形區域即為輪廓面積的統計區域。連續的三個畫素點之間的連線有可能在同一條直線上,因此為了減少輸入輪廓畫素點的數目,可以只輸入輪廓的頂點畫素點,例如一個三角形的輪廓,輪廓中可能具有每一條邊上的所有畫素點,但是在統計面積時可以只輸入三角形的三個頂點。函式第二個引數是區域面積是否具有方向的標誌,引數為true時表示統計的面積具有方向性,輪廓頂點順時針給出和逆時針給出時統計的面積互為相反數;引數為false時表示統計的面積不具有方向性,輸出輪廓面積的絕對值。
為了瞭解該函式的使用方法,在程式碼清單7-16中給出了統計輪廓面積的示例程式。程式中給出一個直角三角形輪廓的三個頂點以及斜邊的中點,統計出的輪廓面積與三角形的面積相等,同時統計圖7-16中每個輪廓的面積,程式的執行結果在圖7-18給出。
#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
system("color F0"); //更改輸出介面顏色
//用四個點表示三角形輪廓
vector<Point> contour;
contour.push_back(Point2f(0, 0));
contour.push_back(Point2f(10, 0));
contour.push_back(Point2f(10, 10));
contour.push_back(Point2f(5, 5));
double area = contourArea(contour);
cout << "area =" << area << endl;
Mat img = imread("coins.jpg");
if (img.empty())
{
cout << "請確認影象檔名稱是否正確" << endl;
return -1;
}
imshow("原圖", img);
Mat gray, binary;
cvtColor(img, gray, COLOR_BGR2GRAY); //轉化成灰度圖
GaussianBlur(gray, gray, Size(9, 9), 2, 2); //平滑濾波
threshold(gray, binary, 170, 255, THRESH_BINARY | THRESH_OTSU); //自適應二值化
// 輪廓檢測
vector<vector<Point>> contours; //輪廓
vector<Vec4i> hierarchy; //存放輪廓結構變數
findContours(binary, contours, hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE, Point());
//輸出輪廓面積
for (int t = 0; t < contours.size(); t++)
{
double area1 = contourArea(contours[t]);
cout << "第" << t << "輪廓面積=" << area1 << endl;
}
return 0;
}
輪廓長度
輪廓的周長也是輪廓重要的統計特性之一,輪廓的周長雖然無法直接反應輪廓區域的大小和形狀,但是可以與輪廓面積結合得到關於輪廓區域的更多資訊,例如某個區域的面積與周長平方的比值為十六分之一時該區域為正方形。OpenCV 4提供了用於檢測輪廓周長或者曲線長度的**arcLength()**函式,該函式的函式原型在程式碼清單7-17中給出。
double cv::arcLength(InputArray curve,bool closed )
- curve:輪廓或者曲線的2D畫素點。
- closed:輪廓或者曲線是否閉合標誌,true表示閉合。
該函式能夠統計輪廓或者曲線的長度,函式返回值為統計長度,單位為畫素,資料型別為double。函式的第一個引數是輪廓或者曲線的2D畫素點,資料型別為vector或者Mat。函式的第二個引數是輪廓或者曲線是否閉合的標誌,true表示閉合。
函式統計的長度是輪廓或者曲線相鄰兩個畫素點之間連線的距離,例如計算三角形三個頂點A、B和C構成的輪廓長度時,並且函式第二個引數為true時,統計的長度是三角形三個邊AB、BC和CA的長度之和;當引數為false時,統計的長度是由A到C三個點之間依次連線的距離長度之和,即AB和BC的長度之和。
為了瞭解該函式的使用方法,在程式碼清單7-18中給出統計輪廓長度的示例程式。程式中給出一個直角三角形輪廓的三個頂點以及斜邊的中點,分別利用arcLength()函式統計輪廓閉合情況下的尺度和非閉合情況下的長度,同時統計圖7-16中每個輪廓的長度,程式的執行結果在圖7-19給出。
#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
system("color F0"); //更改輸出介面顏色
//用四個點表示三角形輪廓
vector<Point> contour;
contour.push_back(Point2f(0, 0));
contour.push_back(Point2f(10, 0));
contour.push_back(Point2f(10, 10));
contour.push_back(Point2f(5, 5));
double length0 = arcLength(contour, true);
double length1 = arcLength(contour, false);
cout << "length0 =" << length0 << endl;
cout << "length1 =" << length1 << endl;
Mat img = imread("coins.jpg");
if (img.empty())
{
cout << "請確認影象檔名稱是否正確" << endl;
return -1;
}
imshow("原圖", img);
Mat gray, binary;
cvtColor(img, gray, COLOR_BGR2GRAY); //轉化成灰度圖
GaussianBlur(gray, gray, Size(9, 9), 2, 2); //平滑濾波
threshold(gray, binary, 170, 255, THRESH_BINARY | THRESH_OTSU); //自適應二值化
// 輪廓檢測
vector<vector<Point>> contours; //輪廓
vector<Vec4i> hierarchy; //存放輪廓結構變數
findContours(binary, contours, hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE, Point());
//輸出輪廓長度
for (int t = 0; t < contours.size(); t++)
{
double length2 = arcLength(contours[t], true);
cout << "第" << t << "個輪廓長度=" << length2 << endl;
}
return 0;
}