• 【OpenCV3】threshold()函数详解


    threshold()函数源码

    double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type )
    {

    // enum
    //{
    // CV_THRESH_BINARY =0, /**< value = value > threshold ? max_value : 0 */
    // CV_THRESH_BINARY_INV =1, /**< value = value > threshold ? 0 : max_value */
    // CV_THRESH_TRUNC =2, /**< value = value > threshold ? threshold : value */
    // CV_THRESH_TOZERO =3, /**< value = value > threshold ? value : 0 */
    // CV_THRESH_TOZERO_INV =4, /**< value = value > threshold ? 0 : value */
    // CV_THRESH_MASK =7,
    // CV_THRESH_OTSU =8, /**< use Otsu algorithm to choose the optimal threshold value;
    // combine the flag with one of the above CV_THRESH_* values */
    // CV_THRESH_TRIANGLE =16 /**< use Triangle algorithm to choose the optimal threshold value;
    // combine the flag with one of the above CV_THRESH_* values, but not
    // with CV_THRESH_OTSU */
    //};

        CV_INSTRUMENT_REGION();
    
        CV_OCL_RUN_(_src.dims() <= 2 && _dst.isUMat(),
                    ocl_threshold(_src, _dst, thresh, maxval, type), thresh)
    
        Mat src = _src.getMat();
        int automatic_thresh = (type & ~CV_THRESH_MASK);// 排除前五种可能,判断是否是CV_THRESH_OTSU  CV_THRESH_TRIANGLE(8,16)
        type &= THRESH_MASK; // THRESH_MASK(7) 得到当前二值化的类型(前五种),0,1,2,3,4
    
        CV_Assert( automatic_thresh != (CV_THRESH_OTSU | CV_THRESH_TRIANGLE) );
        if( automatic_thresh == CV_THRESH_OTSU )// 判断是否是CV_THRESH_OTSU(8)
        {
        //  使用算法选择最佳阈值;将标志与上述cv_thresh_*值之一相结合 计算最佳阈值 CV_Assert( src.type()
    == CV_8UC1 ); thresh = getThreshVal_Otsu_8u( src ); } else if( automatic_thresh == CV_THRESH_TRIANGLE )// 判断是否是CV_THRESH_TRIANGLE(16) {
        // 使用三角算法选择最优阈值;将标志与上述cv_thresh_*值之一组合,但不使用cv_thresh_otsu 计算最佳阈值 CV_Assert( src.type()
    == CV_8UC1 ); thresh = getThreshVal_Triangle_8u( src ); } _dst.create( src.size(), src.type() );// 创建目标图像 Mat dst = _dst.getMat(); if( src.depth() == CV_8U )// 如果原始图像的深度为8位无符号 { int ithresh = cvFloor(thresh);// 将thresh向下取整 thresh = ithresh; int imaxval = cvRound(maxval); // 将maxval向最接近的整数取整 if( type == THRESH_TRUNC ) imaxval = ithresh; imaxval = saturate_cast<uchar>(imaxval); if( ithresh < 0 || ithresh >= 255 ) { if( type == THRESH_BINARY || type == THRESH_BINARY_INV || ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < 0) || (type == THRESH_TOZERO && ithresh >= 255) ) { int v = type == THRESH_BINARY ? (ithresh >= 255 ? 0 : imaxval) : type == THRESH_BINARY_INV ? (ithresh >= 255 ? imaxval : 0) : /*type == THRESH_TRUNC ? imaxval :*/ 0; dst.setTo(v); } else src.copyTo(dst); return thresh; } CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_THRESHOLD>(src.cols, src.rows), openvx_threshold(src, dst, ithresh, imaxval, type), (double)ithresh) thresh = ithresh; maxval = imaxval; } else if( src.depth() == CV_16S )// 如果原始图像的深度为16位short类型 { int ithresh = cvFloor(thresh); thresh = ithresh; int imaxval = cvRound(maxval); if( type == THRESH_TRUNC ) imaxval = ithresh; imaxval = saturate_cast<short>(imaxval); if( ithresh < SHRT_MIN || ithresh >= SHRT_MAX ) { if( type == THRESH_BINARY || type == THRESH_BINARY_INV || ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < SHRT_MIN) || (type == THRESH_TOZERO && ithresh >= SHRT_MAX) ) { int v = type == THRESH_BINARY ? (ithresh >= SHRT_MAX ? 0 : imaxval) : type == THRESH_BINARY_INV ? (ithresh >= SHRT_MAX ? imaxval : 0) : /*type == THRESH_TRUNC ? imaxval :*/ 0; dst.setTo(v); } else src.copyTo(dst); return thresh; } thresh = ithresh; maxval = imaxval; } else if (src.depth() == CV_16U )// 如果原始图像的深度为16位无符号 { int ithresh = cvFloor(thresh); thresh = ithresh; int imaxval = cvRound(maxval); if (type == THRESH_TRUNC) imaxval = ithresh; imaxval = saturate_cast<ushort>(imaxval); int ushrt_min = 0; if (ithresh < ushrt_min || ithresh >= (int)USHRT_MAX) { if (type == THRESH_BINARY || type == THRESH_BINARY_INV || ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < ushrt_min) || (type == THRESH_TOZERO && ithresh >= (int)USHRT_MAX)) { int v = type == THRESH_BINARY ? (ithresh >= (int)USHRT_MAX ? 0 : imaxval) : type == THRESH_BINARY_INV ? (ithresh >= (int)USHRT_MAX ? imaxval : 0) : /*type == THRESH_TRUNC ? imaxval :*/ 0; dst.setTo(v); } else src.copyTo(dst); return thresh; } thresh = ithresh; maxval = imaxval; } else if( src.depth() == CV_32F )// 如果原始图像的深度为32位浮点型 ; else if( src.depth() == CV_64F )// 如果原始图像的深度为64位浮点型 ; else CV_Error( CV_StsUnsupportedFormat, "" ); // 不能识别的图像格式 parallel_for_(Range(0, dst.rows), ThresholdRunner(src, dst, thresh, maxval, type), dst.total()/(double)(1<<16)); return thresh; }

     threshold()函数二值化的方法(types)/** Threshold types */

    enum
    {
        CV_THRESH_BINARY      =0,  /**< value = value > threshold ? max_value : 0       正向二值化*/
        CV_THRESH_BINARY_INV  =1,  /**< value = value > threshold ? 0 : max_value       反向二值化*/
        CV_THRESH_TRUNC       =2,  /**< value = value > threshold ? threshold : value   */
        CV_THRESH_TOZERO      =3,  /**< value = value > threshold ? value : 0           */
        CV_THRESH_TOZERO_INV  =4,  /**< value = value > threshold ? 0 : value           */
        CV_THRESH_MASK        =7,  // 掩码
        CV_THRESH_OTSU        =8, /**< use Otsu algorithm to choose the optimal threshold value;
                                     combine the flag with one of the above CV_THRESH_* values 
                        使用算法选择最佳阈值;将标志与上述cv_thresh_*值之一相结合*/ CV_THRESH_TRIANGLE =16 /**< use Triangle algorithm to choose the optimal threshold value; combine the flag with one of the above CV_THRESH_* values, but not with CV_THRESH_OTSU
                        使用三角算法选择最优阈值;将标志与上述cv_thresh_*值之一组合,但不使用cv_thresh_otsu*/ };
  • 相关阅读:
    怎么控制 echarts提示框浮层的内容
    控制echarts 柱状图啊的柱条的宽度
    如何控制echartsY轴颠倒
    mac mysql nginx
    input textarea 获取焦点挡住输入法 解决办法
    react 记录
    微信内自动播放audio
    react router
    mysql 记录
    express 插件
  • 原文地址:https://www.cnblogs.com/hs-pingfan/p/10494264.html
Copyright © 2020-2023  润新知