#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define window "【原始圖】"
#define windowx "【結果圖1】"
#define windowy "[結果圖2]"
//計算一個圖像的輪廓,不同閾值下canny函數的輪廓,長度,面積。矩以及中心距。並且比較中心距和opencv函數計算的輪廓面積。
Mat src, dst, tmp;
int thresh = 40;
int thresh_max = 255;
RNG rng = theRNG();
void on_canny(int, void*);
int main()
{
//1.讀入圖像,轉換灰度。
//2。建立窗口以及回調函數。
src = imread("馬車.jpg");
cvtColor(src, src, CV_BGR2GRAY);
imshow(window, src);
namedWindow(windowx);
imshow(windowx, src);
createTrackbar("thresh", window, &thresh, thresh_max, on_canny);
waitKey(0);
return 0;
}
void on_canny(int, void*)
{
//3,找出canny邊界輪廓。
Canny(src, tmp, thresh, 2 * thresh);
//4。對二值圖像求輪廓。
vector<vector<Point>> contours;
vector<Vec4i> heri;
findContours(tmp,contours,heri,RETR_TREE,CHAIN_APPROX_SIMPLE);
//5.多各個輪廓求矩。
vector<Moments> mu(contours.size());
for (int i = 0; i < contours.size(); ++i)
{
mu[i]=moments(contours[i]);//計算每個輪廓的矩。
}
//6.利用得到的各個矩,來求中心距。
vector<Point> mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
float x = static_cast<float>(mu[i].m10 / mu[i].m00);
float y = static_cast<float>(mu[i].m01/ mu[i].m00);
mc.push_back(Point(x, y));
}
//7。繪製得到的輪廓,並且將中心距在輪廓中標出。
dst = Mat::zeros(src.size(),CV_8UC3);
for (int i = 0; i < contours.size(); i++)
{
int nx = rng.uniform(0, 255);
int ny = rng.uniform(0, 255);
int nz = rng.uniform(0, 255);
Scalar color = Scalar(nx, ny, nz);//隨機爲當前輪廓取一個顏色。
drawContours(dst,contours,i,color);
circle(dst, mc[i], 3, color, -1);//畫出輪廓質心。
}
//8.比較由矩和opencv分別計算得到面積,同時輸出輪廓的長度。
for (int i=0; i < contours.size(); ++i)
{
cout << "由矩得到輪廓的面積:" << mu[i].m00 ;
cout << "由opencv函數得到的輪廓面積:" << contourArea(contours[i]) << endl;
cout << "輪廓長度:" << arcLength(contours[i], true)<<endl;
}
namedWindow(windowx);
imshow(windowx,dst);
}
計算一個圖像的輪廓,不同閾值下canny函數的輪廓,長度,面積。矩以及中心距。並且比較中心距和opencv函數計算的輪廓面積
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.