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