Jump to content
Compvision.ru
Sign in to follow this  
Smorodov

Шаблоны движения (motion templates)

Recommended Posts

Спасибо за ответ. К сожалению в вашем списке нет сорцов по MHI.

Прилепил работу Брадского к посту. А вот результат:

OpenCV motion segmentation and pose recognition.

Хочу то-же самое, но не фронтальной камерой, а 360° fish eye, которая висит под потолком.

В любой части комнаты встаю в позу Y - включается вентилятор. Скрещиваю руки над головой - выключается. :)

wacv00.pdf

Share this post


Link to post
Share on other sites
Спасибо за ответ. К сожалению в вашем списке нет сорцов по MHI.

Прилепил работу Брадского к посту. А вот результат:

OpenCV motion segmentation and pose recognition.

Хочу то-же самое, но не фронтальной камерой, а 360° fish eye, которая висит под потолком.

В любой части комнаты встаю в позу Y - включается вентилятор. Скрещиваю руки над головой - выключается. :)

Насколько я понимаю, фон не меняется, иначе получите много трудно отделяемых помех.

А если фон не меняется, то зачем Вам знать что куда движется?

При такой постановке задачи вполне хватит анализ контуров (вычисление моментов контура).

А изображение с fish eye нужно преобразовать к обычному линейному (например калибровкой):

http://www.compvision.ru/forum/index.php?showtopic=116

http://www.compvision.ru/forum/index.php?showtopic=47

Можно попробовать еще использовать скелетные изображения:

http://www.compvision.ru/forum/index.php?showtopic=30

которые уже нормировать и скармливать классификатору, нейросетке например.

Share this post


Link to post
Share on other sites

Вы правы, но я наивно полагаю, что шаблоны движения реализовать будет значительно проще, да и ресурсы им достаточны самые эмБЕДНЫЕ.

Вот нашёл систему прототайпинга:

http://eyepatch.stanford.edu/

Завтра поутру наснимаю кучу жестов в разных углах комнаты и буду их прогонять через фильтр движения айпэтча.

Поглядим, как будут определяться жесты. Смотрел бегло в оупенсивишные сорцы айпетча. Помоему они запоминают не только значение ху моментов но и угол.

Угол мне не нужен, придётся вырезать его из распознавалки айпетча.

Если определение будет нестабильным, пойду Вашим путём с отсечением фона, контурами, классификаторами.

Преобразование рыбьего глаза в панораму камера умеет делать сама.

Вам интересна задачка? Хотите пару фильмов для тестов? :)

