基于OpenCV的图像阈值分割研究与实现

时间:2022-03-21 02:57:42

基于OpenCV的图像阈值分割研究与实现

摘 要: 图像的阈值化在图像分割中有着至关重要的作用。在OpenCV 算法环境下,运用固定阈值化和自适应阈值化算法,分别对同一幅图调用OpenCV 中相应的函数进行处理;同时针对图像中的噪声,结合高斯模糊算法对图像噪声的滤除作用,将高斯模糊和阈值化算法结合起来,分析研究图像分割算法。结果表明自适应阈值化算法可以更有效地进行图像分割。

关键字: OpenCV; 自适应阈值; 图像分割; 固定阈值

中图分类号: TN919?34; TP32 文献标识码: A 文章编号: 1004?373X(2013)24?0073?04

Research and implementation of image threshold segmentation based on OpenCV

LEI Jian?feng, WANG Wei

(Capital Medical University, Beijing 100069, China)

Abstract:The image threshold plays a very important role in image segmentation. In the OpenCV algorithm environment, the fixed threshold algorithm and adaptive threshold algorithm are emploied respectively to process the same image by calling the corresponding function in OpenCV. The noise in the image is eliminated in combination with the filtering function of Gauss fuzzy algorithm. The image segmentation algorithm was analyzed by means of Gauss fuzzy and thresholding algorithm. The results show that the adaptive threshold algorithm can perform image segmentation more efficiently.

Keyword: OpenCV; adaptive threshold; image segmentation; fixed threshold

1 OpenCV简介

OpenCV是一种开源的软件,采用基于C/C++语言编写,OpenCV可以在多种操作系统上运行同时为其他软件提供了多种接口。在数据类型上OpenCV提供了多种基本数据类型。虽然这些数据类型在C语言中不是基本类型,但结构都很简单,可将它们作为原子类型。OpenCV 主体分为5个模块,其中4个模块如图1所示。

图1 OpenCV基本结构图

OpenCV的目标是为计算机视觉提供基本工具,在处理计算机视觉中一些很复杂的问题时,可以利用OpenCV提供的高层函数有效地解决这些问题。OpenCV有一个强大的函数库,它可以提供基本函数为大多数计算机视觉问题创建一个完整解决方案。

2 图像分割

图像分割[1]是图像分析中很重要的基础环节,只有准确地将对象从图像中提取出来,才能进一步对该对象做定量的描绘。图像分割又是比较困难的环节,因为在许多情况下,对象与背景之间很难区分。所以图像分割算法已经成为图像处理[2]和分析领域中研究的热点,并且到目前为止没有一种通用的分割算法对各种图像均能得到满意的分割结果。图像分割的准则实质是将一幅图像分成几幅子图像,并且满足3个条件:

(1)图像中的每一个像素必须被归入某一子图像,并只能属于一个子图像;

(2)属于同一子图像的像素在某种性质上是相近的;

(3)属于不同子图像的像素在该性质上相差很大。所谓性质指的是如灰度、灰度梯度、纹理以及空间位置等。因此,图像分割的过程也就是按性质对像素进行分类和识别。

图像分割[3]方法一般有2类:

(1)基于边界分割方法,这种方法通过子图像之间一般都有明显的边界。假设图像中只有2个子图像,子图像不存在多个互不连通的区域;

(2)基于阈值方法,这种方法首先根据像素的某个特征确定分割阈值,然后将像素的这个特征值与此分割阈值相比较,并以此决定将该像素归入哪一类子图像。通常将像素的灰度作为特征来选择阈值。

2.1 VC6.0下OpenCV的安装及环境搭配

(1)下载OpenCV安装程序(1.0版本)。假如要将OpenCV安装到C:\Program Files\OpenCV。在安装时选择“将\OpenCV\bin加入系统变量”。或安装完成后手动添加环境变量“C:\Program Files\OpenCV\bin”。

(2)启动VC++ 6.0,菜单Tools?>Options?>Directories:先设置lib路径,选择Library files,在下方填入路径: C:\Program Files\OpenCV\lib然后选择include files,在下方填入路径:

C:\Program Files\OpenCV\cxcore\include

C:\Program Files\OpenCV\cv\include

C:\Program Files\OpenCV\cvaux\include

C:\Program Files\OpenCV\ml\include

C:\Program Files\OpenCV\otherlibs\highgui

C:\Program Files\OpenCV\otherlibs\cvcam\include

(3)每创建一个将要使用OpenCV的VC Project,都需要给它指定需要的lib。菜单:Project?>Settings,然后将Setting for选为All Configurations,然后选择右边的link标签,在Object/library modules附加上:cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib如果不需要这么多lib,你可以只添加你需要的lib。

