\section{Object Detection}

\cvclass{gpu::HOGDescriptor}
Histogram of Oriented Gradients \cite{dalal_hog} descriptor and detector.

\begin{lstlisting}
struct CV_EXPORTS HOGDescriptor
{
    enum { DEFAULT_WIN_SIGMA = -1 };
    enum { DEFAULT_NLEVELS = 64 };
    enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };

    HOGDescriptor(Size win_size=Size(64, 128), Size block_size=Size(16, 16),
                  Size block_stride=Size(8, 8), Size cell_size=Size(8, 8),
                  int nbins=9, double win_sigma=DEFAULT_WIN_SIGMA,
                  double threshold_L2hys=0.2, bool gamma_correction=true,
                  int nlevels=DEFAULT_NLEVELS);

    size_t getDescriptorSize() const;
    size_t getBlockHistogramSize() const;

    void setSVMDetector(const vector<float>& detector);

    static vector<float> getDefaultPeopleDetector();
    static vector<float> getPeopleDetector48x96();
    static vector<float> getPeopleDetector64x128();

    void detect(const GpuMat& img, vector<Point>& found_locations, 
                double hit_threshold=0, Size win_stride=Size(), 
                Size padding=Size());

    void detectMultiScale(const GpuMat& img, vector<Rect>& found_locations,
                          double hit_threshold=0, Size win_stride=Size(), 
                          Size padding=Size(), double scale0=1.05, 
                          int group_threshold=2);

    void getDescriptors(const GpuMat& img, Size win_stride, 
                        GpuMat& descriptors,
                        int descr_format=DESCR_FORMAT_COL_BY_COL);

    Size win_size;
    Size block_size;
    Size block_stride;
    Size cell_size;
    int nbins;
    double win_sigma;
    double threshold_L2hys;
    bool gamma_correction;
    int nlevels;

private:
    // Hidden
}
\end{lstlisting}

Interfaces of all methods are kept similar to CPU HOG descriptor and detector analogues as much as possible.


\cvCppFunc{gpu::HOGDescriptor::HOGDescriptor}
Creates HOG descriptor and detector.

\cvdefCpp{HOGDescriptor::HOGDescriptor(Size win\_size=Size(64, 128),\par
  Size block\_size=Size(16, 16), Size block\_stride=Size(8, 8),\par
  Size cell\_size=Size(8, 8), int nbins=9,\par
  double win\_sigma=DEFAULT\_WIN\_SIGMA,\par
  double threshold\_L2hys=0.2, bool gamma\_correction=true,\par
  int nlevels=DEFAULT\_NLEVELS);}

\begin{description}
\cvarg{win\_size}{Detection window size. Must be aligned to block size and block stride.}
\cvarg{block\_size}{Block size in pixels. Must be aligned to cell size. Only (16,16) is supported for now.}
\cvarg{block\_stride}{Block stride. Must be a multiple of cell size.}
\cvarg{cell\_size}{Cell size. Only (8, 8) is supported for now.}
\cvarg{nbins}{Number of bins. Only 9 bins per cell is supported for now.}
\cvarg{win\_sigma}{Gaussian smoothing window parameter.}
\cvarg{threshold\_L2Hys}{L2-Hys normalization method shrinkage.}
\cvarg{gamma\_correction}{Do gamma correction preprocessing or not.}
\cvarg{nlevels}{Maximum number of detection window increases.}
\end{description}


\cvCppFunc{gpu::HOGDescriptor::getDescriptorSize}
Returns number of coefficients required for the classification.

\cvdefCpp{size\_t HOGDescriptor::getDescriptorSize() const;}


\cvCppFunc{gpu::HOGDescriptor::getBlockHistogramSize}
Returns block histogram size.

\cvdefCpp{size\_t HOGDescriptor::getBlockHistogramSize() const;}


\cvCppFunc{gpu::HOGDescriptor::setSVMDetector}
Sets coefficients for the linear SVM classifier. 

\cvdefCpp{void HOGDescriptor::setSVMDetector(const vector<float>\& detector);}


\cvCppFunc{gpu::HOGDescriptor::getDefaultPeopleDetector}
Returns coefficients of the classifier trained for people detection (for default window size).

\cvdefCpp{static vector<float> HOGDescriptor::getDefaultPeopleDetector();}


\cvCppFunc{gpu::HOGDescriptor::getPeopleDetector48x96}
Returns coefficients of the classifier trained for people detection (for 48x96 windows).

\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector48x96();}


\cvCppFunc{gpu::HOGDescriptor::getPeopleDetector64x128}
Returns coefficients of the classifier trained for people detection (for 64x128 windows).

\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector64x128();}


\cvCppFunc{gpu::HOGDescriptor::detect}
Perfroms object detection without multiscale window.

\cvdefCpp{void HOGDescriptor::detect(const GpuMat\& img,\par
  vector<Point>\& found\_locations, double hit\_threshold=0,\par
  Size win\_stride=Size(), Size padding=Size());}

\begin{description}
\cvarg{img}{Source image. \texttt{CV\_8UC1} and \texttt{CV\_8UC4}types are supported for now.}
\cvarg{found\_locations}{Will contain left-top corner points of detected objects boundaries.}
\cvarg{hit\_threshold}{Threshold for the distance between features and SVM classifying plane. Usually it's 0 and should be specfied in the detector coefficients (as the last free coefficient), but if the free coefficient is omitted (it's allowed) you can specify it manually here.}
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
\cvarg{padding}{Mock parameter to keep CPU interface compatibility. Must be (0,0).}
\end{description}


