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 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h" 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCVAPI_IMPL( CvStatus, icvUpdateMotionHistory_8u32f_C1IR, 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (const uchar * silIm, int silStep, float *mhiIm, int mhiStep, 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size, float timestamp, float mhi_duration), 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (silIm, silStep, mhiIm, mhiStep, size, timestamp, mhi_duration) ) 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y; 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* function processes floating-point images using integer arithmetics */ 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cv32suf v; 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ts, delbound; 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int *mhi = (int *) mhiIm; 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v.f = timestamp; 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ts = v.i; 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !silIm || !mhiIm ) 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NULLPTR_ERR; 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( size.height <= 0 || size.width <= 0 || 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn silStep < size.width || mhiStep < size.width * CV_SIZEOF_FLOAT || 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (mhiStep & (CV_SIZEOF_FLOAT - 1)) != 0 ) 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_BADSIZE_ERR; 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhi_duration < 0 ) 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_BADFACTOR_ERR; 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_duration = timestamp - mhi_duration; 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v.f = mhi_duration; 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delbound = CV_TOGGLE_FLT( v.i ); 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhiStep /= sizeof(mhi[0]); 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhiStep == size.width && silStep == size.width ) 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size.width *= size.height; 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size.height = 1; 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delbound > 0 ) 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < size.height; y++, silIm += silStep, mhi += mhiStep ) 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < size.width; x++ ) 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val = mhi[x]; 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* val = silIm[x] ? ts : val < delbound ? 0 : val; */ 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val &= (val < delbound) - 1; 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val ^= (ts ^ val) & ((silIm[x] == 0) - 1); 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi[x] = val; 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < size.height; y++, silIm += silStep, mhi += mhiStep ) 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < size.width; x++ ) 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val = mhi[x]; 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* val = silIm[x] ? ts : val < delbound ? 0 : val; */ 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val &= (CV_TOGGLE_FLT( val ) < delbound) - 1; 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val ^= (ts ^ val) & ((silIm[x] == 0) - 1); 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi[x] = val; 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* motion templates */ 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvUpdateMotionHistory( const void* silhouette, void* mhimg, 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double timestamp, double mhi_duration ) 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size; 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat silhstub, *silh = (CvMat*)silhouette; 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat mhistub, *mhi = (CvMat*)mhimg; 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int mhi_step, silh_step; 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvUpdateMHIByTime" ); 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( silh = cvGetMat( silh, &silhstub )); 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mhi = cvGetMat( mhi, &mhistub )); 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MASK_ARR( silh )) 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadMask, "" ); 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_CN( mhi->type ) > 1 ) 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_BadNumChannels, "" ); 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_DEPTH( mhi->type ) != CV_32F ) 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_BadDepth, "" ); 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( mhi, silh )) 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "" ); 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size = cvGetMatSize( mhi ); 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_step = mhi->step; 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn silh_step = silh->step; 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_MAT_CONT( mhi->type & silh->type )) 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size.width *= size.height; 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_step = silh_step = CV_STUB_STEP; 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size.height = 1; 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvUpdateMotionHistory_8u32f_C1IR( (const uchar*)(silh->data.ptr), silh_step, 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi->data.fl, mhi_step, size, 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (float)timestamp, (float)mhi_duration )); 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCalcMotionGradient( const CvArr* mhiimg, CvArr* maskimg, 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvArr* orientation, 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double delta1, double delta2, 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int aperture_size ) 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat *dX_min = 0, *dY_max = 0; 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IplConvKernel* el = 0; 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCalcMotionGradient" ); 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat mhistub, *mhi = (CvMat*)mhiimg; 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat maskstub, *mask = (CvMat*)maskimg; 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat orientstub, *orient = (CvMat*)orientation; 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat dX_min_row, dY_max_row, orient_row, mask_row; 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y; 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float gradient_epsilon = 1e-4f * aperture_size * aperture_size; 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float min_delta, max_delta; 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mhi = cvGetMat( mhi, &mhistub )); 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mask = cvGetMat( mask, &maskstub )); 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( orient = cvGetMat( orient, &orientstub )); 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MASK_ARR( mask )) 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadMask, "" ); 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( aperture_size < 3 || aperture_size > 7 || (aperture_size & 1) == 0 ) 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "aperture_size must be 3, 5 or 7" ); 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta1 <= 0 || delta2 <= 0 ) 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "both delta's must be positive" ); 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE( mhi->type ) != CV_32FC1 || CV_MAT_TYPE( orient->type ) != CV_32FC1 ) 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "MHI and orientation must be single-channel floating-point images" ); 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( mhi, mask ) || !CV_ARE_SIZES_EQ( orient, mhi )) 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "" ); 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( orient->data.ptr == mhi->data.ptr ) 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsInplaceNotSupported, "orientation image must be different from MHI" ); 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta1 > delta2 ) 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t; 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( delta1, delta2, t ); 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size = cvGetMatSize( mhi ); 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn min_delta = (float)delta1; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_delta = (float)delta2; 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dX_min = cvCreateMat( mhi->rows, mhi->cols, CV_32F )); 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dY_max = cvCreateMat( mhi->rows, mhi->cols, CV_32F )); 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* calc Dx and Dy */ 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvSobel( mhi, dX_min, 1, 0, aperture_size )); 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvSobel( mhi, dY_max, 0, 1, aperture_size )); 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( dX_min, &dX_min_row, 0 ); 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( dY_max, &dY_max_row, 0 ); 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( orient, &orient_row, 0 ); 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( mask, &mask_row, 0 ); 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* calc gradient */ 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < size.height; y++ ) 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient_row.data.ptr = orient->data.ptr + y*orient->step; 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr = mask->data.ptr + y*mask->step; 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvCartToPolar( &dX_min_row, &dY_max_row, 0, &orient_row, 1 ); 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* make orientation zero where the gradient is very small */ 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < size.width; x++ ) 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dY = dY_max_row.data.fl[x]; 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dX = dX_min_row.data.fl[x]; 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(dX) < gradient_epsilon && fabs(dY) < gradient_epsilon ) 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr[x] = 0; 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient_row.data.i[x] = 0; 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr[x] = 1; 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( el = cvCreateStructuringElementEx( aperture_size, aperture_size, 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn aperture_size/2, aperture_size/2, CV_SHAPE_RECT )); 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvErode( mhi, dX_min, el ); 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvDilate( mhi, dY_max, el ); 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* mask off pixels which have little motion difference in their neighborhood */ 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < size.height; y++ ) 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr = mask->data.ptr + y*mask->step; 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient_row.data.ptr = orient->data.ptr + y*orient->step; 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < size.width; x++ ) 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float d0 = dY_max_row.data.fl[x] - dX_min_row.data.fl[x]; 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask_row.data.ptr[x] == 0 || d0 < min_delta || max_delta < d0 ) 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr[x] = 0; 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient_row.data.i[x] = 0; 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &dX_min ); 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &dY_max ); 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseStructuringElement( &el ); 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL double 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCalcGlobalOrientation( const void* orientation, const void* maskimg, const void* mhiimg, 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double curr_mhi_timestamp, double mhi_duration ) 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double angle = 0; 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int hist_size = 12; 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvHistogram* hist = 0; 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCalcGlobalOrientation" ); 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat mhistub, *mhi = (CvMat*)mhiimg; 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat maskstub, *mask = (CvMat*)maskimg; 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat orientstub, *orient = (CvMat*)orientation; 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* _orient; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float _ranges[] = { 0, 360 }; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* ranges = _ranges; 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int base_orient; 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double shift_orient = 0, shift_weight = 0, fbase_orient; 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double a, b; 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float delbound; 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat mhi_row, mask_row, orient_row; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y, mhi_rows, mhi_cols; 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mhi = cvGetMat( mhi, &mhistub )); 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mask = cvGetMat( mask, &maskstub )); 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( orient = cvGetMat( orient, &orientstub )); 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MASK_ARR( mask )) 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadMask, "" ); 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE( mhi->type ) != CV_32FC1 || CV_MAT_TYPE( orient->type ) != CV_32FC1 ) 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "MHI and orientation must be single-channel floating-point images" ); 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( mhi, mask ) || !CV_ARE_SIZES_EQ( orient, mhi )) 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "" ); 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhi_duration <= 0 ) 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "MHI duration must be positive" ); 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( orient->data.ptr == mhi->data.ptr ) 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsInplaceNotSupported, "orientation image must be different from MHI" ); 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // calculate histogram of different orientation values 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( hist = cvCreateHist( 1, &hist_size, CV_HIST_ARRAY, &ranges )); 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _orient = orient; 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvCalcArrHist( &_orient, hist, 0, mask ); 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // find the maximum index (the dominant orientation) 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetMinMaxHistValue( hist, 0, 0, 0, &base_orient ); 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_orient *= 360/hist_size; 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // override timestamp with the maximum value in MHI 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvMinMaxLoc( mhi, 0, &curr_mhi_timestamp, 0, 0, mask ); 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // find the shift relative to the dominant orientation as weighted sum of relative angles 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = 254. / 255. / mhi_duration; 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b = 1. - curr_mhi_timestamp * a; 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fbase_orient = base_orient; 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delbound = (float)(curr_mhi_timestamp - mhi_duration); 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_rows = mhi->rows; 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_cols = mhi->cols; 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_MAT_CONT( mhi->type & mask->type & orient->type )) 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_cols *= mhi_rows; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_rows = 1; 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( mhi, &mhi_row, 0 ); 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( mask, &mask_row, 0 ); 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGetRow( orient, &orient_row, 0 ); 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = 254/(255*dt) 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b = 1 - t*a = 1 - 254*t/(255*dur) = 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (255*dt - 254*t)/(255*dt) = 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (dt - (t - dt)*254)/(255*dt); 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn -------------------------------------------------------- 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ax + b = 254*x/(255*dt) + (dt - (t - dt)*254)/(255*dt) = 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (254*x + dt - (t - dt)*254)/(255*dt) = 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((x - (t - dt))*254 + dt)/(255*dt) = 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((x - (t - dt))/dt)*254 + 1)/255 = (((x - low_time)/dt)*254 + 1)/255 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < mhi_rows; y++ ) 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_row.data.ptr = mhi->data.ptr + mhi->step*y; 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row.data.ptr = mask->data.ptr + mask->step*y; 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient_row.data.ptr = orient->data.ptr + orient->step*y; 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < mhi_cols; x++ ) 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask_row.data.ptr[x] != 0 && mhi_row.data.fl[x] > delbound ) 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orient in 0..360, base_orient in 0..360 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn -> (rel_angle = orient - base_orient) in -360..360. 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rel_angle is translated to -180..180 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double weight = mhi_row.data.fl[x] * a + b; 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int rel_angle = cvRound( orient_row.data.fl[x] - fbase_orient ); 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rel_angle += (rel_angle < -180 ? 360 : 0); 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rel_angle += (rel_angle > 180 ? -360 : 0); 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( abs(rel_angle) < 90 ) 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn shift_orient += weight * rel_angle; 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn shift_weight += weight; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // add the dominant orientation and the relative shift 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( shift_weight == 0 ) 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn shift_weight = 0.01; 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_orient = base_orient + cvRound( shift_orient / shift_weight ); 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_orient -= (base_orient < 360 ? 0 : 360); 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_orient += (base_orient >= 0 ? 0 : 360); 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn angle = base_orient; 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseHist( &hist ); 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return angle; 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq* 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSegmentMotion( const CvArr* mhiimg, CvArr* segmask, CvMemStorage* storage, 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double timestamp, double seg_thresh ) 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* components = 0; 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* mask8u = 0; 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSegmentMotion" ); 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat mhistub, *mhi = (CvMat*)mhiimg; 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat maskstub, *mask = (CvMat*)segmask; 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cv32suf v, comp_idx; 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int stub_val, ts; 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y; 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL memory storage" ); 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mhi = cvGetMat( mhi, &mhistub )); 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mask = cvGetMat( mask, &maskstub )); 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE( mhi->type ) != CV_32FC1 || CV_MAT_TYPE( mask->type ) != CV_32FC1 ) 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_BadDepth, "Both MHI and the destination mask" ); 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( mhi, mask )) 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "" ); 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mask8u = cvCreateMat( mhi->rows + 2, mhi->cols + 2, CV_8UC1 )); 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvZero( mask8u ); 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvZero( mask ); 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( components = cvCreateSeq( CV_SEQ_KIND_GENERIC, sizeof(CvSeq), 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(CvConnectedComp), storage )); 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v.f = (float)timestamp; ts = v.i; 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v.f = FLT_MAX*0.1f; stub_val = v.i; 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn comp_idx.f = 1; 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < mhi->rows; y++ ) 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* mhi_row = (int*)(mhi->data.ptr + y*mhi->step); 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < mhi->cols; x++ ) 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhi_row[x] == 0 ) 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_row[x] = stub_val; 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < mhi->rows; y++ ) 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* mhi_row = (int*)(mhi->data.ptr + y*mhi->step); 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* mask8u_row = mask8u->data.ptr + (y+1)*mask8u->step + 1; 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < mhi->cols; x++ ) 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhi_row[x] == ts && mask8u_row[x] == 0 ) 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvConnectedComp comp; 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x1, y1; 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvScalar _seg_thresh = cvRealScalar(seg_thresh); 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint seed = cvPoint(x,y); 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvFloodFill( mhi, seed, cvRealScalar(0), _seg_thresh, _seg_thresh, 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &comp, CV_FLOODFILL_MASK_ONLY + 2*256 + 4, mask8u )); 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y1 = 0; y1 < comp.rect.height; y1++ ) 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* mask_row1 = (int*)(mask->data.ptr + 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (comp.rect.y + y1)*mask->step) + comp.rect.x; 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* mask8u_row1 = mask8u->data.ptr + 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (comp.rect.y + y1+1)*mask8u->step + comp.rect.x+1; 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x1 = 0; x1 < comp.rect.width; x1++ ) 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask8u_row1[x1] > 1 ) 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask8u_row1[x1] = 1; 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row1[x1] = comp_idx.i; 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn comp_idx.f++; 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPush( components, &comp ); 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < mhi->rows; y++ ) 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* mhi_row = (int*)(mhi->data.ptr + y*mhi->step); 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < mhi->cols; x++ ) 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mhi_row[x] == stub_val ) 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mhi_row[x] = 0; 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &mask8u ); 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return components; 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */ 518