2.2 利用OpenCV进行图像阈值分割

阈值分割是传统的图像分割方法,因其实现简单,性能较稳定而成为图像分割中最基本和应用最广泛的分割技术[4]。它适用于目标和背景有不同灰度级范围的图像,而且总可以得到封闭且连通区域的边界。

2.2.1 阈值分割的概念

阈值分割法是一种基于区域的图像分割技术,其基本原理是:通过设定不同的特征阈值,把图像象素点分为若干类[5]。通常将像素的灰度作为特征来选择阈值。首先设原始图像为f(x,y),然后按照一定的准则f(x,y)中找到特征值T,将图像分割为2个部分,分割后的图像为: 若取b0=0(黑),b1=1(白),即为图像二值化。该方法的特点是可以减少数据量,而且简化了分析和处理步骤,因此该方法是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。图像阈值化的目的是要按照灰度级,对像素集合进行一个划分,使每个子集形成一个与现实景物相对应的区域,各个区域内部具有一致的属性,而相邻区域具有不同的属性。这样的划分可以通过从灰度级出发选取一个或多个阈值来实现。

2.2.2 OpenCV实现阈值分割方法

OpenCV实现阈值分割方法[6]:

(1)固定阈值分割,在OpenCV中实现固定阈值分割的函数是cvThreshold(),函数 cvThreshold()对单通道数组应用固定阈值操作。其基本的思想是,给定一个数组和一个阈值,然后根据数组中的每个元素的是低于还是高于阈值而进行一些处理。

(2)自适应阈值分割,在OpenCV中实现自适应阈值分割的函数AdaptiveThreshold(),此函数有2种不同的自适应阈值方法。

2.2.3 基于MFC的OpenCV阈值分割的实现

OpenCV 库是使用“IplImage”结构体来创建和处理图像,在其库函数中,最重要的结构体就是IplImage 结构,使用这种格式的特点是:可以比DIB 格式表示更多的图像性质,而且可以更方便地存取图像中的像素值[7]。定义该结构体变量时,需要用到函数cvCreateImage,定义方法如下:

IplImage *src=cvCreateImage(cvSize(800,600),IPL_DEPTH_16U,3);

在VC6.0 中新建MFC AppWizard(exe),添加支持OpenCV 的库文件,如cxcore.lib cv.libml.lib cvaux.lib highgui.lib cvcam.lib 等,使得VC能够调用OpenCV 的库函数。

(1)固定阈值算法

OpenCV 中使用固定阈值对图像进行二值化的函数是cvThreshold(),函数具体定义为:

Double cvThreshold(

CvArr* src,

CvArr* dst,

double threshold,

double max_value,

int threshold_type);

该函数的特点是只能处理8位或浮点灰度图像。目标图像必须与源图像的类型一致。每个阈值类型threshold_type对应于一个特定的比较操作如表1所示,该比较操作在源图像第i个像素(srci)和阈值(T)之间进行。根据源图像的像素和阈值之间的关系,目标图像的像素dsti 会被设置为0, srci 或者max_value。当threshold_type 被设置为CV_THRESH_BINARY 时,如果源图像第i 个像素(srci)大于阈值T,则目标像素dsti 被设置为最大值max_value。否则目标像素dsti 被设置为0[8]。

表1 cvThreshold()中阈值类型选项和对应的操作

以下是本文测试基于MFC的OpenCV高斯模糊算法部分核心代码:

//定义IplImage 结构体存放高斯模糊后的目标图片

IplImage* pImg8uSmooth= NULL;

IplImage* pImg8u= NULL;

//建立3 通道图像,图像大小与输入图像的大小相同的IplImage 结构体

pImg8uSmooth = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U, 3);

//使用高斯模糊方法对输入图像进行滤波

cvSmooth( img, pImg8uSmooth,CV_GAUSSIAN,3,0,0);

//创建窗口,显示高斯模糊后的图像

cvvNamedWindow( "Smooth Image", 1 );

cvvShowImage( "Smooth Image", pImg8uSmooth);

以下是基于MFC 的OpenCV 固定阈值化算法部分核心代码:

//建立IplImage 结构体存放图片

IplImage* Thresholdimg=NULL;

//设定固定阈值为15(该值为参考值,实际测试程序时,可以根据具体程序设置为其他测试值)

double threshold = 15;

//设定阈值类型为CV_THRESH_BINARY

int threshold_type = CV_THRESH_BINARY;

//对上一步中进行过高斯模糊的图像进行固定阈值化处理

cvCvtColor(pImg8uSmooth, Thresholdimg, CV_BGR2GRAY);

//固定阈值化处理

