对图像进行二值化的关键函数为cvThreshold
,它采用Canny
方法对图像进行边缘检测:
void cvThreshold (
const CvArr *src, CvArr *dst, double threshold,
double max_value, int threshold_type );
参数src
表示输入图像,必须为单通道灰度图;参数dst
表示输出的边缘图像,为单通道黑白图;参数threshold
表示阈值;参数max_value
表示最大值;参数threshold_type
表示运算方法,在OpenCV
的imgproc\types_c.h
中可以找到运算方法的定义:
enum { /* Threshold types */
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,
/* use Otsu algorithm to choose the optimal threshold value;
combine the flag with one of the above CV_THRESH_* values */
CV_THRESH_OTSU = 8
};
代码如下:
#include
IplImage *g_pGrayImage = NULL;
IplImage *g_pBinaryImage = NULL;
const char *pstrWindowsBinaryTitle = "二值图";
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 = "原图";
const char *pstrWindowsToolBarName = "二值图阈值";
IplImage *pSrcImage = cvLoadImage ( "zzjb.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;
}
OpenCV
还有个cvAdaptiveThreshold
函数,这个函数会使用Otsu
算法(大律法或最大类间方差法)来计算出一个全局阈值,然后根据这个阈值进行二值化。