不规则区域的矩,表示把一个归一化的灰度级图像函数理解为一个二维随机变量的概率密度。
这个随机变量的属性可以用统计特征--矩(Moments)来描述。通过假设非零的像素值表示区域,矩可以用于二值或灰度级的区域描述。
Mpq = sigma(i)sigma(j) ip jq f(i,j)
其中x,y,i,j是区域点的坐标(在数字图像中的像素坐标)。
令Xc,Yc表示区域重心的坐标,则:
Xc = M10/M00;
Yc = M01/M00;
在二值图像的情况下,M00表示区域的面积。
OpenCV中可以使用函数cvMoments来计算二值图像的矩信息。
使用函数cvGetSpatialMoment获得指定维的矩信息。
以上介绍转自http://blog.csdn.net/lxiaoxiaot/article/details/6539834
以下代码转自博客http://blog.163.com/forever_871226/blog/static/34424308201141851736984/ 使用OpenCV计算图像重心
/** 计算二值图像的重心 * @param[in] src 输入的待处理图像 * @param[out] center 重心坐标 * @retval 0 操作成功 * @retval -1 操作失败 * @note 输入图像是二值化图像 * @note xc=M10/M00, yc=M01/M00, 其中 Mx_order,y_order=SUMx,y(I(x,y)*x^x_order*y^y_order) */ static int aoiGravityCenter(IplImage *src, CvPoint ¢er) { //if(!src) // return GRAVITYCENTER__SRC_IS_NULL; double m00, m10, m01; CvMoments moment; cvMoments( src, &moment, 1); m00 = cvGetSpatialMoment( &moment, 0, 0 ); if( m00 == 0) return 1; m10 = cvGetSpatialMoment( &moment, 1, 0 ); m01 = cvGetSpatialMoment( &moment, 0, 1 ); center.x = (int) (m10/m00); center.y = (int) (m01/m00); return 0; }
以下代码是按照此方式进行转换的EmguCV图像重心求法,并进行了绘制。
Image<Gray, Byte> imageCenter = imageProcessG.GetSubRect(new System.Drawing.Rectangle(item.X, item.Y, item.Width, item.Height)); double m00, m01, m10; MCvMoments moment = new MCvMoments(); CvInvoke.cvMoments(imageCenter.Ptr, ref moment, 1); m00 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 0); m10 = CvInvoke.cvGetSpatialMoment(ref moment, 1, 0); m01 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 1); //System.Drawing.PointF center = new System.Drawing.PointF(item.Center.X, item.Center.Y); System.Drawing.PointF center = new System.Drawing.PointF(item.X+(float)(m10 / m00), item.Y+(float)(m01 / m00)); Ellipse tempE = new Ellipse(center, new System.Drawing.SizeF(2, 2), (float)Math.PI); imageResults.Draw(tempE, new Bgr(System.Drawing.Color.Red), 2);