www.pudn.com > OpenCV-Intel.zip > cvthresh.cpp


/*M/////////////////////////////////////////////////////////////////////////////////////// 
// 
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 
// 
//  By downloading, copying, installing or using the software you agree to this license. 
//  If you do not agree to this license, do not download, install, 
//  copy or use the software. 
// 
// 
//                        Intel License Agreement 
//                For Open Source Computer Vision Library 
// 
// Copyright (C) 2000, Intel Corporation, all rights reserved. 
// Third party copyrights are property of their respective owners. 
// 
// Redistribution and use in source and binary forms, with or without modification, 
// are permitted provided that the following conditions are met: 
// 
//   * Redistribution's of source code must retain the above copyright notice, 
//     this list of conditions and the following disclaimer. 
// 
//   * Redistribution's in binary form must reproduce the above copyright notice, 
//     this list of conditions and the following disclaimer in the documentation 
//     and/or other materials provided with the distribution. 
// 
//   * The name of Intel Corporation may not be used to endorse or promote products 
//     derived from this software without specific prior written permission. 
// 
// This software is provided by the copyright holders and contributors "as is" and 
// any express or implied warranties, including, but not limited to, the implied 
// warranties of merchantability and fitness for a particular purpose are disclaimed. 
// In no event shall the Intel Corporation or contributors be liable for any direct, 
// indirect, incidental, special, exemplary, or consequential damages 
// (including, but not limited to, procurement of substitute goods or services; 
// loss of use, data, or profits; or business interruption) however caused 
// and on any theory of liability, whether in contract, strict liability, 
// or tort (including negligence or otherwise) arising in any way out of 
// the use of this software, even if advised of the possibility of such damage. 
// 
//M*/ 
 
#include "_cv.h" 
 
static CvStatus CV_STDCALL 
icvThresh_8u_C1R( const uchar* src, int src_step, uchar* dst, int dst_step, 
                  CvSize roi, uchar thresh, uchar maxval, int type ) 
{ 
    int i, j; 
    uchar tab[256]; 
 
    switch( type ) 
    { 
    case CV_THRESH_BINARY: 
        for( i = 0; i <= thresh; i++ ) 
            tab[i] = 0; 
        for( ; i < 256; i++ ) 
            tab[i] = maxval; 
        break; 
    case CV_THRESH_BINARY_INV: 
        for( i = 0; i <= thresh; i++ ) 
            tab[i] = maxval; 
        for( ; i < 256; i++ ) 
            tab[i] = 0; 
        break; 
    case CV_THRESH_TRUNC: 
        for( i = 0; i <= thresh; i++ ) 
            tab[i] = (uchar)i; 
        for( ; i < 256; i++ ) 
            tab[i] = thresh; 
        break; 
    case CV_THRESH_TOZERO: 
        for( i = 0; i <= thresh; i++ ) 
            tab[i] = 0; 
        for( ; i < 256; i++ ) 
            tab[i] = (uchar)i; 
        break; 
    case CV_THRESH_TOZERO_INV: 
        for( i = 0; i <= thresh; i++ ) 
            tab[i] = (uchar)i; 
        for( ; i < 256; i++ ) 
            tab[i] = 0; 
        break; 
    default: 
        return CV_BADFLAG_ERR; 
    } 
 
    for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) 
    { 
        for( j = 0; j <= roi.width - 4; j += 4 ) 
        { 
            uchar t0 = tab[src[j]]; 
            uchar t1 = tab[src[j+1]]; 
 
            dst[j] = t0; 
            dst[j+1] = t1; 
 
            t0 = tab[src[j+2]]; 
            t1 = tab[src[j+3]]; 
 
            dst[j+2] = t0; 
            dst[j+3] = t1; 
        } 
 
        for( ; j < roi.width; j++ ) 
            dst[j] = tab[src[j]]; 
    } 
 
    return CV_NO_ERR; 
} 
 
 
static CvStatus CV_STDCALL 
icvThresh_32f_C1R( const float *src, int src_step, float *dst, int dst_step, 
                   CvSize roi, float thresh, float maxval, int type ) 
{ 
    int i, j; 
    const int* isrc = (const int*)src; 
    int* idst = (int*)dst; 
    int iThresh = CV_TOGGLE_FLT( (int &) thresh ); 
    int iMax = (int &) maxval; 
 
    src_step /= sizeof(src[0]); 
    dst_step /= sizeof(dst[0]); 
 
    switch( type ) 
    { 
    case CV_THRESH_BINARY: 
        for( i = 0; i < roi.height; i++, isrc += src_step, idst += dst_step ) 
        { 
            for( j = 0; j < roi.width; j++ ) 
            { 
                int temp = isrc[j]; 
                idst[j] = ((CV_TOGGLE_FLT(temp) <= iThresh) - 1) & iMax; 
            } 
        } 
        break; 
 
    case CV_THRESH_BINARY_INV: 
        for( i = 0; i < roi.height; i++, isrc += src_step, idst += dst_step ) 
        { 
            for( j = 0; j < roi.width; j++ ) 
            { 
                int temp = isrc[j]; 
                idst[j] = ((CV_TOGGLE_FLT(temp) > iThresh) - 1) & iMax; 
            } 
        } 
        break; 
 
    case CV_THRESH_TRUNC: 
        for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) 
        { 
            for( j = 0; j < roi.width; j++ ) 
            { 
                float temp = src[j]; 
 
                if( temp > thresh ) 
                    temp = thresh; 
                dst[j] = temp; 
            } 
        } 
        break; 
 
    case CV_THRESH_TOZERO: 
        for( i = 0; i < roi.height; i++, isrc += src_step, idst += dst_step ) 
        { 
            for( j = 0; j < roi.width; j++ ) 
            { 
                int temp = isrc[j]; 
                idst[j] = ((CV_TOGGLE_FLT( temp ) <= iThresh) - 1) & temp; 
            } 
        } 
        break; 
 
    case CV_THRESH_TOZERO_INV: 
        for( i = 0; i < roi.height; i++, isrc += src_step, idst += dst_step ) 
        { 
            for( j = 0; j < roi.width; j++ ) 
            { 
                int temp = isrc[j]; 
                idst[j] = ((CV_TOGGLE_FLT( temp ) > iThresh) - 1) & temp; 
            } 
        } 
        break; 
 
    default: 
        return CV_BADFLAG_ERR; 
    } 
 
    return CV_OK; 
} 
 
 
icvAndC_8u_C1R_t icvAndC_8u_C1R_p = 0; 
icvCompareC_8u_C1R_t icvCompareC_8u_C1R_p = 0; 
icvThreshold_GTVal_8u_C1R_t icvThreshold_GTVal_8u_C1R_p = 0; 
icvThreshold_GTVal_32f_C1R_t icvThreshold_GTVal_32f_C1R_p = 0; 
icvThreshold_LTVal_8u_C1R_t icvThreshold_LTVal_8u_C1R_p = 0; 
icvThreshold_LTVal_32f_C1R_t icvThreshold_LTVal_32f_C1R_p = 0; 
 
