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 int cvCountNonZero( const CvArr* img ) { 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*)img; if( !inittab ) { icvInitCountNonZeroC1RTable( &nz_tab ); icvInitCountNonZeroCnCRTable( &nzcoi_tab ); inittab = 1; } if( !CV_IS_ARR(mat) ) { CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_ARR_TYPE(mat->type); size = icvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_ARR_CONT( mat->type )) { size.width *= size.height; size.height = 1; mat_step = CV_STUB_STEP; } if( CV_ARR_CN(type) == 1 || coi == 0 ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(nz_tab.fn_2d[CV_ARR_DEPTH(type)]); if( CV_ARR_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, icvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, &count )); } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(nzcoi_tab.fn_2d[CV_ARR_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, icvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_ARR_CN(type), coi, &count )); } __END__; return count; }