您的位置:首页 > 运维架构

【OpenCV入门指南】第四篇 图像的二值化

2016-09-26 08:24 435 查看


【OpenCV入门指南】第四篇 图像的二值化

   在上一篇《【OpenCV入门指南】第三篇Canny边缘检测》中介绍了使用Canny算子对图像进行边缘检测。与边缘检测相比,轮廓检测有时能更好的反映图像的内容。而要对图像进行轮廓检测,则必须要先对图像进行二值化,图像的二值化就是将图像上的像素点的灰度值设置为0或255,这样将使整个图像呈现出明显的黑白效果。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

《OpenCV入门指南》系列文章地址:http://blog.csdn.net/u014365862/article/category/5790651


一. 关键函数介绍

下面就介绍OpenCV中对图像进行二值化的关键函数——cvThreshold()。

函数功能:采用Canny方法对图像进行边缘检测

函数原型:

void cvThreshold(

  const CvArr* src,

  CvArr* dst,

  double threshold,

  double max_value,

  int threshold_type

);

函数说明:

第一个参数表示输入图像,必须为单通道灰度图。

第二个参数表示输出的边缘图像,为单通道黑白图。

第三个参数表示阈值

第四个参数表示最大值。

第五个参数表示运算方法。

在OpenCV的imgproc\types_c.h中可以找到运算方法的定义。

/* 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 */

};

注释已经写的很清楚了,因此不再用中文来表达了。

 


二. 示例程序代码

下面给出对图像进行二值化的完整的源代码:

[cpp] view
plain copy

//图像的二值化  

//By MoreWindows (http://blog.csdn.net/MoreWindows)  

#include <opencv2/opencv.hpp>  

using namespace std;  

  

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  

IplImage *g_pGrayImage = NULL;  

IplImage *g_pBinaryImage = NULL;  

const char *pstrWindowsBinaryTitle = "二值图(http://blog.csdn.net/MoreWindows)";  

  

void on_trackbar(int pos)  

{  

    // 转为二值图  

    cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);  

    // 显示二值图  

    cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);  

}  

  

int main( int argc, char** argv )  

{     

    const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";  

    const char *pstrWindowsToolBarName = "二值图阈值";  

  

    // 从文件中加载原图  

    IplImage *pSrcImage = cvLoadImage("002.jpg", CV_LOAD_IMAGE_UNCHANGED);  

  

    // 转为灰度图  

    g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

    cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);  

  

    // 创建二值图  

    g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);  

  

    // 显示原图  

    cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

    cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

    // 创建二值图窗口  

    cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);  

  

    // 滑动条    

    int nThreshold = 0;  

    cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);  

  

    on_trackbar(1);  

  

    cvWaitKey(0);  

  

    cvDestroyWindow(pstrWindowsSrcTitle);  

    cvDestroyWindow(pstrWindowsBinaryTitle);  

    cvReleaseImage(&pSrcImage);  

    cvReleaseImage(&g_pGrayImage);  

    cvReleaseImage(&g_pBinaryImage);  

    return 0;  

}  

运行结果如下所示,读者可以到下载源文件和程序(Release版本,不用安装OpenCV也能使用),自己动手调试下阈值大小,看看生成的二值图有什么变化。



 

OpenCV还有个cvAdaptiveThreshold()函数,这个函数会使用Otsu算法(大律法或最大类间方差法)(注1)来计算出一个全局阈值,然后根据这个阈值进行二值化。当然直接使用上一篇《【OpenCV入门指南】第三篇Canny边缘检测》中的cvCanny()函数也可以对图像进行二值化(想到怎么传参数了吗?)。

 

好了,图像的二值化就介绍到这里了,欢迎继续浏览下面二篇《【OpenCV入门指南】第五篇轮廓检测上》《【OpenCV入门指南】第六篇轮廓检测下》,谢谢。

 

  

 

注1.调用cvThreshold()时传入参数CV_THRESH_OTSU也是使用Otsu算法来自动生成一个阈值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息