基本思想:给定一个数组和一个阈值,然后根据数组中的每个元素的值是低于还是高于阈值而进行一些处理
/* Applies fixed-level threshold to grayscale image. This is a basic operation applied before retrieving contours */ CVAPI(double) cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type );
阈值类型 |
操作 |
CV_THRESH_BINARY |
dsti=(srci > T)?M:0 |
CV_THRESH_BINARY_INV |
dsti=(srci>T)?0:M |
CV_THRESH_TRUNC |
dsti=(srci>T)?M:srci |
CV_THRESH_TOZERO_INV |
dsti=(srci>T)?0:srci |
CV_THRESH_TOZERO |
dsti=(srci>T)?srci:0 |
2.目标图像必须与源图像的类型一致,或者为8位图像
3.源图像和目标图像可以是同一图像
程序:对图像中三个通道求和,然后在值为100处对结果图像进行截断
#include "threshold.h" //对图像中的三个通道求和,然后在值为100处对结果图像进行截断 void sum_rgb(IplImage *src, IplImage *dst) { //Allocate individual image planes 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 the color plane cvSplit(src, r, g, b, NULL); //Temporary storage IplImage *s=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); //Add equally weighted rgb values cvAddWeighted(r, 1./3., g, 1./3., 0.0, s); cvAddWeighted(s, 2./3., b, 1./3., 0.0, s); //Truncate values above 100. cvThreshold(s, dst, 100, 100, CV_THRESH_TRUNC); cvReleaseImage(&r); cvReleaseImage(&g); cvReleaseImage(&b); cvReleaseImage(&s); } int main(void) { cvNamedWindow("Threshold"); //Load the image from the given file name. IplImage *src=cvLoadImage("lena.jpg"); IplImage *dst=cvCreateImage(cvGetSize(src), src->depth, 1); if (src == NULL || dst == NULL) exit(0); sum_rgb(src, dst); //Show the image in the named window cvShowImage("Threshold", dst); //Idle until the user hits the "Esc" key while (true) if (cvWaitKey(10) == 27) break; //Clean up and don't be piggies cvDestroyWindow("Threshold"); cvReleaseImage(&src); cvReleaseImage(&dst); }
################################################
/* Applies adaptive threshold to grayscale image. The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and CV_ADAPTIVE_THRESH_GAUSSIAN_C are: neighborhood size (3, 5, 7 etc.), and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...) */ CVAPI(void) cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value, int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C), int threshold_type CV_DEFAULT(CV_THRESH_BINARY), int block_size CV_DEFAULT(3), double param1 CV_DEFAULT(5));
cvAdaptiveThreshold()有两种不同的自适应阈值方法,可以用参数adaptive_method进行设置。在两种情况下,自适应阈值T(x, y)在每个像素点都不同。通过计算像素点周围的bxb区域的加权平均,然后减去一个常熟来得到自适应阈值,b由参数block_size指定,常数由param1制定。如果使用CV_ADAPTIVE_THRESH_MEAN_C方法,那么对区域的所有像素平均加权。如果使用了CV_ADAPTIVE_THRESH_GAUSSIAN_C方法,那么区域中的(x, y)周围的像素根据高斯函数按照它们离中心点的距离进行加权计算。
参数threshold_type和cvThreshold()的参数threshold_type是一样的
note:本函数要求源图像和目标图像不能使用同一图像
void adaptiveThre(void) { //比较cvThreshold()函数和cvAdaptiveThreshold函数 IplImage *src, *dst1, *dst2, *dst3; src=cvLoadImage("left04.jpg", CV_LOAD_IMAGE_GRAYSCALE); dst1=cvCreateImage(cvGetSize(src), src->depth, src->nChannels); dst2=cvCreateImage(cvGetSize(src), src->depth, src->nChannels); dst3=cvCreateImage(cvGetSize(src), src->depth, src->nChannels); if (src == NULL || dst1 == NULL || dst2 == NULL || dst3 == NULL) exit(0); cvThreshold(src, dst1, 100, 255, CV_THRESH_BINARY); cvAdaptiveThreshold(src, dst2, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 5); cvAdaptiveThreshold(src, dst3, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 3, 5); cvNamedWindow("src"); cvNamedWindow("dst1"); cvNamedWindow("dst2"); cvNamedWindow("dst3"); cvShowImage("src", src); cvShowImage("dst1", dst1); cvShowImage("dst2", dst2); cvShowImage("dst3", dst3); cvWaitKey(0); cvReleaseImage(&src); cvReleaseImage(&dst1); cvReleaseImage(&dst2); cvReleaseImage(&dst3); cvDestroyAllWindows(); }