图像阈值化:
在对图像进行操作时,希望能对一些低于和高于一定值的像素进行操作。
opencv的cvThreshold()可以完成某些任务。
double cvThreshold( CvArr* src, CvArr* dst, double threshold, //T double max_value, //M int threshold_type );
//只能处理8位或浮点灰度图像
threshold_type包括一些类型选项
CV_THRESH_BINARY (src>T)?M:0
CV_THRESH_BINARY_INV (src>T)?0:M
CV_THRESH_TRUNC (src>T)?M:src
CV_THRESH_TOZERO_INV (src>T)?0:src
CV_THRESH_TOZERO (src>T)?src:0
实例程序:
#include <stdio.h> #include "cv.h" #include "highgui.h" void sum_rgb(IplImage* src , IplImage* dst) { IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); //Split image onto color planes cvSplit(src,r,g,b,NULL); IplImage* s = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); //s = 1/3 * r + 1/3 * g + 0.0 cvAddWeighted(r , 1./3. , g , 1./3. , 0.0 ,s); //s = 2/3 * s + 1/3 * b + 0.0 cvAddWeighted(s , 2./3. , b , 1./3. , 0.0 ,s); cvThreshold( s , dst, 100 , 100 , CV_THRESH_TRUNC); cvReleaseImage(&r); cvReleaseImage(&g); cvReleaseImage(&b); cvReleaseImage(&s); } int main(int argc , char** argv) { cvNamedWindow("源图像",1); cvNamedWindow("操作后的图像",1); IplImage* src = cvLoadImage(argv[1]); IplImage* dst = cvCreateImage(cvGetSize(src),src->depth); sum_rgb(src,dst); cvShowImage( "源图像" , src); cvShowImage("操作后的图像",dst); while(1) { if((cvWaitKey(10)&0x7f) == 27 ) break; } cvDestoryWindow("源图像"); cvDestroyWindow("操作后的图像"); cvReleaseImage(&src); cvReleaseImage(&dst); }
opencv提供了另一种方法进行自适应阈值,在这种方法中,阈值本身是一个变量。
方法由
cvAdaptiveThreshold( 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 param = 5 );
这种自适应阈值方法,可以是在像素点周围block_size * block_size区域的加权平均,减去一个param常数实现。
adaptive_method定义了两种不同的加权方法,CV_ADAPTIVE_THRESH_MEAN_C对区域的所有像素平均加权,
CV_ADAPTIVE_THRESH_GAUSSIAN_C对周围像素根据高斯函数按照他们离中心点的距离进行加权平均计算,
此函数同样只能处理单通道8位或浮点图像,不支持in place操作
#include "cv.h" #include "highgui.h" IplImage *src = 0 , *dst = 0; int main(int argc , char** argv) { int threshold_type = CV_THRESH_BINARY; int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C; int block_size = 71;//block_size%2==1&&block_size>1 double offset = 5; cvNamedWindow("源图像",1); cvNamedWindow("阈值化后的图像",1); src = cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE); if(src == 0) return -1; dst = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); cvAdaptiveThreshold(src , dst , 200 , adaptive_method , threshold_type, block_size , offset); cvShowImage("源图像",src); cvShowImage("阈值化后的图像",dst); while(1) { if((cvWaitKey(10)&0x7f) == 27 ) break; } cvReleaseImage(&src); cvReleaseImage(&dst); cvDestroyWindow("源图像"); cvDestroYWindow("阈值化后的图像"); return 0; }