Лимит темы на прикрепление файлов исчерпался, а то бы я Вам уже картинку рыбоглазую скинул 2048 х 1536. :(

Share this post


Link to post
Share on other sites

Своял грубейший прототип. РАБОТАЕТ! В приложении "мой" грязнокод.

Мотрек записывает по нажатию клавиши битмэпы с шаблонами движения. Дальше глазами просматривается записанное и один желаемый битмэп переносится в папку к моту.

Мот грузит один битмэп и проверяет поток на шаблон. Если совпадение больше чем пороговое значение - распознал и окружность рисуется красным.

Быдлокод слизан с примера OpenCV и очень сырой. Путь к камере и имя файла с шаблоном надо прописывать в коде жёстко.

OpenCV 2.0 with IPP and ffmpeg, Ubuntu Linux, gcc, qmake, Qt Creator

Камера 360° fish eye Mobotix Q24 800 х 600

Ругайте!

mot.zip

Share this post


Link to post
Share on other sites

Добрый день!. вопрос про шаблоны движения. Как мне укоротить хвост который идет за объектом. Я пробовал выставлять такие параметры

const double MHI_DURATION = 0.1;

const double MAX_TIME_DELTA = 0.1;

const double MIN_TIME_DELTA = 0.05;

const int N = 10;

в результате получил post-803-1288347724_thumb.jpg

как видите я получил как бы 2е копии машины.. как мне от этого избавиться ?

Share this post


Link to post
Share on other sites
Добрый день!. вопрос про шаблоны движения. Как мне укоротить хвост который идет за объектом. Я пробовал выставлять такие параметры

const double MHI_DURATION = 0.1;

const double MAX_TIME_DELTA = 0.1;

const double MIN_TIME_DELTA = 0.05;

const int N = 10;

в результате получил post-803-1288347724_thumb.jpg

как видите я получил как бы 2е копии машины.. как мне от этого избавиться ?

Может Вам лучше использовать что то типа bgfg_codebook или bgfg_segmentation? Эти примеры есть в opencv.

ЗЫ: codebook вначале собирает статистику фона, и показывает черный экран вместо результата. Дождитесь пока соберет, это секунд 15.

Share this post


Link to post
Share on other sites

Попробуй перебрать всевозможные результаты параметров, посмотри, что можно "выжать" из этого.

Вообще, всё зависит от того, что ты хочешь получить. Что-то вроде вычитания фона?

Share this post


Link to post
Share on other sites

я просто хотел обозначить области в которых есть движение... для меня кртитична скорость.. и вполне достаточно програмы шаблона движения.. просто хотенлось этот хвост убрать.. я выставил историю равной 2 кадрам.. а круг изображений равным 10, чтоб объекты закрасились синим.. но.. я так и непонял почему у меня получилось 2 изображения.. если взять круг не 10 а 40 кадров, эти 2 изображения разойдуться.. но ведь историю я ставлю 2 изображения.. почему так получается..??

Share this post


Link to post
Share on other sites

По данному сабжу возникла проблема. :unsure:

При использовании update_mhi потребовалось изменять размеры захватываемых объектов в пикселях.

Причина в том, что на одном и том же человеке (речь об алгоритме пересечения границы) выделяются от двух и более точек движения.

Идея в том, чтобы ограничить comp_rect, чтобы не менее 100 пикселей и не более 300 пикселей.

конкретно в этом условии стандартной функции:

if( (comp_rect.width + comp_rect.height > sb4pos ) && (comp_rect.width + comp_rect.height < sb5pos) ) 

Проблема в том, что возвращаемое значение comp_rect.width превышает 3 миллиона, а comp_rect.height=1920.

Вопрос: почему так происходит и что необходимо исправить, чтобы всё заработало? :rolleyes:

Share this post


Link to post
Share on other sites

Ну, для начала надо бы узнать как и откуда получаются эти значения. Есть возможность заглянуть с отладчиком внутрь OpenCV?

Share this post


Link to post
Share on other sites

А куда смотреть то конкретно?

Лучше один раз увидеть, поэтому...

В прикрепленном: проект под OpenCV 2.4 в MVS 2010

6 реализаций update_mhi в отдельности для каждой камеры. Вызов функции из первого таймера.

Работает с файлом 18.avi, производит сохранение на D:\

Вот целиком проект:

Скачать (~350Mb)

Скачать с другого файлообменника (~350Mb)

Share this post


Link to post
Share on other sites

Вот пример функции update_mhi:

void update_mhi1( IplImage* img, IplImage* dst, int diff_threshold, int sb4pos, int sb5pos)

{

	double timestamp = (double)clock()/CLOCKS_PER_SEC; // get current time in seconds

	CvSize size = cvSize(img->width,img->height); // get current frame size

	int i, idx1 = last1, idx2;

	IplImage* silh=0;

	CvSeq* seq=0;

	CvRect comp_rect;

	double count;

	double angle;

	CvPoint center;

	double magnitude;

	CvScalar color;


// number of cyclic frame buffer used for motion detection

// (should, probably, depend on FPS)


	// allocate images at the beginning or

	// reallocate them if the frame size is changed

	if( !mhi1 || mhi1->width != size.width || mhi1->height != size.height ) 

	{

		if( buf1 == 0 ) 

		{

			buf1 = (IplImage**)malloc(N*sizeof(buf1[0]));

			memset( buf1, 0, N*sizeof(buf1[0]));

		}

		for( i = 0; i < N; i++ ) 

		{

			cvReleaseImage( &buf1[i] );

			buf1[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );

			cvZero( buf1[i] );

		}

	  cvReleaseImage( &mhi1 );

	  cvReleaseImage( &orient1 );

	  cvReleaseImage( &segmask1 );

	  cvReleaseImage( &mask1 );

	  mhi1 = cvCreateImage( size, IPL_DEPTH_32F, 1 );

	  cvZero( mhi1 ); // clear MHI at the beginning

	  orient1 = cvCreateImage(size, IPL_DEPTH_32F, 1 );

	  segmask1 = cvCreateImage(size, IPL_DEPTH_32F, 1 );

	  mask1 = cvCreateImage(size, IPL_DEPTH_8U, 1 );

	}

	cvCvtColor( img, buf1[last1], CV_BGR2GRAY ); // convert frame to grayscale

	idx2 = (last1 + 1) % N; // index of (last - (N-1))th frame

	last1 = idx2;

	silh = buf1[idx2];

	cvAbsDiff( buf1[idx1], buf1[idx2], silh ); // get difference between frames

	cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY ); // and threshold it

	cvUpdateMotionHistory( silh, mhi1, timestamp, MHI_DURATION ); // update MHI

	// convert MHI to blue 8u image

	cvCvtScale( mhi1, mask1, 255./MHI_DURATION,

	(MHI_DURATION - timestamp)*255./MHI_DURATION );

	cvZero( dst );

	cvCvtPlaneToPix( mask1, 0, 0, 0, dst );

	// calculate motion gradient orientation and valid orientation mask

	cvCalcMotionGradient( mhi1, mask1, orient1, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 );

	if( !storage1 )

	storage1 = cvCreateMemStorage(0);

	else

	cvClearMemStorage(storage1);

	// segment motion: get sequence of motion components

	// segmask is marked motion components map. It is not used further

	seq = cvSegmentMotion( mhi1, segmask1, storage1, timestamp, MAX_TIME_DELTA );

	// iterate through the motion components,

	// One more iteration (i == -1) corresponds to the whole image (global motion)

	for( i = -1; i < seq->total; i++ ) 

	{

		if( i < 0 ) 

		{ // case of the whole image

			comp_rect = cvRect( 0, 0, size.width, size.height );

			color = CV_RGB(255,255,255);

			magnitude = 100;

		}

		else 

		{ // i-th motion component

		comp_rect = ((CvConnectedComp*)cvGetSeqElem( seq, i ))->rect;

		if( (comp_rect.width + comp_rect.height > sb4pos ) && (comp_rect.width + comp_rect.height < sb5pos) ) 

			// reject very small and very big components

		continue;

		color = CV_RGB(0,255,0);

		magnitude = 100;

		}

	// select component ROI

	cvSetImageROI( silh, comp_rect );

	cvSetImageROI( mhi1, comp_rect );

	cvSetImageROI( orient1, comp_rect );

	cvSetImageROI( mask1, comp_rect );

	// calculate orientation

	angle = cvCalcGlobalOrientation( orient1, mask1, mhi1, timestamp,MHI_DURATION);

	//angle = 360.0 - angle; // adjust for images with top-left origin

	count = cvNorm( silh, 0, CV_L1, 0 ); // calculate number of points within silhouette ROI

	cvResetImageROI( mhi1 );

	cvResetImageROI( orient1 );

	cvResetImageROI( mask1 );

	cvResetImageROI( silh );

	// check for the case of little motion


	if( count < comp_rect.width*comp_rect.height * 0.05 )

	continue;

	// draw a clock with arrow indicating the direction

	center = cvPoint( (comp_rect.x + comp_rect.width/2),(comp_rect.y + comp_rect.height/2) );

	cvCircle( dst, center, cvRound(magnitude*1.2), color, 3, CV_AA, 0 );

	cvLine( dst, center, cvPoint( cvRound( center.x + magnitude*cos(angle*CV_PI/180)),

	cvRound( center.y - magnitude*sin(angle*CV_PI/180))), color, 3, CV_AA,0 );

	cvLine(dst,cvPoint(0,trackleft1pos),cvPoint(640, trackright1pos), color, 2, CV_AA,0);

	if (onkey)

	if (((center.x*k1+trackleft1pos<center.y+2)&&((center.x*k1+trackleft1pos>center.y-2)))&&(angle>-1)&&(angle<181))

	{incount1++;

	allcount=allcount++;}

	if (onkey)

	if (((center.x*k1+trackleft1pos<center.y+2)&&((center.x*k1+trackleft1pos>center.y-2)))&&(angle>180)&&(angle<360))

	{outcount1++;

	allcount=allcount++;}

  }

}

Share this post


Link to post
Share on other sites

У меня Линукс стоит и очень не хочется переделывать твой проект под него. А насколько проблемно тебе скомпилировать всё в Дебаге и пошариться в отладчике по функциям OpenCV?

Share this post


Link to post
Share on other sites

И в моей (2.49) версии OpenCV не находится функция cvCvtPlaneToPix. Короче, по правилам хорошего тона тебе надо сделать минимальный консольный проектик, в котором повторяется проблема. Или даже не проекти, а исходник с main, в котором захватывается определённое видео.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×