Распознавание образов для программистов

ВНИМАНИЕ! БЛОГ ПЕРЕЕХАЛ ПО АДРЕСУ
RECOG.RU

26 Март 2011

Слежение за баскетбольным мячом

написано в рубрике: OpenCV, Распознавание образов — Кручинин Александр @ 3:32 ПП

Известен подход выделения объектов на изображениях по распределению цветовой гаммы. Данный подход является в своей основе достаточно простым, но, не смотря на это, может использоваться в ряде случае. Иногда этот подход применяется как первоначальный этап обработки изображения, для решения более сложных задач, например детектирования лиц [1]. Такой подход может использоваться и в системах трекинга, если цвет объекта отличается от фона.

Рассмотрим задачу отслеживания движений баскетбольного мяча. Есть входной поток изображения. На каждом кадре изображения необходимо определить наличие или отсутствие баскетбольного мяча. Мяч при детектировании выделить окружностью.

Решение задачи разбивается на несколько этапов:

  • выделения пикселей, соответствующих баскетбольному мячу;
  • выделение контурами найденные объекты;
  • нахождении контура мяча;
  • построение окружности, в которую попадают все точки контура мяча.

С помощью средств OpenCV данная задача решается очень просто. На рисунках 1а представлены примеры кадров с баскетбольным мячом. Мячу соответствуют в основном оранжевые пиксели. Поэтому для выделения большинства из них достаточно следующего условия:

R > 1.5*G, R > 2*B,

где R, G, и B – соответствующие компоненты пикселя.

Условие подобрано примерно и работает удовлетворительно. На рисунках 1б представлены результаты выделения пикселей, соответствующих мячу, что показано в виде белых пикселей на чёрном фоне.

out1-5

out1-20

out1-100

а)

out2-5

out2-20

out2-100

б)

Рис. 1. Исходные изображения (а), изображения с выделенными пикселями, соответствующими цвету мяча (б)

Пример использования контуров в OpenCV приведен здесь http://blog.vidikon.com/?p=59. Из найденных контуров необходимо выделения максимального, который в данном примере будет соответствовать мячу (см. листинг). Результаты выделения максимального контура представлены на рисунке 2а.

Далее необходимо найти центр и радиус окружности, соответствующей области мяча. Для этого в OpenCV есть функция cvMinEnclosingCircle. Ниже приведено её описание.

int cvMinEnclosingCircle(const CvArr* points,

CvPoint2D32f* center,

float* radius);

Параметры:

points – последовательность или массив 2D точек;

center – выходной параметр: центр окружности;

radius – выходной параметр: радиус окружности.

Функция ищет минимальную окружность, включающую в себя все точки последовательности. При невозможности найти окружность функция возвращает 0.

На рисунке 2б приведены примеры выделения окружностей для приведенных случаев.

out3-5

out3-20

out3-100 а)

out4-5

out4-20

out4-100 б)

Рис. 2. Выделение контура мяча (а), выделение окружности (б)

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

#include “cv.h”

#include “highgui.h”

#include <stdio.h>

#include <ctype.h>

void FindBall(IplImage* Img);

void Counter(IplImage* img);

CvPoint2D32f center;

float radius;

long pointer=0;

int main( int argc, char** argv )

{

CvCapture* capture = 0;

capture = cvCaptureFromAVI( “capture-1.avi” );

cvNamedWindow( “Demo”, 1 );

for(;;)

{

IplImage* frame = 0;

int i, k, c;

frame = cvQueryFrame( capture );

if( !frame )

break;

FindBall(frame);

cvShowImage( “Demo”, frame );

c = cvWaitKey(50);

if( (char)c == 27 )

break;

pointer++;

}

cvWaitKey(0);

cvReleaseCapture( &capture );

cvDestroyWindow(”Demo”);

return 0;

}

void FindBall(IplImage* Img)

{

IplImage* Image=cvCreateImage( cvGetSize(Img), 8, 3 );

cvCopy(Img,Image);

//Теперь необходимо получить доступ к всем пикселям.

uchar* ptr1;

ptr1 = (uchar*) (Image->imageData );

int i,j;

for(i=0;i<Img->height;i++)

for(j=0;j<Img->width;j++)

{

//R > 1.5*G, R > 2*B

if (ptr1[j*3+2+i*Image->widthStep]>1.5*ptr1[j*3+1+i*Image->widthStep] &&

ptr1[j*3+2+i*Image->widthStep]>2*ptr1[j*3+i*Image->widthStep])

{

ptr1[j*3+i*Image->widthStep]=255;

ptr1[j*3+1+i*Image->widthStep]=255;

ptr1[j*3+2+i*Image->widthStep]=255;

}

else

{

ptr1[j*3+i*Image->widthStep]=0;

ptr1[j*3+1+i*Image->widthStep]=0;

ptr1[j*3+2+i*Image->widthStep]=0;

}

}

//Выделение контуров и поиск наибольшего контура

Counter(Image);

if (center.x>-1)

{

CvPoint p;

p.x=center.x;

p.y=center.y;

cvCircle( Img, p, radius, CV_RGB(255,0,0), 3, 8, 0 );

}

cvReleaseImage( &Image );

}

void Counter(IplImage* img)

{

IplImage* img_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1);

CvSeq* contours = 0;

CvMemStorage* storage = cvCreateMemStorage(0);

cvCvtColor( img, img_gray, CV_BGR2GRAY );

cvFindContours( img_gray, storage, &contours, sizeof(CvContour),

CV_RETR_LIST  , CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

CvSeq* h_next=0;

//Поиск максимального контура

for( CvSeq* c=contours; c!=NULL; c=c->h_next )

{

if (c!=contours)

{

//Проверяем какой контур больше

if (h_next->total>=c->total)

{

h_next->h_next=h_next->h_next->h_next;

continue;

}

}

h_next=c;

}

center.x=-1;

if (h_next->total<200) return;//нет  мяча – слишком маленькие контуры

cvDrawContours( img, h_next, CV_RGB(255,0,0), CV_RGB(0,255,0),2, 2, CV_AA, cvPoint(0,0) );

//Минимальная окружность

cvMinEnclosingCircle(h_next,&center,&radius);

cvReleaseMemStorage( &storage);

cvReleaseImage( &img_gray );

}

Ролик слежения за мячом.

Литература:

1. Yunlong Zhao, Tat-Seng Chua. Automatic Tracking of Face Sequences in MPEG Video. In Proceedings of Computer Graphics International’2003. pp.170~175

Работает на WordPress