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//
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvBGCodeBookModel* cvCreateBGCodeBookModel()
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBGCodeBookModel* model = (CvBGCodeBookModel*)cvAlloc( sizeof(*model) );
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( model, 0, sizeof(*model) );
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10;
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->modMin[0] = 3;
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->modMax[0] = 10;
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->modMin[1] = model->modMin[2] = 1;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->modMax[1] = model->modMax[2] = 1;
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->storage = cvCreateMemStorage();
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return model;
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvReleaseBGCodeBookModel( CvBGCodeBookModel** model )
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( model && *model )
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMemStorage( &(*model)->storage );
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( *model, 0, sizeof(**model) );
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( model );
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic uchar satTab8u[768];
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef SAT_8U
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define SAT_8U(x) satTab8u[(x) + 255]
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitSatTab()
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int initialized = 0;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !initialized )
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( int i = 0; i < 768; i++ )
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int v = i - 255;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            satTab8u[i] = (uchar)(v < 0 ? 0 : v > 255 ? 255 : v);
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        initialized = 1;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvBGCodeBookUpdate( CvBGCodeBookModel* model, const CvArr* _image,
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvRect roi, const CvArr* _mask )
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvBGCodeBookUpdate" );
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *image = cvGetMat( _image, &stub );
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mstub, *mask = _mask ? cvGetMat( _mask, &mstub ) : 0;
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, x, y, T;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nblocks;
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar cb0, cb1, cb2;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBGCodeBookElem* freeList;
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( model && CV_MAT_TYPE(image->type) == CV_8UC3 &&
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (!mask || CV_IS_MASK_ARR(mask) && CV_ARE_SIZES_EQ(image, mask)) );
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.x == 0 && roi.y == 0 && roi.width == 0 && roi.height == 0 )
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.width = image->cols;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.height = image->rows;
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( (unsigned)roi.x < (unsigned)image->cols &&
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   (unsigned)roi.y < (unsigned)image->rows &&
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.width >= 0 && roi.height >= 0 &&
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.x + roi.width <= image->cols &&
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.y + roi.height <= image->rows );
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( image->cols != model->size.width || image->rows != model->size.height )
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvClearMemStorage( model->storage );
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        model->freeList = 0;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &model->cbmap );
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int bufSz = image->cols*image->rows*sizeof(model->cbmap[0]);
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        model->cbmap = (CvBGCodeBookElem**)cvAlloc(bufSz);
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( model->cbmap, 0, bufSz );
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        model->size = cvSize(image->cols, image->rows);
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvInitSatTab();
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cb0 = model->cbBounds[0];
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cb1 = model->cbBounds[1];
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cb2 = model->cbBounds[2];
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    T = ++model->t;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    freeList = model->freeList;
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    nblocks = (int)((model->storage->block_size - sizeof(CvMemBlock))/sizeof(*freeList));
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    nblocks = MIN( nblocks, 1024 );
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( nblocks > 0 );
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < roi.height; y++ )
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const uchar* p = image->data.ptr + image->step*(y + roi.y) + roi.x*3;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const uchar* m = mask ? mask->data.ptr + mask->step*(y + roi.y) + roi.x : 0;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvBGCodeBookElem** cb = model->cbmap + image->cols*(y + roi.y) + roi.x;
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < roi.width; x++, p += 3, cb++ )
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvBGCodeBookElem *e, *found = 0;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar p0, p1, p2, l0, l1, l2, h0, h1, h2;
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int negRun;
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m && m[x] == 0 )
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p0 = p[0]; p1 = p[1]; p2 = p[2];
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            l0 = SAT_8U(p0 - cb0); l1 = SAT_8U(p1 - cb1); l2 = SAT_8U(p2 - cb2);
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h0 = SAT_8U(p0 + cb0); h1 = SAT_8U(p1 + cb1); h2 = SAT_8U(p2 + cb2);
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( e = *cb; e != 0; e = e->next )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( e->learnMin[0] <= p0 && p0 <= e->learnMax[0] &&
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->learnMin[1] <= p1 && p1 <= e->learnMax[1] &&
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->learnMin[2] <= p2 && p2 <= e->learnMax[2] )
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->tLastUpdate = T;
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMin[0] = MIN(e->boxMin[0], p0);
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMax[0] = MAX(e->boxMax[0], p0);
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMin[1] = MIN(e->boxMin[1], p1);
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMax[1] = MAX(e->boxMax[1], p1);
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMin[2] = MIN(e->boxMin[2], p2);
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMax[2] = MAX(e->boxMax[2], p2);
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    // no need to use SAT_8U for updated learnMin[i] & learnMax[i] here,
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    // as the bounding li & hi are already within 0..255.
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMin[0] > l0 ) e->learnMin[0]--;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMax[0] < h0 ) e->learnMax[0]++;
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMin[1] > l1 ) e->learnMin[1]--;
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMax[1] < h1 ) e->learnMax[1]++;
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMin[2] > l2 ) e->learnMin[2]--;
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( e->learnMax[2] < h2 ) e->learnMax[2]++;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    found = e;
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                negRun = T - e->tLastUpdate;
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->stale = MAX( e->stale, negRun );
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; e != 0; e = e->next )
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                negRun = T - e->tLastUpdate;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->stale = MAX( e->stale, negRun );
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !found )
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !freeList )
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    freeList = (CvBGCodeBookElem*)cvMemStorageAlloc(model->storage,
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        nblocks*sizeof(*freeList));
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < nblocks-1; i++ )
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        freeList[i].next = &freeList[i+1];
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    freeList[nblocks-1].next = 0;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e = freeList;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                freeList = freeList->next;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->learnMin[0] = l0; e->learnMax[0] = h0;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->learnMin[1] = l1; e->learnMax[1] = h1;
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->learnMin[2] = l2; e->learnMax[2] = h2;
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->boxMin[0] = e->boxMax[0] = p0;
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->boxMin[1] = e->boxMax[1] = p1;
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->boxMin[2] = e->boxMax[2] = p2;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->tLastUpdate = T;
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->stale = 0;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->next = *cb;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *cb = e;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->freeList = freeList;
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint cvBGCodeBookDiff( const CvBGCodeBookModel* model, const CvArr* _image,
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      CvArr* _fgmask, CvRect roi )
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int maskCount = -1;
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvBGCodeBookDiff" );
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *image = cvGetMat( _image, &stub );
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mstub, *mask = cvGetMat( _fgmask, &mstub );
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y;
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar m0, m1, m2, M0, M1, M2;
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( model && CV_MAT_TYPE(image->type) == CV_8UC3 &&
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        image->cols == model->size.width && image->rows == model->size.height &&
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_IS_MASK_ARR(mask) && CV_ARE_SIZES_EQ(image, mask) );
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.x == 0 && roi.y == 0 && roi.width == 0 && roi.height == 0 )
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.width = image->cols;
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.height = image->rows;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( (unsigned)roi.x < (unsigned)image->cols &&
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   (unsigned)roi.y < (unsigned)image->rows &&
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.width >= 0 && roi.height >= 0 &&
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.x + roi.width <= image->cols &&
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.y + roi.height <= image->rows );
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m0 = model->modMin[0]; M0 = model->modMax[0];
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m1 = model->modMin[1]; M1 = model->modMax[1];
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m2 = model->modMin[2]; M2 = model->modMax[2];
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    maskCount = roi.height*roi.width;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < roi.height; y++ )
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const uchar* p = image->data.ptr + image->step*(y + roi.y) + roi.x*3;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* m = mask->data.ptr + mask->step*(y + roi.y) + roi.x;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvBGCodeBookElem** cb = model->cbmap + image->cols*(y + roi.y) + roi.x;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < roi.width; x++, p += 3, cb++ )
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvBGCodeBookElem *e;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar p0 = p[0], p1 = p[1], p2 = p[2];
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int l0 = p0 + m0, l1 = p1 + m1, l2 = p2 + m2;
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int h0 = p0 - M0, h1 = p1 - M1, h2 = p2 - M2;
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            m[x] = (uchar)255;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( e = *cb; e != 0; e = e->next )
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( e->boxMin[0] <= l0 && h0 <= e->boxMax[0] &&
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMin[1] <= l1 && h1 <= e->boxMax[1] &&
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->boxMin[2] <= l2 && h2 <= e->boxMax[2] )
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    m[x] = 0;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    maskCount--;
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return maskCount;
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvBGCodeBookClearStale( CvBGCodeBookModel* model, int staleThresh,
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             CvRect roi, const CvArr* _mask )
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvBGCodeBookClearStale" );
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mstub, *mask = _mask ? cvGetMat( _mask, &mstub ) : 0;
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, T;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBGCodeBookElem* freeList;
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( model && (!mask || CV_IS_MASK_ARR(mask) &&
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        mask->cols == model->size.width && mask->rows == model->size.height) );
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.x == 0 && roi.y == 0 && roi.width == 0 && roi.height == 0 )
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.width = model->size.width;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        roi.height = model->size.height;
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( (unsigned)roi.x < (unsigned)mask->cols &&
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   (unsigned)roi.y < (unsigned)mask->rows &&
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.width >= 0 && roi.height >= 0 &&
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.x + roi.width <= mask->cols &&
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   roi.y + roi.height <= mask->rows );
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvInitSatTab();
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    freeList = model->freeList;
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    T = model->t;
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < roi.height; y++ )
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const uchar* m = mask ? mask->data.ptr + mask->step*(y + roi.y) + roi.x : 0;
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvBGCodeBookElem** cb = model->cbmap + model->size.width*(y + roi.y) + roi.x;
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < roi.width; x++, cb++ )
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvBGCodeBookElem *e, first, *prev = &first;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( m && m[x] == 0 )
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( first.next = e = *cb; e != 0; e = prev->next )
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( e->stale > staleThresh )
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev->next = e->next;
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->next = freeList;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    freeList = e;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->stale = 0;
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    e->tLastUpdate = T;
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev = e;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *cb = first.next;
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    model->freeList = freeList;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
363