проблемы с отслеживанием объекта camshift

#c #opencv

#c #opencv

Вопрос:

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

это мой код:

 bool destroy=false;
 CvRect box;
 CvRect track_window;   
 bool drawing_box = false;
 cv::Mat imageROI;
 IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;   
 CvHistogram *hist = 0;   
 int hdims = 16;   
 float hranges_arr[] = {0,180};   
 float* hranges = hranges_arr;   
 int vmin = 10, vmax = 256, smin = 30;   
 IplImage *image2;
 CvScalar hsv2rgb( float hue );
 CvConnectedComp track_comp;   
 CvBox2D track_box;   

 void draw_box(Mat img, CvRect rect)
 {
   imageROI= img(cv::Rect(box.x,box.y,box.width,box.height));
cv::rectangle(img, cvPoint(box.x, box.y), cvPoint(box.x box.width,box.y box.height),
          cvScalar(0,0,255) ,2);

 }

  CvScalar hsv2rgb( float hue )   
{   
   int rgb[3], p, sector;   
    static const int sector_data[][3]=   
    {{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};   
   hue *= 0.033333333333333333333333333333333f;   
    sector = cvFloor(hue);   
   p = cvRound(255*(hue - sector));   
   p ^= sector amp; 1 ? 255 : 0;   

      rgb[sector_data[sector][0]] = 255;   
     rgb[sector_data[sector][1]] = 0;   
     rgb[sector_data[sector][2]] = p;   

    return cvScalar(rgb[2], rgb[1], rgb[0],0);
}

     void my_mouse_callback( int event, int x, int y, int flags, void* param )
      {
       IplImage* frame = (IplImage*) param;

    switch( event )
       {
      case CV_EVENT_MOUSEMOVE: 
     {
      if( drawing_box )
      {
          box.width = x-box.x;
          box.height = y-box.y;
      }
  }
  break;

  case CV_EVENT_LBUTTONDOWN:
  {
      drawing_box = true;
      box = cvRect( x, y, 0, 0 );

  }
  break;

  case CV_EVENT_LBUTTONUP:
  {
      drawing_box = false;
      if( box.width < 0 )
      {
          box.x  = box.width;
          box.width *= -1;
      }

      if( box.height < 0 )
      {
          box.y  = box.height;
          box.height *= -1;
      }

      draw_box(frame, box);

  }
  break;

  case CV_EVENT_RBUTTONUP:
  {
      destroy=true;
  }
  break;

  default:
  break;
} }

    int _tmain(int argc, _TCHAR* argv[])
     {

VideoCapture cap(0);  
if(!cap.isOpened())   
    return -1;

  Mat image;
   Mat frame;
//cv::Mat image= cv::imread("1.jpg");
 cap>>image;
if (!image.data)
    return 0; 


// Display image
cv::namedWindow("Image");
cv::imshow("Image",image);

IplImage* img = new IplImage(image);
cvSmooth(img,img,CV_GAUSSIAN,3,0,0.0,0.0);
IplImage* temp = cvCloneImage(img);
cvSetMouseCallback("Image", my_mouse_callback, (void*) img);


while( 1 )
{
 if (destroy) 
{
  cvDestroyWindow("Image"); break;
}
cvCopyImage(img, temp);

if (drawing_box) 
    draw_box(temp, box);


cvShowImage("Image", temp);

if (cvWaitKey(15) == 27) 
    break;
}

cvReleaseImage(amp;temp);
cvDestroyWindow("Image");


    for(;;)
  {
      int i, bin_w, c;   

       cap >> frame;
        IplImage* frame_ipl = new IplImage(frame);
        hsv = cvCreateImage( cvGetSize(frame_ipl), 8, 3 ); 
        image2 = cvCreateImage( cvGetSize(frame_ipl), 8, 3 );
        hue = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );   
        mask = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );   
        backproject = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );   
        hist = cvCreateHist( 1, amp;hdims, CV_HIST_ARRAY, amp;hranges, 1 );   
        histimg = cvCreateImage( cvSize(320,200), 8, 3 );   
        cvZero( histimg ); 

        cvCopy( frame_ipl, image2, 0 );   
        cvCvtColor( image2, hsv, CV_BGR2HSV );   

        int _vmin = vmin, _vmax = vmax;   

        cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),   
                    cvScalar(180,256,MAX(_vmin,_vmax),0), mask );   
        cvSplit( hsv, hue, 0, 0, 0 );   

            float max_val = 0.f;   
            cvSetImageROI( hue, box );   
            cvSetImageROI( mask, box );   
            cvCalcHist( amp;hue, hist, 0, mask );   
            cvGetMinMaxHistValue( hist, 0, amp;max_val, 0, 0 );   
            cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );   
            cvResetImageROI( hue );   
            cvResetImageROI( mask );   
            track_window = box;   


            cvZero( histimg );   
            bin_w = histimg->width / hdims;   
            for( i = 0; i < hdims; i   )   
            {   
                int val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 );   
                CvScalar color = hsv2rgb(i*180.f/hdims);   
                cvRectangle( histimg, cvPoint(i*bin_w,histimg->height),   
                             cvPoint((i 1)*bin_w,histimg->height - val),   
                             color, -1, 8, 0 );   
            }   

        cvCalcBackProject( amp;hue, backproject, hist );   
        cvAnd( backproject, mask, backproject, 0 );   
         cvCamShift( backproject, track_window, cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ), amp;track_comp, amp;track_box );   
        track_window = track_comp.rect;   
        cv::rectangle(frame, track_window, cv::Scalar(0,255,0));
       cv::namedWindow("result");
       cv::imshow("result",frame);


if(waitKey(30) >= 0) break;
  }

return 0;
}
  

Комментарии:

1. Можете ли вы немного сократить свой код, чтобы он воспроизводил ошибку? Кроме того, что еще происходит с прямоугольником, перемещается ли он вообще? Кроме того, что вы пытались исправить и что не сработало?

2. пожалуйста, используйте не c-api, а c .

Ответ №1:

но я использую c-api

Что можно изменить в этом коде для IplImage :

 void draw_box(Mat img, CvRect rect)
 {
   imageROI= img(cv::Rect(box.x,box.y,box.width,box.height));
cv::rectangle(img, cvPoint(box.x, box.y), cvPoint(box.x box.width,box.y box.height),
          cvScalar(0,0,255) ,2);

 }