cv::Rect ObjectDetection::testClassifyMultiScale(cv::Mat& img, int stride, double& prob)
{
//	cv::imshow("object detector", img);
//        int c = cv::waitKey(0) & 255;

	prob = 0.0;
	int ht = img.rows;
	int wid = img.cols;

	// scale to 64 if one of the dim is less than 64
	if( ht < m_winHt || wid < m_winWid ) {
		int minzD = m_winWid;
                int minz = wid;
                if(ht*m_winWid < m_winHt*wid) { minz = ht; minzD = m_winHt; }

                double sc = ((minzD*1.0) / (double)minz);

                if(sc > 1.5) return cv::Rect(0,0,0,0);

                cv::Size sz(0,0);
                if(ht == minz) {
                        sz.height = m_winHt;
                        sz.width = (sc * img.cols);
                        cv::resize(img, img, sz, sc, 0, cv::INTER_LINEAR);
                } else {
                        sz.width = m_winWid;
                        sz.height = (sc * img.rows);
                        cv::resize(img, img, sz, 0, sc, cv::INTER_LINEAR);
                }
                ht = img.rows;
                wid = img.cols;
	}

	// multiscale detection - it calculates the max prob at diff scales
	double max_prob = 0.0;
	cv::Mat max_frame;
	cv::Rect max_frame_rect(0, 0, 0, 0);

	for(double scale = 1.0; scale <= 5.0; scale *= 1.2) {
		cv::Mat simg;
		cv::resize(img, simg, cv::Size(0, 0), (1.0/scale), (1.0/scale), cv::INTER_LINEAR);
		if( simg.rows < m_winHt || simg.cols < m_winWid)
			continue;
		int sht = simg.rows;
		int swid = simg.cols;
		for(int x = 0; x < swid; x += stride) {
			for(int y = 0; y < sht; y += stride) {
				if( (x + m_winWid) > swid || (y + m_winHt) > sht)
					continue;
				// detect
				double p = 0.0;
				cv::Mat blockImg = simg(cv::Range(y,y+m_winHt), cv::Range(x, x+m_winWid));
				this->testClassify(blockImg, p);
				if( p > max_prob) {
					max_prob = p;
					blockImg.copyTo(max_frame);
					max_frame_rect.x = (x * scale);
					max_frame_rect.y = (y * scale);
					max_frame_rect.width = (m_winWid * scale);
					max_frame_rect.height = (m_winHt * scale);
				}
			}
		}
	}
	prob = max_prob;
	cout << "Max probability: " << max_prob << endl;

	if(max_frame.data != NULL) {	
		cv::imshow("object detector", max_frame);
        	cv::waitKey(0) & 255;
	}
	
	return max_frame_rect;
}
Exemple #2
0
template <class P> static
StarDetector::Status Detect( DPoint& pos, int& radius, float threshold, const GenericImage<P>& img )
{
   img.Status().DisableInitialization();

   /*
    * Iteratively find the barycenter of a star.
    */
   for ( int it = 0; it < 10; ++it )
   {
      // Central pixel in the current search box
      Point p0 = pos;

      // Search box
      Rect r0( p0-radius, p0+radius+1 );
      if ( !img.Intersects( r0 ) )
         return StarDetector::OutsideImage;

      // Extract the search subimage
      img.SelectRectangle( r0 );
      r0 = img.SelectedRectangle(); // in case the search box is clipped
      Image simg( img );

      // Threshold background pixels
      Threshold( simg, threshold );

      // Begin searching from the brightest pixel
      if ( simg.LocateMaximumPixelValue( p0 ) == simg.MinimumPixelValue() )
         return StarDetector::NoSignificantData;

      // Coordinate and intensity accumulators.
      double sx = 0, sy = 0, si = 0;

      // Star bounding rectangle.
      Rect r( p0, p0 );

      for ( int down = 0; down < 2; ++down )
      {
         if ( down ? (p0.y == simg.Height()-1) : (p0.y == 0) )
            continue;

         for ( int y = down ? p0.y+1 : p0.y; ; )
         {
            double yc = y + 0.5;
            int xa, xb;

            /*
             * Explore the left segment of this row.
             */
            for ( xa = p0.x+1; xa > 0; )
            {
               Image::sample f = simg.Pixel( xa-1, y );
               if ( f == 0 )
                  break;
               --xa;
               sx += f*(xa + 0.5);
               sy += f*yc;
               si += f;
            }

            /*
             * Explore the right segment of this row.
             */
            for ( xb = p0.x; xb < simg.Width()-1; )
            {
               Image::sample f = simg.Pixel( xb+1, y );
               if ( f == 0 )
                  break;
               ++xb;
               sx += f*(xb + 0.5);
               sy += f*yc;
               si += f;
            }

            /*
             * Update horizontal boundaries.
             */
            if ( xa < r.x0 )  // left boundary
               r.x0 = xa;
            if ( xb >= r.x1 ) // right boundary
               r.x1 = xb+1;

            /*
             * Update y to explore the next row.
             */
            if ( down )
            {
               ++y;
               if ( y == simg.Height() )
                  break;
            }
            else
            {
               if ( y == 0 )
                  break;
               --y;
            }

            /*
             * Decide whether we are done with this star, or if there is at
             * least one more row that has to be explored. This is true if
             * there is at least one significant pixel touching the current row
             * in the next row.
             */
            bool nextRow = false;
            for ( int x = xa; x <= xb; ++x )
               if ( simg.Pixel( x, y ) != 0 )
               {
                  nextRow = true;
                  break;
               }
            if ( !nextRow )
               break;

            /*
             * Update vertical boundaries.
             */
            if ( down )
               r.y1 = y+1; // bottom boundary
            else
               r.y0 = y;   // top boundary
         }
      }

      /*
       * Check if we have gathered some data.
       */
      if ( 1 + si == 1 )
         return StarDetector::NoSignificantData;

      /*
       * Update barycenter coordinates.
       */
      DPoint lastPos = pos;
      pos.x = r0.x0 + sx/si;
      pos.y = r0.y0 + sy/si;

      /*
       * Update search radius.
       */
      int r1 = Range( Max( r.Width(), r.Height() ), 5, 127 );
      if ( r1 != radius )
         radius = r1;
      else
      {
         /*
          * If the search radius has stabilized, check if we have reached
          * convergence. We converge to within +/- 0.01 px.
          */
         if ( Abs( pos.x - lastPos.x ) < 0.005 && Abs( pos.y - lastPos.y ) < 0.005 )
            return (r.x0 > 0 && r.y0 > 0 && r.x1 < simg.Width() && r.y1 < simg.Height()) ?
                        StarDetector::DetectedOk : StarDetector::CrossingEdges;
      }
   }

   return StarDetector::NoConvergence;
}