\cvCppFunc{gpu::HOGDescriptor::detectMultiScale}
Perfroms object detection with multiscale window.

\cvdefCpp{void HOGDescriptor::detectMultiScale(const GpuMat\& img,\par
  vector<Rect>\& found\_locations, double hit\_threshold=0,\par
  Size win\_stride=Size(), Size padding=Size(),\par
  double scale0=1.05, int group\_threshold=2);}

\begin{description}
\cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}
\cvarg{found\_locations}{Will contain detected objects boundaries.}
\cvarg{hit\_threshold}{The threshold for the distance between features and SVM classifying plane. See \cvCppCross{gpu::HOGDescriptor::detect} for details.}
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
\cvarg{padding}{Mock parameter to keep CPU interface compatibility. Must be (0,0).}
\cvarg{scale0}{Coefficient of the detection window increase.}
\cvarg{group\_threshold}{After detection some objects could be covered by many rectangles. This coefficient regulates similarity threshold. 0 means don't perform grouping.\newline
See \cvCppCross{groupRectangles}.}
\end{description}


\cvCppFunc{gpu::HOGDescriptor::getDescriptors}
Returns block descriptors computed for the whole image. It's mainly used for classifier learning purposes.

\cvdefCpp{void HOGDescriptor::getDescriptors(const GpuMat\& img,\par
  Size win\_stride, GpuMat\& descriptors,\par
  int descr\_format=DESCR\_FORMAT\_COL\_BY\_COL);}

\begin{description}
\cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
\cvarg{descriptors}{2D array of descriptors.}
\cvarg{descr\_format}{Descriptor storage format: 
\begin{description}
    \cvarg{DESCR\_FORMAT\_ROW\_BY\_ROW}{Row-major order.}
    \cvarg{DESCR\_FORMAT\_COL\_BY\_COL}{Column-major order.}
\end{description}}
\end{description}


\cvclass{gpu::CascadeClassifier\_GPU}
The cascade classifier class for object detection.

\begin{lstlisting}
class CV_EXPORTS CascadeClassifier_GPU
{
public:            
	CascadeClassifier_GPU();
	CascadeClassifier_GPU(const string& filename);
	~CascadeClassifier_GPU();

	bool empty() const;
	bool load(const string& filename);
	void release();
	
	/* returns number of detected objects */
	int detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor=1.2, int minNeighbors=4, Size minSize=Size());
					
        /* Finds only the largest object. Special mode for need to training*/		
	bool findLargestObject;

        /* Draws rectangles in input image */		
	bool visualizeInPlace;

	Size getClassifierSize() const;	
};
\end{lstlisting}

\cvfunc{cv::gpu::CascadeClassifier\_GPU::CascadeClassifier\_GPU}\par
Loads the classifier from file.
\cvdefCpp{cv::CascadeClassifier\_GPU(const string\& filename);}
\begin{description}
\cvarg{filename}{Name of file from which classifier will be load. Only old haar classifier (trained by haartraining application) and NVidia's nvbin are supported.}
\end{description}

\cvfunc{cv::gpu::CascadeClassifier\_GPU::empty}
Checks if the classifier has been loaded or not.
\cvdefCpp{bool CascadeClassifier\_GPU::empty() const;}


\cvfunc{cv::gpu::CascadeClassifier\_GPU::load}
Loads the classifier from file. The previous content is destroyed.
\cvdefCpp{bool CascadeClassifier\_GPU::load(const string\& filename);}
\begin{description}
\cvarg{filename}{Name of file from which classifier will be load. Only old haar classifier (trained by haartraining application) and NVidia's nvbin are supported.}
\end{description}


\cvfunc{cv::gpu::CascadeClassifier\_GPU::release}
Destroys loaded classifier.
\cvdefCpp{void CascadeClassifier\_GPU::release()}



\cvfunc{cv::gpu::CascadeClassifier\_GPU::detectMultiScale}
Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.

\cvdefCpp{int CascadeClassifier\_GPU::detectMultiScale(const GpuMat\& image, GpuMat\& objectsBuf, double scaleFactor=1.2, int minNeighbors=4, Size minSize=Size());}
\begin{description}
\cvarg{image}{Matrix of type \texttt{CV\_8U} containing the image in which to detect objects.}
\cvarg{objects}{Buffer to store detected objects (rectangles). If it is empty, it will be allocated with default size. If not empty, function will search not more than N objects, where N = sizeof(objectsBufer's data)/sizeof(cv::Rect).}
\cvarg{scaleFactor}{Specifies how much the image size is reduced at each image scale.}
\cvarg{minNeighbors}{Specifies how many neighbors should each candidate rectangle have to retain it.}
\cvarg{minSize}{The minimum possible object size. Objects smaller than that are ignored.}
\end{description}

The function returns number of detected objects, so you can retrieve them as in following example:

\begin{lstlisting}

cv::gpu::CascadeClassifier_GPU cascade_gpu(...);

Mat image_cpu = imread(...)
GpuMat image_gpu(image_cpu);

GpuMat objbuf;
int detections_number = cascade_gpu.detectMultiScale( image_gpu,
          objbuf, 1.2, minNeighbors); 

Mat obj_host;
// download only detected number of rectangles
objbuf.colRange(0, detections_number).download(obj_host);

Rect* faces = obj_host.ptr<Rect>(); 
for(int i = 0; i < detections_num; ++i)                
   cv::rectangle(image_cpu, faces[i], Scalar(255));  

imshow("Faces", image_cpu);

\end{lstlisting}


See also: \cvCppCross{CascadeClassifier::detectMultiScale}.