void C_HuMoments::getHuMoments(IplImage * img, double * Hu, uchar thresh, uchar density)
{
if (NULL == Hu)
return;
double m_00 = 0, m_10 = 0, m_01 = 0;
double u_11 = 0, u_20 = 0, u_02 = 0, u_30 = 0, u_03 = 0, u_12 = 0, u_21 = 0;
getStdMoment(img, m_00, m_01, m_10, thresh, density);
double x_0, y_0;
if (m_00 == 0) return;
//計算圖像中心
double c_x = m_10 / m_00;
double c_y = m_01 / m_00;
uchar binary = 0;
//計算中心矩
for (int j = 0; j < img->height; j = j + density)
{
uchar *p_line = (uchar *)(img->imageData + j * img->widthStep);
for (int i = 0; i < img->width; i = i + density)
{
if (p_line[i] < thresh) continue;
x_0 = i - c_x;
y_0 = j - c_y;
u_11 += x_0 * y_0;
u_20 += x_0 * x_0;
u_02 += y_0 * y_0;
u_30 += x_0 * x_0 * x_0;
u_03 += y_0 * y_0 * y_0;
u_12 += x_0 * y_0 * y_0;
u_21 += x_0 * x_0 * y_0;
}
}
//歸一化中心矩
double m2 = pow(m_00, 2);
double m2_5 = pow(m_00, 2.5);
u_11 = u_11 / m2; u_20 = u_20 / m2; u_02 = u_02 / m2;
u_30 = u_30 / m2_5; u_03 = u_03 / m2_5; u_12 = u_12 / m2_5; u_21 = u_21 / m2_5;
//計算hu矩
double t[5];
t[0] = u_20 - u_02; t[1] = u_30 - 3 * u_12; t[2] = 3 * u_21 - u_03;
t[3] = u_30 + u_12; t[4] = u_21 + u_03;
Hu[0] = u_20 + u_02;
Hu[1] = t[0] * t[0] + 4 * u_11*u_11;
Hu[2] = t[1] * t[1] + t[2] * t[2];
Hu[3] = t[3] * t[3] + t[4] * t[4];
Hu[4] = t[1] * t[3] * (t[3] * t[3] - 3 * t[4] * t[4]) + t[2] * t[4] * (3 * t[3] * t[3] - t[4] * t[4]);
Hu[5] = t[0] * (t[3] * t[3] - t[4] * t[4]) + 4 * u_11*t[3] * t[4];
Hu[6] = t[2] * t[3] * (t[3] * t[3] - 3 * t[4] * t[4]) - t[1] * t[4] * (3 * t[3] * t[3] - t[4] * t[4]);
Hu[7] = m_00 / (float)(img->width * img->height);
Hu[8] = (float)img->width / (float)img->height;
}
void C_HuMoments::getHuMomentsByOpencv(IplImage *img, double *Hu)
{
CvMoments moment;
cvMoments(img, &moment, 2);
CvHuMoments humoment;
cvGetHuMoments(&moment, &humoment);
Hu[0] = humoment.hu1;
Hu[1] = humoment.hu2;
Hu[2] = humoment.hu3;
Hu[3] = humoment.hu4;
Hu[4] = humoment.hu5;
Hu[5] = humoment.hu6;
Hu[6] = humoment.hu7;
}