《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(四)图像的矩
8.4 圖像的矩
從一幅數字圖形中計算出來的矩集,通常描述了該圖像形狀的全局特征,并提供了大量關于該圖像不同類型的幾何特性信息,如大小、位置、方向、形狀等
(1)一階矩與形狀有關
(2)二階矩顯示曲線圍繞直線平均值的擴展程度
(3)三階矩關于平均值的對稱性的測量
(4)二階矩和三階矩可以導出一組共7個不變矩,不變矩是圖像的統計特性,滿足平移、伸縮、旋轉均不變的特性。
8.4.1 矩的相關函數
1.矩的計算:moments()函數
(1)作用:用于計算多邊形和光柵形狀的最高達三階的所有矩。矩用來計算形狀的重心、面積、主軸和其他形狀特征
(2)函數原型:Moment moments(InputArray array, bool binaryImage=false)
(3)參數說明:
??1)輸入參數,可以是光柵圖像(單通道,8位或浮點的二維數組)或二維數組(1N或N1)
??2)此參數僅對圖像使用,取true,則所有非零像素為1,默認false
2.計算輪廓面積:contourArea()函數
(1)作用:用于計算整個輪廓或部分輪廓的面積
(2)函數原型:double contourArea(InputArray contour, bool oriented=false)
(3)參數說明:
??1)輸入的二維點集
??2)面向區域標識符,若其為true,該函數返回一個帶符號的面積值,其正負取決于輪廓方向(順/逆時針),若其為false,該函數返回面積絕對值。
3.計算輪廓長度:arcLength()函數
(1)作用:計算封閉輪廓的周長或曲線的長度
(2)函數原型:double arcLength(InputArray curve,bool closed)
(3)參數說明:
??1)輸入的二維點集
??2)用于指示曲線是否封閉的標識符,默認closed
8.4.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, g_cannyMat_output;
int g_nThresh = 100;
int g_nMaxThresh = 255;
RNG g_rng(12345);
vector<vector<Point>>g_vContours;
vector<Vec4i>g_vHierarchy;
//全局函數
void on_ThreshChange(int, void*);int main()
{//載入原圖g_srcImage = imread("Google.jpg");//把原圖轉為灰度圖并進行平滑cvtColor(g_srcImage, g_grayImage, COLOR_RGB2GRAY);blur(g_grayImage, g_grayImage, Size(3,3));//創建窗口namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);imshow(WINDOW_NAME1, g_srcImage);//創建滑動條并初始化createTrackbar("閾值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ThreshChange);on_ThreshChange(0, 0);waitKey(0);return 0;
}
void on_ThreshChange(int, void*)
{//使用Canny檢測邊緣Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);//找到輪廓findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//計算矩vector<Moments> mu(g_vContours.size());for (int i = 0; i < g_vContours.size(); i++){mu[i] = moments(g_vContours[i], false);}//計算中心矩vector<Point2f> mc(g_vContours.size());for (int i = 0; i < g_vContours.size(); i++){mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00), static_cast<float>(mu[i].m01 / mu[i].m00));}//繪制輪廓Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);for (int i = 0; i < g_vContours.size(); i++){Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//隨機生成顏色值drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());//繪制外層和內層輪廓circle(drawing, mc[i], 4, color, -1, 8, 0);//繪制圓}//顯示窗口namedWindow(WINDOW_NAME2,WINDOW_AUTOSIZE);imshow(WINDOW_NAME2, drawing);//通過m00計算輪廓面積和OpenCV函數比較printf("\t 輸出內容:面積和輪廓長度\n");for (int i = 0; i < g_vContours.size(); i++){printf(">通過m00計算出輪廓[%d]的面積:(M_00) = %.2f \n", i, mu[i].m00);printf(" OpenCV函數計算出的面積 = %.2f, 長度:%.2f \n\n", contourArea(g_vContours[i]), arcLength(g_vContours[i], true));}
}
運行效果:
總結
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(四)图像的矩的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 饮雪狂兽性格
- 下一篇: 《OpenCV3编程入门》学习笔记8 图