【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*/ };
上一篇: 不用加减乘除做加法
下一篇: js创建对象的三种方式