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