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 "_cv.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_SNAKE_BIG 2.e+38f
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_SNAKE_IMAGE 1
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_SNAKE_GRAD  2
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name:      icvSnake8uC1R
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose:
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               src - source image,
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               srcStep - its step in bytes,
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               roi - size of ROI,
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               pt - pointer to snake points array
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               n - size of points array,
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               alpha - pointer to coefficient of continuity energy,
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               beta - pointer to coefficient of curvature energy,
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               gamma - pointer to coefficient of image energy,
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               coeffUsage - if CV_VALUE - alpha, beta, gamma point to single value
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            if CV_MATAY - point to arrays
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               criteria - termination criteria.
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               scheme - image energy scheme
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                         if _CV_SNAKE_IMAGE - image intensity is energy
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                         if _CV_SNAKE_GRAD  - magnitude of gradient is energy
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns:
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSnake8uC1R( unsigned char *src,
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               int srcStep,
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               CvSize roi,
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               CvPoint * pt,
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               int n,
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               float *alpha,
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               float *beta,
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               float *gamma,
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               int coeffUsage, CvSize win, CvTermCriteria criteria, int scheme )
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int neighbors = win.height * win.width;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int centerx = win.width >> 1;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int centery = win.height >> 1;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float invn;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int iteration = 0;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int converged = 0;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *Econt;
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *Ecurv;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *Eimg;
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *E;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float _alpha, _beta, _gamma;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*#ifdef GRAD_SNAKE */
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *gradient = NULL;
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *map = NULL;
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int map_width = ((roi.width - 1) >> 3) + 1;
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int map_height = ((roi.height - 1) >> 3) + 1;
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter pX, pY;
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #define WTILE_SIZE 8
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #define TILE_SIZE (WTILE_SIZE + 2)
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    short dx[TILE_SIZE*TILE_SIZE], dy[TILE_SIZE*TILE_SIZE];
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat _dx = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dx );
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat _dy = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dy );
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat _src = cvMat( roi.height, roi.width, CV_8UC1, src );
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* inner buffer of convolution process */
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //char ConvBuffer[400];
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*#endif */
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check bad arguments */
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src == NULL )
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (roi.height <= 0) || (roi.width <= 0) )
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( srcStep < roi.width )
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( pt == NULL )
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n < 3 )
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( alpha == NULL )
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( beta == NULL )
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( gamma == NULL )
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coeffUsage != CV_VALUE && coeffUsage != CV_ARRAY )
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFLAG_ERR;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (win.height <= 0) || (!(win.height & 1)))
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (win.width <= 0) || (!(win.width & 1)))
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    invn = 1 / ((float) n);
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( scheme == _CV_SNAKE_GRAD )
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pX.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 1, 0, 3 );
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pY.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 0, 1, 3 );
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        gradient = (float *) cvAlloc( roi.height * roi.width * sizeof( float ));
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !gradient )
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        map = (uchar *) cvAlloc( map_width * map_height );
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !map )
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &gradient );
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* clear map - no gradient computed */
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( (void *) map, 0, map_width * map_height );
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Econt = (float *) cvAlloc( neighbors * sizeof( float ));
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Ecurv = (float *) cvAlloc( neighbors * sizeof( float ));
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Eimg = (float *) cvAlloc( neighbors * sizeof( float ));
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    E = (float *) cvAlloc( neighbors * sizeof( float ));
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( !converged )
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float ave_d = 0;
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int moved = 0;
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        converged = 0;
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iteration++;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* compute average distance */
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i < n; i++ )
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int diffx = pt[i - 1].x - pt[i].x;
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int diffy = pt[i - 1].y - pt[i].y;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ave_d += cvSqrt( (float) (diffx * diffx + diffy * diffy) );
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ave_d += cvSqrt( (float) ((pt[0].x - pt[n - 1].x) *
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  (pt[0].x - pt[n - 1].x) +
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  (pt[0].y - pt[n - 1].y) * (pt[0].y - pt[n - 1].y)));
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ave_d *= invn;
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* average distance computed */
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < n; i++ )
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* Calculate Econt */
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float maxEcont = 0;
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float maxEcurv = 0;
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float maxEimg = 0;
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float minEcont = _CV_SNAKE_BIG;
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float minEcurv = _CV_SNAKE_BIG;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float minEimg = _CV_SNAKE_BIG;
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float Emin = _CV_SNAKE_BIG;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int offsetx = 0;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int offsety = 0;
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float tmp;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* compute bounds */
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int left = MIN( pt[i].x, win.width >> 1 );
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int right = MIN( roi.width - 1 - pt[i].x, win.width >> 1 );
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int upper = MIN( pt[i].y, win.height >> 1 );
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int bottom = MIN( roi.height - 1 - pt[i].y, win.height >> 1 );
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            maxEcont = 0;
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            minEcont = _CV_SNAKE_BIG;
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = -upper; j <= bottom; j++ )
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = -left; k <= right; k++ )
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int diffx, diffy;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float energy;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( i == 0 )
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        diffx = pt[n - 1].x - (pt[i].x + k);
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        diffy = pt[n - 1].y - (pt[i].y + j);
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        diffx = pt[i - 1].x - (pt[i].x + k);
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        diffy = pt[i - 1].y - (pt[i].y + j);
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Econt[(j + centery) * win.width + k + centerx] = energy =
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (float) fabs( ave_d -
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      cvSqrt( (float) (diffx * diffx + diffy * diffy) ));
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    maxEcont = MAX( maxEcont, energy );
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    minEcont = MIN( minEcont, energy );
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = maxEcont - minEcont;
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = (tmp == 0) ? 0 : (1 / tmp);
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < neighbors; k++ )
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Econt[k] = (Econt[k] - minEcont) * tmp;
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /*  Calculate Ecurv */
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            maxEcurv = 0;
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            minEcurv = _CV_SNAKE_BIG;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = -upper; j <= bottom; j++ )
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = -left; k <= right; k++ )
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int tx, ty;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float energy;
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( i == 0 )
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        tx = pt[n - 1].x - 2 * (pt[i].x + k) + pt[i + 1].x;
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ty = pt[n - 1].y - 2 * (pt[i].y + j) + pt[i + 1].y;
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else if( i == n - 1 )
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        tx = pt[i - 1].x - 2 * (pt[i].x + k) + pt[0].x;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ty = pt[i - 1].y - 2 * (pt[i].y + j) + pt[0].y;
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        tx = pt[i - 1].x - 2 * (pt[i].x + k) + pt[i + 1].x;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ty = pt[i - 1].y - 2 * (pt[i].y + j) + pt[i + 1].y;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Ecurv[(j + centery) * win.width + k + centerx] = energy =
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (float) (tx * tx + ty * ty);
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    maxEcurv = MAX( maxEcurv, energy );
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    minEcurv = MIN( minEcurv, energy );
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = maxEcurv - minEcurv;
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = (tmp == 0) ? 0 : (1 / tmp);
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < neighbors; k++ )
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Ecurv[k] = (Ecurv[k] - minEcurv) * tmp;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* Calculate Eimg */
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = -upper; j <= bottom; j++ )
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = -left; k <= right; k++ )
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float energy;
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( scheme == _CV_SNAKE_GRAD )
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        /* look at map and check status */
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int x = (pt[i].x + k)/WTILE_SIZE;
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int y = (pt[i].y + j)/WTILE_SIZE;
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( map[y * map_width + x] == 0 )
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int l, m;
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            /* evaluate block location */
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int upshift = y ? 1 : 0;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int leftshift = x ? 1 : 0;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int bottomshift = MIN( 1, roi.height - (y + 1)*WTILE_SIZE );
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int rightshift = MIN( 1, roi.width - (x + 1)*WTILE_SIZE );
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvRect g_roi = { x*WTILE_SIZE - leftshift, y*WTILE_SIZE - upshift,
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                leftshift + WTILE_SIZE + rightshift, upshift + WTILE_SIZE + bottomshift };
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvMat _src1;
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cvGetSubArr( &_src, &_src1, g_roi );
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            pX.process( &_src1, &_dx );
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            pY.process( &_src1, &_dy );
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            for( l = 0; l < WTILE_SIZE + bottomshift; l++ )
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                for( m = 0; m < WTILE_SIZE + rightshift; m++ )
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                {
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    gradient[(y*WTILE_SIZE + l) * roi.width + x*WTILE_SIZE + m] =
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        (float) (dx[(l + upshift) * TILE_SIZE + m + leftshift] *
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 dx[(l + upshift) * TILE_SIZE + m + leftshift] +
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 dy[(l + upshift) * TILE_SIZE + m + leftshift] *
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 dy[(l + upshift) * TILE_SIZE + m + leftshift]);
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                }
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            map[y * map_width + x] = 1;
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Eimg[(j + centery) * win.width + k + centerx] = energy =
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            gradient[(pt[i].y + j) * roi.width + pt[i].x + k];
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Eimg[(j + centery) * win.width + k + centerx] = energy =
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            src[(pt[i].y + j) * srcStep + pt[i].x + k];
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    maxEimg = MAX( maxEimg, energy );
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    minEimg = MIN( minEimg, energy );
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = (maxEimg - minEimg);
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp = (tmp == 0) ? 0 : (1 / tmp);
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < neighbors; k++ )
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Eimg[k] = (minEimg - Eimg[k]) * tmp;
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* locate coefficients */
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( coeffUsage == CV_VALUE)
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _alpha = *alpha;
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _beta = *beta;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _gamma = *gamma;
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _alpha = alpha[i];
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _beta = beta[i];
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _gamma = gamma[i];
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* Find Minimize point in the neighbors */
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < neighbors; k++ )
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                E[k] = _alpha * Econt[k] + _beta * Ecurv[k] + _gamma * Eimg[k];
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Emin = _CV_SNAKE_BIG;
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = -upper; j <= bottom; j++ )
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = -left; k <= right; k++ )
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( E[(j + centery) * win.width + k + centerx] < Emin )
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Emin = E[(j + centery) * win.width + k + centerx];
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        offsetx = k;
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        offsety = j;
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( offsetx || offsety )
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt[i].x += offsetx;
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt[i].y += offsety;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                moved++;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        converged = (moved == 0);
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (criteria.type & CV_TERMCRIT_ITER) && (iteration >= criteria.max_iter) )
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            converged = 1;
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (criteria.type & CV_TERMCRIT_EPS) && (moved <= criteria.epsilon) )
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            converged = 1;
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &Econt );
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &Ecurv );
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &Eimg );
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &E );
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( scheme == _CV_SNAKE_GRAD )
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &gradient );
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &map );
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSnakeImage( const IplImage* src, CvPoint* points,
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int length, float *alpha,
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              float *beta, float *gamma,
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int coeffUsage, CvSize win,
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              CvTermCriteria criteria, int calcGradient )
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvSnakeImage" );
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *data;
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size;
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step;
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->nChannels != 1 )
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, "input image has more than one channel" );
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->depth != IPL_DEPTH_8U )
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetRawData( src, &data, &step, &size );
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IPPI_CALL( icvSnake8uC1R( data, step, size, points, length,
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              alpha, beta, gamma, coeffUsage, win, criteria,
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              calcGradient ? _CV_SNAKE_GRAD : _CV_SNAKE_IMAGE ));
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* end of file */
439