OpticalFlow::~OpticalFlow() { cvReleaseImage(&m_pyramids[0]); cvReleaseImage(&m_pyramids[1]); cvReleaseImage(&m_tmpEVImage[0]); cvReleaseImage(&m_tmpEVImage[1]); if (m_pConDens) { cvReleaseConDensation(&m_pConDens); m_pConDens = NULL; } }
/** Initialize the Condensation data structure and state dynamics */ void OpticalFlow::InitCondensation(int condens_num_samples) { // initialize Condensation data structure and set the // system dynamics m_sample_confidences.resize(condens_num_samples); if (m_pConDens) { cvReleaseConDensation(&m_pConDens); } m_pConDens = cvCreateConDensation(OF_CONDENS_DIMS, OF_CONDENS_DIMS, condens_num_samples); CvMat dyn = cvMat(OF_CONDENS_DIMS, OF_CONDENS_DIMS, CV_32FC1, m_pConDens->DynamMatr); // CvMat dyn = cvMat(OF_CONDENS_DIMS, OF_CONDENS_DIMS, CV_MAT3x3_32F, m_pConDens->DynamMatr); cvmSetIdentity(&dyn); cvmSet(&dyn, 0, 1, 0.0); cvmSet(&dyn, 2, 3, 0.0); // initialize bounds for state float lower_bound[OF_CONDENS_DIMS]; float upper_bound[OF_CONDENS_DIMS]; // velocity bounds highly depend on the frame rate that we will achieve, // increase the factor for lower frame rates; // it states how much the center can move in either direction in a single // frame, measured in terms of the width or height of the initial match size double velocity_factor = .25; double cx = (m_condens_init_rect.left+m_condens_init_rect.right)/2.0; double cy = (m_condens_init_rect.top+m_condens_init_rect.bottom)/2.0; double width = (m_condens_init_rect.right-m_condens_init_rect.left)*velocity_factor; double height = (m_condens_init_rect.bottom-m_condens_init_rect.top)*velocity_factor; lower_bound[0] = (float) (cx-width); upper_bound[0] = (float) (cx+width); lower_bound[1] = (float) (-width); upper_bound[1] = (float) (+width); lower_bound[2] = (float) (cy-height); upper_bound[2] = (float) (cy+height); lower_bound[3] = (float) (-height); upper_bound[3] = (float) (+height); lower_bound[4] = (float) (-10.0*velocity_factor*M_PI/180.0); upper_bound[4] = (float) (+10.0*velocity_factor*M_PI/180.0); CvMat lb = cvMat(OF_CONDENS_DIMS, 1, CV_MAT3x1_32F, lower_bound); CvMat ub = cvMat(OF_CONDENS_DIMS, 1, CV_MAT3x1_32F, upper_bound); cvConDensInitSampleSet(m_pConDens, &lb, &ub); // set the state that will later be computed by condensation to // the currently observed state m_condens_state.x = cx; m_condens_state.y = cy; m_condens_state.vx = 0; m_condens_state.vy = 0; m_condens_state.angle = 0; // debugging: // DbgSetModuleLevel(LOG_CUSTOM1, 3); }
CCondens::~CCondens() { cvReleaseConDensation(&ConDens); } // ~CCondens
//パーティクルフィルタ void particleFilter() { int i, c; double w = 0.0, h = 0.0; cv::VideoCapture capture(0); //CvCapture *capture = 0; //capture = cvCreateCameraCapture (0); int n_stat = 4; int n_particle = 4000; CvConDensation *cond = 0; CvMat *lowerBound = 0; CvMat *upperBound = 0; int xx, yy; capture >> capframe; //1フレームキャプチャし,キャプチャサイズを取得する. //frame = cvQueryFrame (capture); //redimage=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); //greenimage=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); //blueimage=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); w = capframe.cols; h = capframe.rows; //w = frame->width; //h = frame->height; cv::namedWindow("Condensation", CV_WINDOW_AUTOSIZE); cv::setMouseCallback("Condensation", on_mouse, 0); //cvNamedWindow ("Condensation", CV_WINDOW_AUTOSIZE); //cvSetMouseCallback("Condensation",on_mouse,0); //フォントの設定 //CvFont dfont; //float hscale = 0.7f; //float vscale = 0.7f; //float italicscale = 0.0f; //int thickness = 1; //char text[255] = ""; //cvInitFont (&dfont, CV_FONT_HERSHEY_SIMPLEX , hscale, vscale, italicscale, thickness, CV_AA); //Condensation構造体を作成する. cond = cvCreateConDensation (n_stat, 0, n_particle); //状態ベクトル各次元の取りうる最小値・最大値を指定する //今回は位置(x,y)と速度(xpixcel/frame,ypixcel/frame)の4次元 lowerBound = cvCreateMat (4, 1, CV_32FC1); upperBound = cvCreateMat (4, 1, CV_32FC1); cvmSet (lowerBound, 0, 0, 0.0); cvmSet (lowerBound, 1, 0, 0.0); cvmSet (lowerBound, 2, 0, -20.0); cvmSet (lowerBound, 3, 0, -20.0); cvmSet (upperBound, 0, 0, w); cvmSet (upperBound, 1, 0, h); cvmSet (upperBound, 2, 0, 20.0); cvmSet (upperBound, 3, 0, 20.0); //Condensation構造体を初期化する cvConDensInitSampleSet (cond, lowerBound, upperBound); //ConDensationアルゴリズムにおける状態ベクトルのダイナミクスを指定する cond->DynamMatr[0] = 1.0; cond->DynamMatr[1] = 0.0; cond->DynamMatr[2] = 1.0; cond->DynamMatr[3] = 0.0; cond->DynamMatr[4] = 0.0; cond->DynamMatr[5] = 1.0; cond->DynamMatr[6] = 0.0; cond->DynamMatr[7] = 1.0; cond->DynamMatr[8] = 0.0; cond->DynamMatr[9] = 0.0; cond->DynamMatr[10] = 1.0; cond->DynamMatr[11] = 0.0; cond->DynamMatr[12] = 0.0; cond->DynamMatr[13] = 0.0; cond->DynamMatr[14] = 0.0; cond->DynamMatr[15] = 1.0; //ノイズパラメータを再設定する. cvRandInit (&(cond->RandS[0]), -25, 25, (int) cvGetTickCount ()); cvRandInit (&(cond->RandS[1]), -25, 25, (int) cvGetTickCount ()); cvRandInit (&(cond->RandS[2]), -5, 5, (int) cvGetTickCount ()); cvRandInit (&(cond->RandS[3]), -5, 5, (int) cvGetTickCount ()); while (1) { capture >> capframe; //frame = cvQueryFrame (capture); //各パーティクルについて尤度を計算する. for (i = 0; i < n_particle; i++) { xx = (int) (cond->flSamples[i][0]); yy = (int) (cond->flSamples[i][1]); if (xx < 0 || xx >= w || yy < 0 || yy >= h) { cond->flConfidence[i] = 0.0; } else { cond->flConfidence[i] = calc_likelihood (capframe, xx, yy); //cond->flConfidence[i] = calc_likelihood (frame, xx, yy); cv::circle(capframe, cv::Point(xx, yy), 1, CV_RGB(0, 255, 200)); //cvCircle (frame, cvPoint (xx, yy), 1, CV_RGB (0, 255, 200), -1); } } //重みの総和&重心を求める double wx = 0, wy = 0; double sumWeight = 0; for (i = 0; i < n_particle; i++) { sumWeight += cond->flConfidence[i]; } for (i = 0; i < n_particle; i++) { wx += (int) (cond->flSamples[i][0]) * (cond->flConfidence[i] / sumWeight); wy += (int) (cond->flSamples[i][1]) * (cond->flConfidence[i] / sumWeight); } //重心表示 cv::circle(capframe, cv::Point((int)wx, (int)wy), 10, cv::Scalar(0, 0, 255)); cv::circle(capframe, cv::Point(20, 20), 10, CV_RGB(red, green, blue), 6); cv::putText(capframe, "target", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 0.7, CV_RGB(red, green, blue)); cv::imshow("Condensation", capframe); //cvCircle(frame,cvPoint(20,20),10,CV_RGB(red,green,blue),-1); //cvPutText(frame,"target",cvPoint(0,50),&dfont,CV_RGB(red,green,blue)); //cvShowImage ("Condensation", frame); c = cv::waitKey(30); //c = cvWaitKey (30); if (c == 27) break; //次のモデルの状態を推定する cvConDensUpdateByTime (cond); } cv::destroyWindow("Condensation"); //cvDestroyWindow ("Condensation"); //cvReleaseCapture (&capture); //cvReleaseImage(&redimage); //cvReleaseImage(&greenimage); //cvReleaseImage(&blueimage); cvReleaseConDensation (&cond); cvReleaseMat (&lowerBound); cvReleaseMat (&upperBound); }