Opencv 笔记2 全局固定阈值二值化和局部自适应阈值二值化

一、二值化

 二值化是将一张单通道的图像中的像素分别设为0或者255 的操作,在数字图像处理的过程中这个一部分是很重要的,halcon 中有9个二值化的算子,每个用法都有各自的优势,这个等后面复习halcon 的时候再总结一下,然后和Opencv的二值化做一个对比,这里只说threshold和adaptiveThreshold算子

二、全局固定二值化-threshold

double threshold( 
const Mat& src,  // 必须是   8/32  位的图像
Mat& dst, 
double thresh, // 手动输入的阈值0-255
double maxVal,  // 最大阈值 一般都是255
int thresholdType // 这个是最重要的一个参数:阈值类型,有如下几个类型:
src(x,y) 表示原图的(x,y)点的像素值,thresh,手动输入的参数值,maxVal 最大值:
          THRESH_BINARY:src(x,y)>thresh?maxVal:0;
          THRESH_BINARY_INV:src(x,y)>thresh?0:maxVal;
          THRESH_TRUNC: src(x,y)>thresh?thresh:src(x,y);(大于阈值=阈值,其他不变)
          THRESH_TOZERO:src(x,y)>thresh?src(x,y):0;(大于阈值=原值,其他0)
          THRESH_TOZERO_INV:src(x,y)>thresh?0:src(x,y);
          THRESH_OTSU:不支持32位的,只支持8位的,非常适合有双峰的图像,
          THRESH_TRIANGLE:不支持32位的,只支持8位的,适合单个波峰

)

代码显示如下:


int  type_value = 2;
int  type_Max = 5;

Mat src, src_gray, dest1, dest2;
int threshold_value = 127;
int threshold_max = 255;
const  char* output_litle = "Binary_out_demo";
void  Threshold_Demo(int, void*);
void  Threshold_Demo(int, void*)
{
	cvtColor(src, src_gray, CV_BGR2GRAY);

	threshold(src_gray, dest1, threshold_value, threshold_max, type_value);

	imshow(output_litle, dest1);
}


int main(int args, char* arg)
{

	// point  
	src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
	if (!src.data)
	{
		printf("could not  load  image....\n");
	}
	//1 显示灰色图像
	namedWindow("input_demo", CV_WINDOW_AUTOSIZE);
	namedWindow(output_litle, CV_WINDOW_AUTOSIZE);
	imshow("input_demo", src);


	createTrackbar("Threshold Value:", output_litle, &threshold_value, threshold_max, Threshold_Demo);
	createTrackbar("Threshold Model:", output_litle, &type_value, type_Max, Threshold_Demo);
	Threshold_Demo(0, 0);
	waitKey(0);
	return -1;
}

 源码:

double threshold( InputArray _src,OutputArray _dst, double thresh, double maxval, int type )
{
   Mat src = _src.getMat();
   bool use_otsu = (type & THRESH_OTSU) != 0;
    type &= THRESH_MASK;
 
   if( use_otsu )
    {
       CV_Assert( src.type() == CV_8UC1 );
       thresh = getThreshVal_Otsu_8u(src);
    }
 
   _dst.create( src.size(), src.type() );
   Mat dst = _dst.getMat();
 
   if( src.depth() == CV_8U )
    {
        int ithresh = cvFloor(thresh);
       thresh = ithresh;
       int imaxval = cvRound(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;
       }
       thresh = ithresh;
       maxval = imaxval;
    }
   else if( src.depth() == CV_16S )
    {
       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_32F )
       ;
   else
       CV_Error( CV_StsUnsupportedFormat, "" );
 
   parallel_for_(Range(0, dst.rows),
                  ThresholdRunner(src, dst,thresh, maxval, type),
                 dst.total()/(double)(1<<16));
   return thresh;
}

三、局部自动阈值

