16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::CvCamShiftTracker()
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( &m_box, 0, sizeof(m_box));
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( &m_comp, 0, sizeof(m_comp));
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( m_color_planes, 0, sizeof(m_color_planes));
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_threshold = 0;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < CV_MAX_DIM; i++ )
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_min_ch_val[i] = 0;
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_max_ch_val[i] = 255;
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_hist_ranges[i] = m_hist_ranges_data[i];
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_hist_ranges[i][0] = 0.f;
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_hist_ranges[i][1] = 256.f;
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_hist = 0;
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_back_project = 0;
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_temp = 0;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_mask = 0;
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::~CvCamShiftTracker()
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseHist( &m_hist );
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < CV_MAX_DIM; i++ )
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseImage( &m_color_planes[i] );
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseImage( &m_back_project );
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseImage( &m_temp );
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseImage( &m_mask );
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::color_transform( const IplImage* image )
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetSize(image);
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* color_data = 0, *mask = 0;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* planes[CV_MAX_DIM];
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, color_step = 0, plane_step = 0, mask_step;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dims[CV_MAX_DIM];
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, n = get_hist_dims(dims);
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( image->nChannels == 3 && m_hist != 0 );
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !m_temp || !m_mask || !m_color_planes[0] || !m_color_planes[n-1] || !m_back_project ||
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_temp->width != size.width || m_temp->height != size.height ||
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_temp->nChannels != 3 )
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseImage( &m_temp );
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_temp = cvCreateImage( size, IPL_DEPTH_8U, 3 );
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseImage( &m_mask );
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_mask = cvCreateImage( size, IPL_DEPTH_8U, 1 );
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseImage( &m_back_project );
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_back_project = cvCreateImage( size, IPL_DEPTH_8U, 1 );
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < CV_MAX_DIM; i++ )
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseImage( &m_color_planes[i] );
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                m_color_planes[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvCvtColor( image, m_temp, CV_BGR2HSV );
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetRawData( m_temp, &color_data, &color_step, &size );
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetRawData( m_mask, &mask, &mask_step, &size );
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < n; i++ )
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetRawData( m_color_planes[i], &planes[i], &plane_step, &size );
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; size.height--; color_data += color_step, mask += mask_step )
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < size.width; x++ )
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int val0 = color_data[x*3];
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int val1 = color_data[x*3+1];
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int val2 = color_data[x*3+2];
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m_min_ch_val[0] <= val0 && val0 <= m_max_ch_val[0] &&
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                m_min_ch_val[1] <= val1 && val1 <= m_max_ch_val[1] &&
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                m_min_ch_val[2] <= val2 && val2 <= m_max_ch_val[2] )
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // hue is written to the 0-th plane, saturation - to the 1-st one,
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // so 1d histogram will automagically correspond to hue-based tracking,
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // 2d histogram - to saturation-based tracking.
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                planes[0][x] = (uchar)val0;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n > 1 )
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    planes[1][x] = (uchar)val1;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n > 2 )
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    planes[2][x] = (uchar)val2;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                mask[x] = (uchar)255;
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                planes[0][x] = 0;
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n > 1 )
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    planes[1][x] = 0;
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n > 2 )
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    planes[2][x] = 0;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                mask[x] = 0;
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < n; i++ )
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            planes[i] += plane_step;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::update_histogram( const IplImage* cur_frame )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float max_val = 0;
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, dims;
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_comp.rect.width == 0 || m_comp.rect.height == 0 ||
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_hist == 0 )
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(0);
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    color_transform(cur_frame);
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dims = cvGetDims( m_hist->bins );
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dims; i++ )
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetImageROI( m_color_planes[i], m_comp.rect );
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSetImageROI( m_mask, m_comp.rect );
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSetHistBinRanges( m_hist, m_hist_ranges, 1 );
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvCalcHist( m_color_planes, m_hist, 0, m_mask );
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dims; i++ )
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetImageROI( m_color_planes[i], m_comp.rect );
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dims; i++ )
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvResetImageROI( m_color_planes[i] );
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvResetImageROI( m_mask );
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetMinMaxHistValue( m_hist, 0, &max_val );
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvScale( m_hist->bins, m_hist->bins, max_val ? 255. / max_val : 0. );
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return max_val != 0;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::reset_histogram()
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_hist )
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvClearHist( m_hist );
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::track_object( const IplImage* cur_frame )
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect rect;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize bp_size;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    union
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        void** arr;
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IplImage** img;
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } u;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_comp.rect.width == 0 || m_comp.rect.height == 0 ||
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_hist == 0 )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    color_transform( cur_frame );
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    u.img = m_color_planes;
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvCalcArrBackProject( u.arr, m_back_project, m_hist );
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvAnd( m_back_project, m_mask, m_back_project );
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rect = m_comp.rect;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bp_size = cvGetSize( m_back_project );
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rect.x < 0 )
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rect.x = 0;
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rect.x + rect.width > bp_size.width )
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rect.width = bp_size.width - rect.x;
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rect.y < 0 )
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rect.y = 0;
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rect.y + rect.height > bp_size.height )
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rect.height = bp_size.height - rect.y;
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvCamShift( m_back_project, rect,
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                &m_comp, &m_box );
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_comp.rect.width == 0 || m_comp.rect.height == 0 )
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_comp.rect = rect; // do not allow tracker to loose the object
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return m_comp.rect.width != 0 && m_comp.rect.height != 0;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::set_hist_dims( int c_dims, int *dims )
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)(c_dims-1) >= (unsigned)CV_MAX_DIM || dims == 0 )
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_hist )
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int dims2[CV_MAX_DIM];
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int c_dims2 = cvGetDims( m_hist->bins, dims2 );
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( c_dims2 == c_dims && memcmp( dims, dims2, c_dims*sizeof(dims[0])) == 0 )
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return true;
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseHist( &m_hist );
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_hist = cvCreateHist( c_dims, dims, CV_HIST_ARRAY, 0, 0 );
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvCamShiftTracker::set_hist_bin_range( int channel, int min_val, int max_val )
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)channel >= (unsigned)CV_MAX_DIM ||
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        min_val >= max_val || min_val < 0 || max_val > 256 )
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(0);
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_hist_ranges[channel][0] = (float)min_val;
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_hist_ranges[channel][1] = (float)max_val;
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
286