图像的矩

/*模式识别  目标分类 目标识别 方位估计 图像编码重构

使用moments计算图像所有的矩 最高3阶
使用contourArea 计算轮廓面积
使用arcLength计算轮廓或曲线长度

矩的计算  Moments moments (inputarray array,//  可以是光栅图像 单通道 8位或浮点的二位数组
					Bool binaryImage=false// 默认false 或是true则素有非零像素为1);

计算轮廓面积:
		double contourArea(inputarray contour,//输入向量 mat vector
					Bool oriented=false//面向区域标识符 若是true 返回一个带符号的面积值,取决于轮廓的方向
					);

计算轮廓长度:double arcLength( inputarray curve,//点集 mat vector
						Bool closed// 是否封闭
						)
*/


#include <opencv2//highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

//*********************************
//		查找和绘制图像轮廓矩
//*********************************

#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【图像轮廓】"

Mat g_srcImage;
Mat g_grayImage;
Mat 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*);
static void ShowHelpText();

int main()
{
	system("color 1E");
	g_srcImage = imread("C:/Users/hasee-pc/Desktop/women.jpg",1);

	//原图转灰度平滑
	cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
	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(g_grayImage,//输入
		g_cannyMat_output,//输出
		g_nThresh, //最小阈值
		g_nThresh * 2, //最大阈值
		3//sobel算子
	);

	//找到轮廓
	findContours(g_cannyMat_output,//输入图
		g_vContours,//检测到的轮廓值
		g_vHierarchy,//输出向量
		RETR_TREE,//轮廓检索模式
		CHAIN_APPROX_SIMPLE,//轮廓近似方法
		Point(0, 0)//轮廓点偏移量
	);

	//计算矩
	vector<Moments> mu(g_vContours.size());
	for (unsigned int i = 0; i < g_vContours.size(); ++i)
	{
		mu[i] = moments(g_vContours[i], false);
	}
	//计算矩中心
	vector<Point2f> mc(g_vContours.size());
	for (unsigned 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].m10/mu[i].m00));
	}
	//绘制轮廓
	Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
	for (unsigned 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计算轮廓面积并且和Opecv函数比较
		printf("\t 输出内容:面积和轮廓长度\n");
		for (unsigned int i = 0; i < g_vContours.size(); ++i)
		{

			printf(" >通过 m00计算出轮廓[%d]的面积:(M_00) = %.2f \n OpenCV 函数计算出的面积=%.2f , "
				"长度:%.2f \n\n", 
				i,
				mu[i].m00,
				contourArea(g_vContours[i]),//轮廓面积
				arcLength(g_vContours[i],true)//轮廓曲线长度
			);
			//随机颜色
			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);线条形态
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值