不規則區域的矩,表示把一個歸一化的灰度級圖像函數理解爲一個二維隨機變量的概率密度。
這個隨機變量的屬性可以用統計特徵--矩(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);