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 Renn#define _CV_NORM_L2(a) (float)(icvSqrt32f(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]))
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_NORM_L22(a) (float)(a[0]*a[0] + a[1]*a[1] + a[2]*a[2])
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   find region where hand is   (for gesture recognition)
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   flag = 0 (use left bucket)  flag = 1 (use right bucket)
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFindHandRegion( CvPoint3D32f * points, int count,
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvSeq * indexs,
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   float *line, CvSize2D32f size, int flag,
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvPoint3D32f * center,
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvMemStorage * storage, CvSeq ** numbers )
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    IppmVect32f sub, cros;   */
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *sub, *cros;
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvStatus status;
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nbins = 20, i, l, i_point, left, right;
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int *bin_counts = 0;        //  pointer to the point's counter in the bickets
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int low_count;              //  low threshold
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint *tmp_number = 0, *pt;
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float value, vmin, vmax, vl, bsize, vc;
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float hand_length, hand_length2, hand_left, hand_right;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float threshold, threshold2;
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *vv = 0;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float a[3];
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    status = CV_OK;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_length = size.width;
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_length2 = hand_length / 2;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold = (float) (size.height * 3 / 5.);
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold2 = threshold * threshold;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    low_count = count/nbins;     */
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    low_count = (int) (count / 60.);
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( points != NULL && line != NULL );
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( points == NULL || line == NULL )
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( count > 5 );
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( count < 5 )
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFLAG_ERR;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( flag == 0 || flag == 1 );
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( flag != 0 && flag != 1 )
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFLAG_ERR;
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  create vectors         */
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    sub = icvCreateVector_32f( 3 );
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cros = icvCreateVector_32f( 3 );
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sub == NULL || cros == NULL )
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the point's projections on the line    */
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vv = (float *) cvAlloc( count * sizeof( float ));
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vv == NULL )
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the point's counter in the bickets     */
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bin_counts = (int *) cvAlloc( nbins * sizeof( int ));
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( bin_counts == NULL )
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( bin_counts, 0, nbins * sizeof( int ));
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( indexs, &reader, 0 );
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the temporale point's numbers      */
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp_number = (CvPoint *) cvAlloc( count * sizeof( CvPoint ));
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( tmp_number == NULL )
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  find min and max point's projection on the line     */
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vmin = 1000;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vmax = -1000;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i_point = 0;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < count; i++ )
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvSubVector_32f ((IppmVect32f )&points[i], (IppmVect32f )&line[3], sub, 3);
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvCrossProduct2L_32f ((IppmVect32f )&line[0], sub, cros);
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[0] = points[i].x - line[3];
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[1] = points[i].y - line[4];
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[2] = points[i].z - line[5];
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[0] = sub[0] * line[1] - sub[1] * line[0];
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[1] = sub[1] * line[2] - sub[2] * line[1];
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[2] = sub[2] * line[0] - sub[0] * line[2];
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*      if(IPPI_NORM_L22 ( cros ) < threshold2)    */
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _CV_NORM_L22( a ) < threshold2 )
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            value = (float)icvDotProduct_32f( sub, &line[0], 3 );
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( value > vmax )
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                vmax = value;
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( value < vmin )
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                vmin = value;
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            vv[i_point] = value;
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt = (CvPoint*)cvGetSeqElem( indexs, i );
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp_number[i_point] = *pt;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i_point++;
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute the length of one bucket             */
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vl = vmax - vmin;
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bsize = vl / nbins;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute the number of points in each bucket   */
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < i_point; i++ )
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        l = cvRound( (vv[i] - vmin) / bsize );
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bin_counts[l]++;
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *numbers = cvCreateSeq( CV_SEQ_POINT_SET, sizeof( CvSeq ), sizeof( CvPoint ), storage );
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( numbers != 0 );
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( numbers == NULL )
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( *numbers, &writer );
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( flag == 0 )
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  find the leftmost bucket           */
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = 0; l < nbins; l++ )
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( bin_counts[l] > low_count )
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        left = l;
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute center point of the left hand     */
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_left = vmin + left * bsize;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vc = hand_left + hand_length2;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_right = hand_left + hand_length;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  find the rightmost bucket                */
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = nbins - 1; l >= 0; l-- )
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( bin_counts[l] > low_count )
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        right = l;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute center point of the right hand    */
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_right = vmax - (nbins - right - 1) * bsize;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vc = hand_right - hand_length2;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_left = hand_right - hand_length;
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvScaleVector_32f( &line[0], sub, 3, vc );
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvAddVector_32f( &line[3], sub, (float *) center, 3 );
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  select hand's points and calculate mean value     */
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //ss.x = ss.y = ss.z = 0;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 0; l < i_point; l++ )
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( vv[l] >= hand_left && vv[l] <= hand_right )
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( tmp_number[l], writer );
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  M_END:
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( tmp_number != NULL )
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &tmp_number );
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( bin_counts != NULL )
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &bin_counts );
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vv != NULL )
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &vv );
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sub != NULL ) icvDeleteVector (sub);
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cros != NULL ) icvDeleteVector (cros);
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return status;
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_NORM_L31(a) (float)(icvSqrt32f(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]))
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_NORM_L32(a) (float)(a[0]*a[0] + a[1]*a[1] + a[2]*a[2])
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   find region where hand is   (for gesture recognition)
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   flag = 0 (use left bucket)  flag = 1 (use right bucket)
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFindHandRegionA( CvPoint3D32f * points, int count,
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvSeq * indexs,
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float *line, CvSize2D32f size, int jc,
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvPoint3D32f * center,
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvMemStorage * storage, CvSeq ** numbers )
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    IppmVect32f sub, cros;   */
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *sub, *cros;
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float eps = (float) 0.01;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvStatus status;
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float gor[3] = { 1, 0, 0 };
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float ver[3] = { 0, 1, 0 };
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nbins = 20, i, l, i_point, left, right, jmin, jmax, jl;
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j_left, j_right;
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int *bin_counts = 0;        //  pointer to the point's counter in the bickets
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    int *bin_countsj = 0;   //  pointer to the index's counter in the bickets
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int low_count;              //  low threshold
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint *tmp_number = 0, *pt;
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float value, vmin, vmax, vl, bsize, bsizej, vc, vcl, vcr;
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double v_ver, v_gor;
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float hand_length, hand_length2, hand_left, hand_right;
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float threshold, threshold2;
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *vv = 0;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float a[3];
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    char log;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    status = CV_OK;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_length = size.width;
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_length2 = hand_length / 2;
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold = (float) (size.height * 3 / 5.);
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold2 = threshold * threshold;
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    low_count = count/nbins;     */
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    low_count = (int) (count / 60.);
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( points != NULL && line != NULL );
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( points == NULL || line == NULL )
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( count > 5 );
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( count < 5 )
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFLAG_ERR;
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  create vectors         */
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    sub = icvCreateVector_32f( 3 );
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cros = icvCreateVector_32f( 3 );
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sub == NULL || cros == NULL )
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the point's projections on the line    */
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vv = (float *) cvAlloc( count * sizeof( float ));
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vv == NULL )
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the point's counter in the bickets     */
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bin_counts = (int *) cvAlloc( nbins * sizeof( int ));
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( bin_counts == NULL )
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( bin_counts, 0, nbins * sizeof( int ));
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the point's counter in the bickets     */
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    bin_countsj = (int*) icvAlloc(nbins*sizeof(int));
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    if(bin_countsj == NULL) {status = CV_OUTOFMEM_ERR; goto M_END;}
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    memset(bin_countsj,0,nbins*sizeof(int));
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( indexs, &reader, 0 );
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  alloc memory for the temporale point's numbers      */
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp_number = (CvPoint *) cvAlloc( count * sizeof( CvPoint ));
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( tmp_number == NULL )
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  find min and max point's projection on the line     */
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vmin = 1000;
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vmax = -1000;
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    jmin = 1000;
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    jmax = -1000;
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i_point = 0;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < count; i++ )
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvSubVector_32f ((IppmVect32f )&points[i], (IppmVect32f )&line[3], sub, 3);
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvCrossProduct2L_32f ((IppmVect32f )&line[0], sub, cros);
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[0] = points[i].x - line[3];
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[1] = points[i].y - line[4];
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sub[2] = points[i].z - line[5];
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      if(fabs(sub[0])<eps||fabs(sub[1])<eps||fabs(sub[2])<eps) continue;
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[0] = sub[0] * line[1] - sub[1] * line[0];
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[1] = sub[1] * line[2] - sub[2] * line[1];
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[2] = sub[2] * line[0] - sub[0] * line[2];
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        v_gor = icvDotProduct_32f( gor, &line[0], 3 );
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        v_ver = icvDotProduct_32f( ver, &line[0], 3 );
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( v_ver > v_gor )
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            log = true;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            log = false;
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*      if(IPPI_NORM_L22 ( cros ) < threshold2)    */
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if(fabs(a[0])<eps && fabs(a[1])<eps && fabs(a[2])<eps)
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDotProduct_32f( sub, &line[0], 3, &value);
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if(value > vmax) vmax = value;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if(value < vmin) vmin = value;
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            vv[i_point] = value;
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt = (CvPoint* )icvGetSeqElem ( indexs, i, 0);
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if(pt->x > jmax) jmax = pt->x;
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if(pt->x < jmin) jmin = pt->x;
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp_number[i_point] = *pt;
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i_point++;
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( _CV_NORM_L32( a ) < threshold2 )
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                value = (float)icvDotProduct_32f( sub, &line[0], 3 );
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( value > vmax )
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    vmax = value;
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( value < vmin )
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    vmin = value;
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                vv[i_point] = value;
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt = (CvPoint*)cvGetSeqElem( indexs, i );
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !log )
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( pt->x > jmax )
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        jmax = pt->x;
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( pt->x < jmin )
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        jmin = pt->x;
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( pt->y > jmax )
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        jmax = pt->y;
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( pt->y < jmin )
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        jmin = pt->y;
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tmp_number[i_point] = *pt;
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i_point++;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute the length of one bucket along the line        */
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vl = vmax - vmin;
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  examining on the arm's existence  */
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vl < eps )
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *numbers = NULL;
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OK;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bsize = vl / nbins;
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute the number of points in each bucket along the line  */
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < i_point; i++ )
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        l = cvRound( (vv[i] - vmin) / bsize );
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bin_counts[l]++;
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*  compute the length of one bucket along the X axe        */
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    jl = jmax - jmin;
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( jl <= 1 )
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *numbers = NULL;
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OK;
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bsizej = (float) (jl / (nbins + 0.));
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute the number of points in each bucket along the X axe */
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    for(i=0;i<i_point;i++)
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    {
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//        l = cvRound((tmp_number[i].x - jmin)/bsizej);
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//        bin_countsj[l]++;
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    }
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    left = right = -1;
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  find the leftmost and the rightmost buckets           */
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 0; l < nbins; l++ )
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( bin_counts[l] > low_count && left == -1 )
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            left = l;
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( bin_counts[l] > low_count && left >= 0 )
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            right = l;
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute center point of the left hand     */
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( left == -1 && right == -1 )
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *numbers = NULL;
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OK;
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_left = vmin + left * bsize;
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j_left = (int) (jmin + left * bsizej);
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vcl = hand_left + hand_length2;
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  compute center point of the right hand    */
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hand_right = vmax - (nbins - right - 1) * bsize;
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vcr = hand_right - hand_length2;
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j_right = (int) (jmax - (nbins - right - 1) * bsizej);
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j_left = abs( j_left - jc );
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j_right = abs( j_right - jc );
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( j_left <= j_right )
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_right = hand_left + hand_length;
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vc = vcl;
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hand_left = hand_right - hand_length;
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vc = vcr;
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvScaleVector_32f( &line[0], sub, 3, vc );
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvAddVector_32f( &line[3], sub, (float *) center, 3 );
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  select hand's points and calculate mean value     */
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *numbers = cvCreateSeq( CV_SEQ_POINT_SET, sizeof( CvSeq ), sizeof( CvPoint ), storage );
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( *numbers != 0 );
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( *numbers == NULL )
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( *numbers, &writer );
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 0; l < i_point; l++ )
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( vv[l] >= hand_left && vv[l] <= hand_right )
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( tmp_number[l], writer );
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  M_END:
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( tmp_number != NULL )
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &tmp_number );
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    if(bin_countsj != NULL) cvFree( &bin_countsj );
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( bin_counts != NULL )
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &bin_counts );
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vv != NULL )
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &vv );
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sub != NULL ) icvDeleteVector (sub);
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cros != NULL ) icvDeleteVector (cros);
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return status;
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name:     cvFindHandRegion
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose:  finds hand region in range image data
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      points - pointer to the input point's set.
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      count  - the number of the input points.
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      indexs - pointer to the input sequence of the point's indexes
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      line   - pointer to the 3D-line
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      size   - size of the hand in meters
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      flag   - hand direction's flag (0 - left, -1 - right,
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               otherwise j-index of the initial image center)
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      center - pointer to the output hand center
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage - pointer to the memory storage
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      numbers - pointer to the output sequence of the point's indexes inside
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                hand region
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFindHandRegion( CvPoint3D32f * points, int count,
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  CvSeq * indexs,
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  float *line, CvSize2D32f size, int flag,
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  CvPoint3D32f * center, CvMemStorage * storage, CvSeq ** numbers )
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvFindHandRegion" );
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if(flag == 0 || flag == -1)
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	{
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		IPPI_CALL( icvFindHandRegion( points, count, indexs, line, size, -flag,
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			                           center, storage, numbers ));
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	else
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		IPPI_CALL( icvFindHandRegionA( points, count, indexs, line, size, flag,
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			                            center, storage, numbers ));
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __CLEANUP__;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name:     cvFindHandRegionA
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose:  finds hand region in range image data
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      points - pointer to the input point's set.
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      count  - the number of the input points.
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      indexs - pointer to the input sequence of the point's indexes
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      line   - pointer to the 3D-line
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      size   - size of the hand in meters
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      jc     - j-index of the initial image center
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      center - pointer to the output hand center
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage - pointer to the memory storage
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      numbers - pointer to the output sequence of the point's indexes inside
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                hand region
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFindHandRegionA( CvPoint3D32f * points, int count,
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvSeq * indexs,
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   float *line, CvSize2D32f size, int jc,
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvPoint3D32f * center, CvMemStorage * storage, CvSeq ** numbers )
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvFindHandRegionA" );
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IPPI_CALL( icvFindHandRegionA( points, count, indexs, line, size, jc,
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    center, storage, numbers ));
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __CLEANUP__;
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646