CV_IMPL int cvCountNonZero( const CvArr* arr ) { static CvFuncTable nz_tab; static CvFuncTable nzcoi_tab; static int inittab = 0; int count = 0; CV_FUNCNAME("cvCountNonZero"); __BEGIN__; int type, coi = 0; int mat_step; CvSize size; CvMat stub, *mat = (CvMat*)arr; if( !inittab ) { icvInitCountNonZeroC1RTable( &nz_tab ); icvInitCountNonZeroCnCRTable( &nzcoi_tab ); inittab = 1; } if( !CV_IS_MAT(mat) ) { if( CV_IS_MATND(mat) ) { void* matnd = (void*)arr; CvMatND nstub; CvNArrayIterator iterator; CvFunc2D_1A1P func; CV_CALL( cvInitNArrayIterator( 1, &matnd, 0, &nstub, &iterator )); type = CV_MAT_TYPE(iterator.hdr[0]->type); if( CV_MAT_CN(type) != 1 ) CV_ERROR( CV_BadNumChannels, "Only single-channel array are supported here" ); func = (CvFunc2D_1A1P)(nz_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { int temp; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, &temp )); count += temp; } while( cvNextNArraySlice( &iterator )); EXIT; } else CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_MAT_TYPE(mat->type); size = cvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_MAT_CONT( mat->type )) { size.width *= size.height; size.height = 1; mat_step = CV_STUB_STEP; } if( CV_MAT_CN(type) == 1 || coi == 0 ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(nz_tab.fn_2d[CV_MAT_DEPTH(type)]); if( CV_MAT_CN(type) != 1 ) CV_ERROR( CV_BadNumChannels, "The function can handle only a single channel at a time (use COI)"); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, &count )); } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(nzcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_MAT_CN(type), coi, &count )); } __END__; return count; }
CV_IMPL CvScalar cvSum( const CvArr* arr ) { static CvBigFuncTable sum_tab; static CvFuncTable sumcoi_tab; static int inittab = 0; CvScalar sum = {{0,0,0,0}}; CV_FUNCNAME("cvSum"); __BEGIN__; int type, coi = 0; int mat_step; CvSize size; CvMat stub, *mat = (CvMat*)arr; if( !inittab ) { icvInitSumRTable( &sum_tab ); icvInitSumCnCRTable( &sumcoi_tab ); inittab = 1; } if( !CV_IS_MAT(mat) ) { if( CV_IS_MATND(mat) ) { void* matnd = (void*)mat; CvMatND nstub; CvNArrayIterator iterator; int pass_hint; CV_CALL( cvInitNArrayIterator( 1, &matnd, 0, &nstub, &iterator )); type = CV_MAT_TYPE(iterator.hdr[0]->type); if( CV_MAT_CN(type) > 4 ) CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels" ); pass_hint = CV_MAT_DEPTH(type) == CV_32F; if( !pass_hint ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { CvScalar temp = {{0,0,0,0}}; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, temp.val )); sum.val[0] += temp.val[0]; sum.val[1] += temp.val[1]; sum.val[2] += temp.val[2]; sum.val[3] += temp.val[3]; } while( cvNextNArraySlice( &iterator )); } else { CvFunc2D_1A1P1I func = (CvFunc2D_1A1P1I)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { CvScalar temp = {{0,0,0,0}}; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, temp.val, cvAlgHintAccurate )); sum.val[0] += temp.val[0]; sum.val[1] += temp.val[1]; sum.val[2] += temp.val[2]; sum.val[3] += temp.val[3]; } while( cvNextNArraySlice( &iterator )); } EXIT; } else CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_MAT_TYPE(mat->type); size = cvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_MAT_CONT( mat->type )) { size.width *= size.height; if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE ) { if( type == CV_32FC1 ) { float* data = mat->data.fl; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } if( type == CV_64FC1 ) { double* data = mat->data.db; do { sum.val[0] += data[size.width - 1]; } while( --size.width ); EXIT; } } size.height = 1; mat_step = CV_STUB_STEP; } if( CV_MAT_CN(type) == 1 || coi == 0 ) { int pass_hint = CV_MAT_DEPTH(type) == CV_32F; if( CV_MAT_CN(type) > 4 ) CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels" ); if( !pass_hint ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, sum.val )); } else { CvFunc2D_1A1P1I func = (CvFunc2D_1A1P1I)(sum_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, sum.val, cvAlgHintAccurate )); } } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(sumcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_MAT_CN(type), coi, sum.val )); } __END__; return sum; }