#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <iostream>
using namespace cv;
using namespace std;
//定义全局变量
Mat srcImage, grayImage;
int thresh = 100;
const int threshMaxValue = 255;
RNG rng(12345);
int g_nBilateralFilterValue=3;
int g_nGaussianBlurValue=10;
//声明回调函数
void thresh_callback(int, void*);
int main()
{
double time0 = static_cast<double>(getTickCount());
srcImage = imread("1.bmp");//载入图像
//判断文件是否加载成功
if (!srcImage.data)
{
cout << "图像加载失败...";
return -1;
}
else
cout << "图像加载成功..." << endl << endl;
namedWindow("原图像", WINDOW_AUTOSIZE);
imshow("原图像", srcImage);
//图像转化为灰度图并平滑
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
// Mat element = getStructuringElement(MORPH_RECT, Size(10, 10));
// morphologyEx(grayImage,grayImage, MORPH_OPEN, element);
blur(grayImage, grayImage, Size(3, 3)); //均值滤波
//bilateralFilter(srcImage, srcImage, g_nBilateralFilterValue,
//g_nBilateralFilterValue*2,g_nBilateralFilterValue/2 ); //双边滤波
//GaussianBlur(grayImage, grayImage, Size(g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0);
namedWindow("灰度图", WINDOW_AUTOSIZE);
imshow("灰度图", grayImage);
//创建轨迹条
thresh_callback(60, 0);
time0=((double)getTickCount()-time0)/getTickFrequency();
cout<<"此方法运行时间为:"<<time0<<"秒"<<endl;
waitKey(0);
return 0;
}
void thresh_callback(int, void*)
{
Mat canny_output;
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
vector<double>angle(10000);
//canny边缘检测
Canny(grayImage, canny_output,50 ,thresh*2, 3);
imshow("canny",canny_output);
waitKey(0);
//轮廓提取
findContours(canny_output, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));
//轮廓填充cvDrawContours(contours, contours, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 2, CV_FILLED, 8, cvPoint(0, 0));
//计算图像矩
vector<Moments>mu(contours.size());
for (int i = 0; i < contours.size(); i++)
{
//int SumXY=0,SumX=0,SumY=0;
//int SumX2=0,AvrX=0,AvrY=0;
//double b=0,a=0;
//利用回归方程计算每一轮廓的斜率。
//for (int j=0;j < contours[i].size();j++)
//{
//SumXY=contours[i][j].x*contours[i][j].y+SumXY;
//SumX2=SumX2+contours[i][j].x*contours[i][j].x;
//SumX=SumX+contours[i][j].x;
//SumY+contours[i][j].y;
//}
//AvrX=SumX/contours[i].size();
//AvrY=SumY/contours[i].size();
//b=SumXY-contours[i].size()*AvrX*AvrY;
//a=AvrX-b*AvrY;//计算斜率
//angle[i]=atan(a);//计算角度
//angle[i] = a;
mu[i] = moments(contours[i], false);
}
//计算图像的质心
vector<Point2f>mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
}
//绘制轮廓,输出质心
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++)
{
if(contourArea(contours[i])>1000) //轮廓面积判断,大于某一特定值,才画
// 出该轮廓,输出该轮廓的质心以及角度。
{
RotatedRect box=minAreaRect(contours[i]);//定义一个成员,存储最小包围举行的信息。
//定义一个点数组,暂时存放四个角点信息,以供后续画图
Point2f vertex[4];
box.points(vertex);
if (box.size.height >box.size.width )
angle[i]=-box.angle;
else angle[i]=-box.angle+90;
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
// for(int j=0;j<4;j++)
// {
// line(drawing,vertex[j],vertex[(j+1)%4], Scalar(100,200,211) ,2,LINE_AA);
// }
circle(drawing, mc[i], 4, color, -1, 8, 0);
printf("Contour[%d]质心:(%f,%f)\n",i,mc[i].x,mc[i].y);
printf("角度:%f,面积:%.2f\n",angle[i],contourArea(contours[i]));
}
}
namedWindow("轮廓图", WINDOW_AUTOSIZE);
imshow("轮廓图", drawing);
imwrite("2.jpg",drawing);
//用moments矩集计算轮廓面积并与opencv函数计算结果进行比较
// printf("\t Info: Area and Contour Length \n");
// for (int i = 0; i < contours.size(); i++)
//{
// printf("* Contour[%d] - Area(M_00)=%.2f-Area OpenCV:%.2f - Length:%.2f\n", i, mu[i].m00, contourArea(contours[i]), arcLength(contours[i], true));
// Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
// circle(drawing, mc[i], 4, color, -1, 8, 0);
//}
}
评论0