Opencv图像识别从零到精通(15)-----阈值分割、固定阈值Threshold、自适应阈值分割adaptiveThreshold、OSTU大津法

    当我们用图像技术来找到图像特征的时候,其中很重要的一个步骤就是分割,不区分出来我们想要的就没有办法得到其中的参数,而这里首先介绍阈值分割,也是最基础的分割方式,一共有下面三个部分组成。本来想介绍一个函数与定义然后再跟着例子,但是感觉有点乱,然后就按现在这样来说了,当后面看到不懂的在前面的函数与定义都会提及到,希望对大家有用。

(1)、函数与定义

(2)、代码应用

  • Threshold()
  • adaptiveThreshold()
  • ostu

(3)、matlab辅助     


一、函数与定义   

       阈值分割是一种区域分割技术,将灰度根据主观愿望分成两个或者多个灰度区间,利用图像中背景和目标物体的灰度上的差异,旋转一个合适的阈值进行分割。

     一般的分割有全局分割和局部分割,这是不同的思路,在Opencv中给出了threshold(),adapativeThreshold(),这两个函数中的tpye会给出很多的方法

<span style="font-size:18px;">double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)</span>

参数信息:

  • 第一个参数,InputArray类型的src,输入数组,填单通道 , 8或32位浮点类型的Mat即可。
  • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放输出结果,且和第一个参数中的Mat变量有一样的尺寸和类型。
  • 第三个参数,double类型的thresh,阈值的具体值。
  • 第四个参数,double类型的maxval,当第五个参数阈值类型type取 THRESH_BINARY 或THRESH_BINARY_INV阈值类型时的最大值.
  • 第五个参数,int类型的type,阈值类型,。

第五个参数,第五参数有以下几种类型

  • 0: THRESH_BINARY  当前点值大于阈值时,取Maxval,也就是第四个参数,下面再不说明,否则设置为0
  • 1: THRESH_BINARY_INV 当前点值大于阈值时,设置为0,否则设置为Maxval
  • 2: THRESH_TRUNC 当前点值大于阈值时,设置为阈值,否则不改变
  • 3: THRESH_TOZERO 当前点值大于阈值时,不改变,否则设置为0
  • 4: THRESH_TOZERO_INV  当前点值大于阈值时,设置为0,否则不改变

源代码中的定义
<span style="font-size:18px;">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 */

};</span>

<span style="font-size:18px;">void cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value,
                          int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,
                          int threshold_type=CV_THRESH_BINARY,
                          int block_size=3, double param1=5 );</span>

  • src 输入图像. dst 输出图像. max_value使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值. adaptive_method自适应阈值算法使用:CV_ADAPTIVE_THRESH_MEAN_C 或 CV_ADAPTIVE_THRESH_GAUSSIAN_C (见讨论). threshold_type
    取阈值类型:必须是下者之一
    • CV_THRESH_BINARY,
    • CV_THRESH_BINARY_INV
  • block_size用来计算阈值的象素邻域大小: 3, 5, 7, ... param1与方法有关的参数。对方法 CV_ADAPTIVE_THRESH_MEAN_C 和 CV_ADAPTIVE_THRESH_GAUSSIAN_C, 它是一个从均值或加权均值提取的常数(见讨论), 尽管它可以是负数。

二、代码应用
(1)
  • Threshold()
<span style="font-size:18px;">#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat dst,gray,bluriamge;
int thresh,thresh1;
void on_thresh(int,void*)
{
	threshold(bluriamge,dst,thresh,255,thresh1);
	imshow("threshold二值化灰图",dst);
}

 int main()
 {
	Mat src;
	src=imread("lena.jpg");  
	cvtColor( src, gray, CV_BGR2GRAY );  
	blur( gray, bluriamge, Size(3,3) );  
	imshow("threshold二值化灰图",src);
	namedWindow("threshold二值化灰图");
	createTrackbar("阈值:","threshold二值化灰图",&thresh,255,on_thresh);
	createTrackbar("type:","threshold二值化灰图",&thresh1,4,on_thresh);
	on_thresh(0,0);
	waitKey(0);
	return 0;
}</span>
                                                                  
(2)adaptiveThreshold
<span style="font-size:18px;">#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#include <iostream>

int main(int argc, char** argv)
{
 cv::Mat image = cv::imread("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
 if (image.empty())
 {
  std::cout<<"read image failure"<<std::endl;
  return -1;
 }

 int th = 100; 
 cv::Mat global;
 cv::threshold(image, global, th, 255, CV_THRESH_BINARY_INV);

 int blockSize = 25;
 int constValue = 10;
 cv::Mat local;
 cv::adaptiveThreshold(image, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);

 cv::imshow("globalThreshold", global);
 cv::imshow("localThreshold", local);
 cv::waitKey(0);

 return 0;
}</span>


(3)OSTU关于他是什么回事,想看理论的可以到我以前的写一篇文章中,很清晰明了 http://blog.youkuaiyun.com/qq_20823641/article/details/51480651
<span style="font-size:18px;">#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#include <iostream>
int piexlSum;
int thresh;  
float w1,u1,w2,u2,g,gmax;
  
int main(int argc, uchar* argv[])  
{  
    vector<int> hist(256);  
    Mat img=imread("lena.jpg",0);  
    Mat dst1;  
 
    for(auto it=img.begin<uchar>();it!=img.end<uchar>();++it)  
        hist[*it]++;  
      
    piexlSum=img.cols*img.rows;  
      
    for(int i=0;i!=hist.size();i++)       
    {  
        w1=w2=u1=u2=0;  
  
        for(int j=0;j!=hist.size();j++)  
        {  
            float k=(float)hist[j]/piexlSum;  
  
            if(j<=i)  
            {  
                w1+=k;    
                u1+=j*k     ;    
                  
            }  
            else       
            {  
                w2+=k;  
                u2+=j*k;  
            }  
        }  
              
            g=w1*w2*(u1-u2)*(u1-u2);  
            if(g>gmax)  
            {  
                gmax=g;  
                thresh=i;  
            }  
                     
    }  
  
    threshold(img,dst1,thresh,255,CV_THRESH_OTSU); 
    imshow("otsu1",dst1);  
    waitKey(0);  
    return 0;  
}  </span>

三、Matlab辅助
I=imread('d:\lena.jpg');
I=rgb2gray(I);
figure
subplot(1,2,1)
imshow(I);
title('原图')
[width,height]=size(I);
level=graythresh(I);
BW=im2bw(I,level);
subplot(1,2,2)
imshow(BW);
title('otsu算法阈值分割效果图');


图像识别算法交流 QQ群:145076161,欢迎图像识别与图像算法,共同学习与交流

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值