0
点赞
收藏
分享

微信扫一扫

Opencv-C++笔记 (11) : opencv-图像二值化与LUB查找表

云卷云舒xj 2023-06-24 阅读 97

文章目录

一、概述

double cv::threshold(InputArray src,OutputArray dst,double  thresh,double  maxval,int  type)
  • src:待二值化的图像,图像只能是CV_8U和CV_32F两种数据类型。对于图像通道数目的要求和选择的二值化方法相关。
  • dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型和通道数。
  • thresh:二值化的阈值。
  • maxval:二值化过程的最大值,此函数只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用,但是在使用其他方法是也需要输入。
  • type:选择图像二值化方法的标志。

接下来将详细的介绍每种标志对应的二值化原理和需要的参数。

二、THRESH_BINARY和THRESH_BINARY_INV

这两个标志是相反的二值化方法,THRESH_BINARY是将灰度值与阈值(第三个参数thresh)进行比较,如果灰度值大于阈值就将灰度值改为函数中第四个参数maxval的值,否则将灰度值改成0。THRESH_BINARY_INV标志正好与这个过程相反,如果灰度值大于阈值就将灰度值改为0,否则将灰度值改为maxval的值。这两种标志的计算公式在式(3.7)中给出。
在这里插入图片描述

三、THRESH_TRUNC

在这里插入图片描述

四、THRESH_TOZERO和THRESH_TOZERO_INV

这两个标志是相反的阈值比较方法, THRESH_TOZERO表示将灰度值与阈值thresh进行比较,如果灰度值大于thresh则将保持不变,否则将灰度值改为0。THRESH_TOZERO_INV方法与其相反,将灰度值与阈值thresh进行比较,如果灰度值小于等于thresh则将保持不变,否则将灰度值改为0。这种两种方法都没有使用到函数中的第四个参数maxval的值,因此maxval的值对本方法不产生影响。这两个标志的计算公式在式(3.9)中给出。
在这里插入图片描述
前面五种标志都支持输入多通道的图像,在计算时分别对每个通道进行阈值比较。为了更加直观的理解上述阈值比较方法,我们假设图像灰度值是连续变化的信号,将阈值比较方法比做滤波器,绘制连续信号通过滤波器后的信号形状,结果如图3-14所示,图中红线为设置的阈值,黑线为原始信号通过滤波器后的信号形状。
在这里插入图片描述

五、THRESH_OTSU和THRESH_TRIANGLE

void cv::adaptiveThreshold(InputArray src,
                                 OutputArray dst,
                                double  maxValue,
                                int  adaptiveMethod,
                                 int  thresholdType,
                                 int  blockSize,
                                double   C
                                  )
  • src:待二值化的图像,图像只能是CV_8UC1数据类型。
  • dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型。
  • maxValue:二值化的最大值。
  • adaptiveMethod:自制应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C这两种。
  • thresholdType:选择图像二值化方法的标志,只能是THRESH_BINARY和THRESH_BINARY_INV。
  • blockSize:自适应确定阈值的像素邻域大小,一般为3,5,7的奇数。 C:从平均值或者加权平均值中减去的常数,可以为正,也可以为负。

该函数将灰度图像转换成二值图像,通过均值法和高斯法自适应的计算blockSize* blockSize邻域内的阈值,之后进行二值化,其原理与前面的相同,这里就不再赘述。

