動画シリーズ 円の検出ハフ変換を2回して正確に

ハフ変換を2回して検出物の中心座標が同じ場合は円を描画する。

サンプルから動画への変換は「while句がある動画」を参考にすること。
メモリーリークの対応は、「ヒープ領域に作られるmalloc的な関数の使用上の注意」を参考にすること。

「今日の訪問数: -
「昨日の訪問数: -
「今までの訪問数: -
名前:
コメント:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int
main (int argc, char *argv[])
{
  int i, ii;
  float *p, *pp;
  IplImage *src_img = 0, *gray_img = 0;
  CvMemStorage *storage;
  CvSeq *circles, *circles_back = 0;
  CvCapture *capture = NULL;
 
 
  /* この設定は,利用するカメラに依存する */
  capture = cvCreateCameraCapture (0);
 
  cvNamedWindow ("circles", CV_WINDOW_AUTOSIZE);
  cvNamedWindow ("平滑化", CV_WINDOW_AUTOSIZE);
  storage = cvCreateMemStorage (0);
  src_img = cvQueryFrame (capture);
  gray_img = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1);
  while (1)
    {
      src_img = cvQueryFrame (capture);
      // グレイスケールに変換
      cvCvtColor (src_img, gray_img, CV_BGR2GRAY);
      // (2)ハフ変換のための前処理(画像の平滑化を行なわないと誤検出が発生しやすい)
      cvSmooth (gray_img, gray_img, CV_GAUSSIAN, 9, 9);
      cvShowImage ("平滑化", gray_img);
 
      // (3)ハフ変換による円の検出と検出した円の描画
 
      circles =
	cvHoughCircles (gray_img, storage, CV_HOUGH_GRADIENT, 1, 100, 20, 50,
			10, MAX (gray_img->width, gray_img->height));
 
 
      for (i = 0; i < circles->total; i++)
	{
	  p = (float *) cvGetSeqElem (circles, i);
	  //printf("%d,%d\n",cvRound(p[0]),cvRound(p[1]));
	  if (circles_back != 0)
	    {
	      for (ii = 0; ii < circles_back->total; ii++)
		{
		  pp = (float *) cvGetSeqElem (circles_back, ii);
		  //printf("%d,%d\n",cvRound(pp[0]),cvRound(pp[1]));
		  if ((cvRound (p[0]) == cvRound (pp[0]))
		      && (cvRound (p[1]) == cvRound (pp[1]))) //前回と中心が一致したモノだけ円を描画する。
		    {
		      cvCircle (src_img, cvPoint (cvRound (p[0]), cvRound (p[1])), 3, CV_RGB (0, 255, 0), -1, 8, 0);	//中心点
		      cvCircle (src_img, cvPoint (cvRound (p[0]), cvRound (p[1])), cvRound (p[2]), CV_RGB (255, 0, 0), 3, 8, 0);	//円をトレース
		    }
		}
	    }
	  else
	    {
 
	    }
	}
      //cvCloneSeq(circles,(CvMemStorage *)circles_back);
      // (4)検出結果表示用のウィンドウを確保し表示する
 
      cvShowImage ("circles", src_img);
      int key = cvWaitKey (1);
      if (key >= 0)
	{
	  break;
	}
      circles_back =
	cvHoughCircles (gray_img, storage, CV_HOUGH_GRADIENT, 1, 100, 20, 50,
			10, MAX (gray_img->width, gray_img->height));
      printf ("円らしきもの%d,%dつ発見\r", circles->total,
	      circles_back->total);
    }
  cvReleaseCapture (&capture);
  cvReleaseImage (&src_img);
  cvReleaseImage (&gray_img);
  cvReleaseMemStorage (&storage);
  cvDestroyWindow ("平滑化");
  cvDestroyWindow ("circles");
  return 0;
}
 
最終更新:2010年01月27日 09:53
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。