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; }
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; }