为了直观的体会到图像二值化的效果,在代码清单3-19中给出了分别对彩色图像和灰度图像进行二值化的示例程序

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    Mat img=imread("699342568.jpg");
    if(img.empty()){
        cout<<"请确认输入的图片的路径是否正确"<<endl;
        return -1;
    }

    Mat gray;
    cvtColor(img,gray,COLOR_BGR2GRAY);
    Mat img_B,img_B_V,gray_B,gray_B_V,gray_T,gray_T_V,gray_TRUNC;

    //彩色图像二值化
    threshold(img,img_B,125,255,THRESH_BINARY);
    threshold(img,img_B_V,125,255,THRESH_BINARY_INV);
    imshow("img_B",img_B);
    imshow("img_B_V",img_B_V);

    //灰度图像二值化
    threshold(gray,gray_B,125,255,THRESH_BINARY);
    threshold(gray,gray_B_V,125,255,THRESH_BINARY_INV);
    imshow("gray_B",gray_B);
    imshow("gray_B_V",gray_B_V);

    //灰度图像TOZERO变换
    threshold(gray,gray_T,125,255,THRESH_TOZERO);
    threshold(gray,gray_T_V,125,255,THRESH_TOZERO_INV);
    imshow("gray_T",gray_T);
    imshow("gray_T_V",gray_T_V);

    //灰度图像TRUNC变换
    threshold(gray,gray_TRUNC,125,255,THRESH_TRUNC);
    imshow("gray_TRUNC",gray_TRUNC);

    //灰度图像大津法和三角法二值化
    Mat img_Thr=imread("threshold.jpg",IMREAD_GRAYSCALE);
    Mat img_Thr_0,img_Thr_T;
    threshold(img_Thr,img_Thr_0,100,255,THRESH_BINARY|THRESH_OTSU);
    threshold(img_Thr,img_Thr_T,125,255,THRESH_BINARY|THRESH_TRIANGLE);
    imshow("img_Thr",img_Thr);
    imshow("img_Thr_0",img_Thr_0);
    imshow("img_Thr_T",img_Thr_T);

    //灰度图像自适应二值化
    Mat adaptive_mean,adaptive_gauss;
    adaptiveThreshold(img_Thr,adaptive_mean,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,55,0);
    adaptiveThreshold(img_Thr,adaptive_gauss,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,55,0);

    imshow("adaptive_mean",adaptive_mean);
    imshow("adaptive_gauss",adaptive_gauss);
    waitKey(0);
    return 0;
}

在这里插入图片描述

六、LUT查找表

 void cv::LUT(InputArray src,
                   InputArray lut,
                   OutputArray dst
                  )
  • src:输入图像矩阵,其数据类型只能是CV_8U。

  • lut:256个像素灰度值的查找表,单通道或者与src通道数相同。

-dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同。

为了体会LUT查找表处理图像后的效果,在代码清单3-21中给出通过LUT()函数将灰度图像和彩色图像分别处理的示例程序,程序中分别应用单通道和三通道的查找表对彩色图像进行映射

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    //LUT查找表第一层
    uchar lutFirst[256];
    for(int i=0;i<256;++i){
        if(i<=100)lutFirst[i]=0;
        else if(i>100&&i<=200)lutFirst[i]=100;
        else lutFirst[i]=255;
    }
    Mat lutOne(1,256,CV_8UC1,lutFirst);

    //LUT查找表第二层
    uchar lutSecond[256];
    for(int i=0;i<256;++i){
        if(i<=100)lutSecond[i]=0;
        else if(i>100&&i<=150)lutSecond[i]=100;
        else if(i>150&&i<=200)lutSecond[i]=150;
        else lutSecond[i]=255;
    }
    Mat lutTwo(1,256,CV_8UC1,lutSecond);

    //LUT查找表第三层
    uchar lutThird[256];
    for(int i=0;i<256;++i){
        if(i<=100)lutThird[i]=0;
        else if(i>100&&i<=200)lutThird[i]=100;
        else lutThird[i]=255;
    }
    Mat lutThree(1,256,CV_8UC1,lutThird);

    //拥有三通道的LUT查找表矩阵
    vector<Mat>mergeMats;
    mergeMats.push_back(lutOne);
    mergeMats.push_back(lutTwo);
    mergeMats.push_back(lutThree);
    Mat LutTree;
    merge(mergeMats,LutTree);

    //计算图像的查找表
    Mat img=imread("lena.jpeg");
    if(img.empty()){
        cout<<"请确认输入的图片路径是否正确"<<endl;
        return -1;
    }
    Mat gray,out0,out1,out2;
    cvtColor(img,gray,COLOR_BGR2GRAY);
    LUT(gray,lutOne,out0);
    LUT(img,lutOne,out1);
    LUT(img,LutTree,out2);
    imshow("out0",out0);
    imshow("out1",out1);
    imshow("out2",out2);
    waitKey(0);
    return 0;
}

在这里插入图片描述

举报

相关推荐

0 条评论