cvThreshold(Thresholdimg,It,threshold,255,threshold_type);

(2)自适应阈值算法

针对有很强照明和反射梯度的图像,图像中像素分布很不均匀,要想对图像处理得到效果较好的二值化效果,很难通过某一个或者某几个固定的阈值来实现。在这种情况下,需要根据梯度进行阈值化,于是便有了自适应阈值算法[9]。

自适应阈值算法是OpenCV 中的一种改进了的阈值化处理技术,使用的阈值本身就是一个变量,这种方法由函数cvAdaptiveThreshold()实现,其具体函数为:

Void cvAdaptiveThreshold(

CvArr* src,

CvArr* dst,

double max_val,

Int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,

Int threshold_type=CV_THRESH_BINARY,

Int block_size=3,

Double param1=5);

cvAdaptiveThreshold()有两种不同的自适应阈值方法,可以用参数adaptive_method进行设置。在这两种方法下,自适应阈值T(x,y)在每个像素点都不同。通过计算像素点周围b×b区域加权平均,然后减去常数得到自适应阈值,b由参数block_size 指定,常参数由param1 指定。当adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C 时,对区域所有像素平均加权;当adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C时,区域中的(x,y)周围像素根据高斯函数按照它们离中心的距离进行加权计算。最后参数threshold_type和表1中的一样。

本方法对于有很强照明或反射梯度的图像,需要根据梯度进行阈值化时,自适应阈值技术与其他技术相比就有很好的效果。本文是在adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C时使用高斯模糊算法对输入图像进行去噪滤波,之后用cvAdaptiveThreshold ()函数对高斯滤波之后的图像进行自适应阈值化处理。具体核心代码如下:

//定义IplImage 结构体存放自适应阈值化后的目标图片

IplImage* AdpThresholdimg=NULL;

//设定阈值类型为CV_THRESH_BINARY

int threshold_type = CV_THRESH_BINARY;

//设定自适应阈值方法为CV_ADAPTIVE_THRESH_MEAN_C 方法

int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C;

int block_size = 71;

//设置减去的常数值,以得到自适应阈值

double offset = 15;

//建立Iat 指针存放自适应阈值化处理后的图像结构体,作为输出图像

Iat = cvCreateImage(cvSize(Igray?>width,Igray?>height),IPL_DEPTH_8U, 1);

// AdpThresholdimg 存放经过高斯模糊处理的图像结构体,作为输入图像

AdpThresholdimg=cvCreateImage(cvGetSize(img),IPL_

DEPTH_8U, 1);

//进行自适应阈值化处理,

cvAdaptiveThreshold(AdpThresholdimg, Iat, 255, adaptive_method,

threshold_type, block_size, offset);

//创建窗口,显示自适应阈值处理后的图像

cvNamedWindow("Adaptive Threshold",1);

cvShowImage("Adaptive Threshold",Iat);

经过上述两种算法处理的图像如图2~图4所示。

图2 原始图

图3 固定阈值分割

图4 自适应阈值分割

3 结 语

本文介绍了基于OpenCV 的图像处理并给出了实例,利用OpenCV 中的函数使图像处理[10]问题变得很简单,具有很强的实用价值,通过图2和图3的图像处理后的效果,发现自适应阈值相较于固定阈值有着较好的特征提取效果。当使用固定阈值时,无法分割出图像中需要的信息,而使用自适应阈值,可以有效地分割出图像中的有用信息。

注:本文通讯作者为汪伟。

参考文献

[1] 韩思奇,王蕾.图像分割的阈值法综述[J].系统工程与电子技术,24(6):91?94.

[2] 陈胜勇,刘盛.基于OpenCV 的计算机视觉技术实现[M].北京:科学出版社,2008.

[3] 黄春艳.图像分割若干算法研究[D].开封:河南大学,2011.

[4] 赵春燕,闰长青,时秀芳.图像分割综述[J].中国科技信息,2009(7):41?43.

[5] 刘爽.图象分割中阈值选取方法的研究及其算法实现[J].电脑知识与技术,2010(11):68?70.

[6] .图像分割算法研究[J].福建电脑,2009(3):27?35.

[7] 高秀娟.图像分割的理论、方法及应用[D].长春:吉林大学,2012.

[8] 刘瑞祯,于仕琪.OpenCV 教程基础篇[M].北京:北京航空航天大学出版社,2009.

[9] 苏彦华.Visual C++数字图像识别技术典型案例[M].北京:人民邮电出版社,2004.

[10] 杨金龙.图像分割算法研究与实现[D].兰州:西北师范大学,2011.

上一篇:基于LabVIEW的智能家居监控系统设计 下一篇:基于双麦克风声源定位的视频跟踪