​adaptiveThreshold(
InputArray src, // 必须是8位的图像
 OutputArray dst,
 double local,// 局部的阈值,0-255
 int adaptiveMethod, // 在邻域块中计算阈值用的方法,有两个:
            ADAPTIVE_THRESH_MEAN_C:表示计算出领域的   平均值 -C(输入的第七个参数)
            ADAPTIVE_THRESH_GAUSSIAN_C:表示计算出领域的  高斯均值 - C(输入的第七个参数)
int thresholdType, // 阈值类型,有两个类型:
                THRESH_BINARY: src(x,y)>local?255:0;
                THRESH_BINARY_INV :与THRESH_BINARY 相反
int blockSize, // 邻域块的大小,奇数
double C  // 是一个偏移量 
)

图像显示

代码显示


int  block_size = 10;
int  size_Max = 40;

Mat src, src_gray, dest1, dest2;
int local_threshold_value = 127;
int local_threshold_max = 255;
const  char* output_litle = "Binary_out_demo";
void  adaptiveThreshold_Demo(int, void*);
void  adaptiveThreshold_Demo(int, void*)
{
	cvtColor(src, src_gray, CV_BGR2GRAY);
	src_gray.convertTo(src_gray, CV_8UC1);
	int  size_s = 2 * block_size + 1;
	adaptiveThreshold(src_gray, dest1, local_threshold_value, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, size_s,10);
	imshow(output_litle, dest1);
}


int main(int args, char* arg)
{

	// point  
	src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
	if (!src.data)
	{
		printf("could not  load  image....\n");
	}
	//1 显示灰色图像
	namedWindow("input_demo", CV_WINDOW_AUTOSIZE);
	namedWindow(output_litle, CV_WINDOW_AUTOSIZE);
	imshow("input_demo", src);


	createTrackbar("local Value:", output_litle, &local_threshold_value, 255, adaptiveThreshold_Demo);
	createTrackbar("local Model:", output_litle, &block_size, size_Max, adaptiveThreshold_Demo);
	adaptiveThreshold_Demo(0, 0);
	waitKey(0);
	return -1;
}
void adaptiveThreshold( InputArray  _src, OutputArray  _dst, double maxValue,
                            int method, int type, int blockSize, double delta )
{
   Mat src = _src.getMat();
   CV_Assert( src.type() == CV_8UC1 );
   CV_Assert( blockSize % 2 == 1 && blockSize > 1 );
   Size size = src.size();
 
   _dst.create( size, src.type() );
   Mat dst = _dst.getMat();
 
   if( maxValue < 0 )
    {
       dst = Scalar(0);
       return;
    }
 
   Mat mean;
 
   if( src.data != dst.data )
       mean = dst;
 
   if( method == ADAPTIVE_THRESH_MEAN_C )
       boxFilter( src, mean, src.type(), Size(blockSize, blockSize),
                   Point(-1,-1), true,BORDER_REPLICATE );
   else if( method == ADAPTIVE_THRESH_GAUSSIAN_C )
       GaussianBlur( src, mean, Size(blockSize, blockSize), 0, 0,BORDER_REPLICATE );
   else
       CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive thresholdmethod" );
 
   int i, j;
   uchar imaxval = saturate_cast<uchar>(maxValue);
   int idelta = type == THRESH_BINARY ? cvCeil(delta) : cvFloor(delta);
   uchar tab[768];
 
   if( type == CV_THRESH_BINARY )
       for( i = 0; i < 768; i++ )
           tab[i] = (uchar)(i - 255 > -idelta ? imaxval : 0);
   else if( type == CV_THRESH_BINARY_INV )
       for( i = 0; i < 768; i++ )
           tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0);
   else
       CV_Error( CV_StsBadFlag, "Unknown/unsupported threshold type");
 
   if( src.isContinuous() && mean.isContinuous() &&dst.isContinuous() )
    {
       size.width *= size.height;
       size.height = 1;
    }
 
   for( i = 0; i < size.height; i++ )
    {
       const uchar* sdata = src.data + src.step*i;
       const uchar* mdata = mean.data + mean.step*i;
       uchar* ddata = dst.data + dst.step*i;
 
       for( j = 0; j < size.width; j++ )
           ddata[j] = tab[sdata[j] - mdata[j] + 255];
    }

}

 

 待续。。。。。。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值