CV_IMPL void 
cvThreshold( const void* srcarr, void* dstarr, double thresh, double maxval, int type ) 
{ 
    CV_FUNCNAME( "cvThreshold" ); 
 
    __BEGIN__; 
 
    CvSize roi; 
    int src_step, dst_step; 
    CvMat src_stub, *src = (CvMat*)srcarr; 
    CvMat dst_stub, *dst = (CvMat*)dstarr; 
    CvMat src0, dst0; 
    int coi1 = 0, coi2 = 0; 
    int ithresh, imaxval, cn; 
 
    CV_CALL( src = cvGetMat( src, &src_stub, &coi1 )); 
    CV_CALL( dst = cvGetMat( dst, &dst_stub, &coi2 )); 
 
    if( coi1 + coi2 ) 
        CV_ERROR( CV_BadCOI, "COI is not supported by the function" ); 
 
    if( !CV_ARE_CNS_EQ( src, dst ) ) 
        CV_ERROR( CV_StsUnmatchedFormats, "Both arrays must have equal number of channels" ); 
 
    cn = CV_MAT_CN(src->type); 
    if( cn > 1 ) 
    { 
        src = cvReshape( src, &src0, 1 ); 
        dst = cvReshape( dst, &dst0, 1 ); 
    } 
 
    if( !CV_ARE_DEPTHS_EQ( src, dst ) ) 
    { 
        if( CV_MAT_TYPE(dst->type) != CV_8UC1 ) 
            CV_ERROR( CV_StsUnsupportedFormat, "In case of different types destination should be 8uC1" ); 
 
        if( type != CV_THRESH_BINARY && type != CV_THRESH_BINARY_INV ) 
            CV_ERROR( CV_StsBadArg, 
            "In case of different types only CV_THRESH_BINARY " 
            "and CV_THRESH_BINARY_INV thresholding types are supported" ); 
 
        if( maxval < 0 ) 
        { 
            CV_CALL( cvSetZero( dst )); 
        } 
        else 
        { 
            CV_CALL( cvCmpS( src, thresh, dst, type == CV_THRESH_BINARY ? CV_CMP_GT : CV_CMP_LE )); 
            if( maxval < 255 ) 
                CV_CALL( cvAndS( dst, cvScalarAll( maxval ), dst )); 
        } 
        EXIT; 
    } 
 
    if( !CV_ARE_SIZES_EQ( src, dst ) ) 
        CV_ERROR( CV_StsUnmatchedSizes, "" ); 
 
    roi = cvGetMatSize( src ); 
    if( CV_IS_MAT_CONT( src->type & dst->type )) 
    { 
        roi.width *= roi.height; 
        roi.height = 1; 
        src_step = dst_step = CV_STUB_STEP; 
    } 
    else 
    { 
        src_step = src->step; 
        dst_step = dst->step; 
    } 
 
    switch( CV_MAT_DEPTH(src->type) ) 
    { 
    case CV_8U: 
         
        ithresh = cvFloor(thresh); 
        imaxval = cvRound(maxval); 
        if( type == CV_THRESH_TRUNC ) 
            imaxval = ithresh; 
        imaxval = CV_CAST_8U(imaxval); 
 
        if( ithresh < 0 || ithresh >= 255 ) 
        { 
            if( type == CV_THRESH_BINARY || type == CV_THRESH_BINARY_INV || 
                (type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV) && ithresh < 0 || 
                type == CV_THRESH_TOZERO && ithresh >= 255 ) 
            { 
                int v = type == CV_THRESH_BINARY ? (ithresh >= 255 ? 0 : imaxval) : 
                        type == CV_THRESH_BINARY_INV ? (ithresh >= 255 ? imaxval : 0) : 
                        type == CV_THRESH_TRUNC ? imaxval : 0; 
 
                cvSet( dst, cvScalarAll(v) ); 
                EXIT; 
            } 
            else 
            { 
                cvCopy( src, dst ); 
                EXIT; 
            } 
        } 
 
        if( type == CV_THRESH_BINARY || type == CV_THRESH_BINARY_INV ) 
        { 
            if( icvCompareC_8u_C1R_p && icvAndC_8u_C1R_p ) 
            { 
                IPPI_CALL( icvCompareC_8u_C1R_p( src->data.ptr, src_step, 
                    (uchar)ithresh, dst->data.ptr, dst_step, roi, 
                    type == CV_THRESH_BINARY ? cvCmpGreater : cvCmpLessEq )); 
 
                if( imaxval < 255 ) 
                    IPPI_CALL( icvAndC_8u_C1R_p( dst->data.ptr, dst_step, 
                    (uchar)imaxval, dst->data.ptr, dst_step, roi )); 
                EXIT; 
            } 
        } 
        else if( type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV ) 
        { 
            if( icvThreshold_GTVal_8u_C1R_p ) 
            { 
                IPPI_CALL( icvThreshold_GTVal_8u_C1R_p( src->data.ptr, src_step, 
                    dst->data.ptr, dst_step, roi, (uchar)ithresh, 
                    (uchar)(type == CV_THRESH_TRUNC ? ithresh : 0) )); 
                EXIT; 
            } 
        } 
        else 
        { 
            assert( type == CV_THRESH_TOZERO ); 
            if( icvThreshold_LTVal_8u_C1R_p ) 
            { 
                ithresh = cvFloor(thresh+1.); 
                ithresh = CV_CAST_8U(ithresh); 
                IPPI_CALL( icvThreshold_LTVal_8u_C1R_p( src->data.ptr, src_step, 
                    dst->data.ptr, dst_step, roi, (uchar)ithresh, 0 )); 
                EXIT; 
            } 
        } 
 
        icvThresh_8u_C1R( src->data.ptr, src_step, 
                          dst->data.ptr, dst_step, roi, 
                          (uchar)ithresh, (uchar)imaxval, type ); 
        break; 
    case CV_32F: 
 
        if( type == CV_THRESH_TRUNC || type == CV_THRESH_TOZERO_INV ) 
        { 
            if( icvThreshold_GTVal_32f_C1R_p ) 
            { 
                IPPI_CALL( icvThreshold_GTVal_32f_C1R_p( src->data.fl, src_step, 
                    dst->data.fl, dst_step, roi, (float)thresh, 
                    type == CV_THRESH_TRUNC ? (float)thresh : 0 )); 
                EXIT; 
            } 
        } 
        else if( type == CV_THRESH_TOZERO ) 
        { 
            if( icvThreshold_LTVal_32f_C1R_p ) 
            { 
                IPPI_CALL( icvThreshold_LTVal_32f_C1R_p( src->data.fl, src_step, 
                    dst->data.fl, dst_step, roi, (float)(thresh*(1 + FLT_EPSILON)), 0 )); 
                EXIT; 
            } 
        } 
 
        icvThresh_32f_C1R( src->data.fl, src_step, dst->data.fl, dst_step, roi, 
                           (float)thresh, (float)maxval, type ); 
        break; 
    default: 
        CV_ERROR( CV_BadDepth, cvUnsupportedFormat ); 
    } 
 
    __END__; 
} 
 
/* End of file. */