Моменты в OpenCV / OpenCV / Recog.ru - Распознавание образов для программистов


Моменты в OpenCV

Момент – это характеристика контура, объединённая (суммированная) со всеми пикселями контура. Момент (p,q) определяется как:

Здесь p – порядок x, q – порядок y, где порядок означает, так сказать, мощность, на которой соответствующий компонент взят в сумме с другими отображенными.
Описывает моменту структура CvMoments.
typedef struct CvMoments{
	// пространственные моменты
	double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
	// центральные моменты
	double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
	// m00 != 0 ? 1/sqrt(m00) : 0
	double inv_sqrt_m00;
} CvMoments;

В структуре появились ещё и центральные моменты, которые вычисляются по следующей формуле:

где xavg = m10/ m00 и yavg = m01/ m00.
Центральные моменты можно нормализовать с помощью функции cvGetNormalizedCentralMoment. Нормализованные моменты вычисляются следующим образом:

Ну и остались ещё инвариантные моменты. Идея здесь в том, что комбинируя различные нормализованные центральные моменты, возможно создавать инвариантные функции, представляющие различные аспекты изображения, которые не зависят от масштабов, вращения и отражения.
В документации к OpenCV приведены следующие формулы:

Ниже приведены функции для расчета моментов.
void cvMoments( 
	const CvArr* arr, 
	CvMoments* moments, 
	int binary=0 
);

Параметры:
arr
Изображение, с которого мы хотим получить моменты (не забываем про то, что это можно применять к участку изображения с помощью ROI).
moments
Сюда будут записываться моменты.
binary
Если этот флаг не равен 0, то все не нулевые пиксели приравниваются к единице.
void cvGetHuMoments( 
	CvMoments* moments, 
	CvHuMoments* hu_moments 
);

Параметры:
moments
Моменты полученные в предыдущей функции, модифицированные cvGetNormalizedCentralMoment().
hu_moments
Результирующие инвариантные моменты.

Пример вычисления моментов приведен здесь. Но как сравнивать моменты? Оказывается для сравнения есть функция cvMatchShapes.
double cvMatchShapes(
	const void* object1,
	const void* object2,
	int method,
	double parameter = 0
);

Параметры:
object1 и object2 – первый и второй контуры или изображения в градациях серого.
method – метод сравнения.
Ну а последний параметр пока не используется.
Функция сравнивает моменты CvHuMoments. На настоящий момент поддерживаются 3 метода:
CV_CONTOURS_MATCH_I1

CV_CONTOURS_MATCH_I2

CV_CONTOURS_MATCH_I3

Остальные параметры рассчитываются по следующей формуле:

Логично предположить, что чем меньше будет возвращаемое значение cvMatchShapes, тем более похожи друг на друга объекты A (1) и B (2).
Однако, вы наверное заметили, что функция cvMatchShapes не принимает параметры CvHuMoments. Тогда зачем, спрашивается, мы считали параметры с помощью cvGetHuMoments. Да и зачем хранить контуры и изображения, если можно хранить моменты. К счастью, есть открытый исходный код – поэтому меняем код как нам нужно
double cvMatchShapesNew( CvHuMoments HuMoments1, CvHuMoments HuMoments2,
               int method)
{
...
    ma[0] = HuMoments1.hu1;
    ma[1] = HuMoments1.hu2;
    ma[2] = HuMoments1.hu3;
    ma[3] = HuMoments1.hu4;
    ma[4] = HuMoments1.hu5;
    ma[5] = HuMoments1.hu6;
    ma[6] = HuMoments1.hu7;

    mb[0] = HuMoments2.hu1;
    mb[1] = HuMoments2.hu2;
    mb[2] = HuMoments2.hu3;
    mb[3] = HuMoments2.hu4;
    mb[4] = HuMoments2.hu5;
    mb[5] = HuMoments2.hu6;
    mb[6] = HuMoments2.hu7;
...
  • 0
  • 29 апреля 2011, 16:21
  • vidikon

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.