OpenCV学习笔记-阈值化

转载 2012年03月30日 20:41:29
需要的几个函数:

Threshold

對數組元素進行固定閾值操作

void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type );
src
原始數組 (單通道 , 8-bit of 32-bit 浮點數).
dst
輸出數組,必須與 src 的類型一致,或者為 8-bit.
threshold
閾值
max_value
使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值.
threshold_type
閾值類型 (見討論)

函數 cvThreshold 對單通道數組應用固定閾值操作。該函數的典型應用是對灰度圖像進行閾值操作得到二值圖像。(cvCmpS 也可以達到此目的) 或者是去掉噪聲,例如過濾很小或很大象素值的圖像點。本函數支持的對圖像取閾值的方法由 threshold_type 確定:

threshold_type=CV_THRESH_BINARY: dst(x,y) = max_value, if src(x,y)>threshold 0, otherwise threshold_type=CV_THRESH_BINARY_INV: dst(x,y) = 0, if src(x,y)>threshold max_value, otherwise threshold_type=CV_THRESH_TRUNC: dst(x,y) = threshold, if src(x,y)>threshold src(x,y), otherwise threshold_type=CV_THRESH_TOZERO: dst(x,y) = src(x,y), if (x,y)>threshold 0, otherwise threshold_type=CV_THRESH_TOZERO_INV: dst(x,y) = 0, if src(x,y)>threshold src(x,y), otherwise

下面是圖形化的閾值描述:



  1. Split  
  2. 分割多通道数组成几个单通道数组或者从数组中提取一个通道  
  3. void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,  
  4.                CvArr* dst2, CvArr* dst3 );  
  5. #define cvCvtPixToPlane cvSplit  
  6. src  
  7. 原数组.  
  8. dst0...dst3  
  9. 目标通道  
  10. 函数 cvSplit 分割多通道数组成分离的单通道数组d。可获得两种操作模式 . 如果原数组有N通道且前N输出数组非NULL, 所有的通道都会被从原数组中提取,如果前N个通道只有一个通道非NULL函数只提取该指定通道,否则会产生一个错误,余下的通道(超过前N个通道的以上的)必须被设置成NULL,对于设置了COI的IplImage 结使用cvCopy 也可以从图像中提取单通道。  


  1. AddWeighted  
  2. 计算两数组的加权值的和  
  3. void  cvAddWeighted( const CvArr* src1, double alpha,  
  4.                      const CvArr* src2, double beta,  
  5.                      double gamma, CvArr* dst );  
  6. src1  
  7. 第一个原数组.  
  8. alpha  
  9. 第一个数组元素的权值  
  10. src2  
  11. 第二个原数组  
  12. beta  
  13. 第二个数组元素的权值  
  14. dst  
  15. 输出数组  
  16. gamma  
  17. 添加的常数项。  
  18. 函数 cvAddWeighted 计算两数组的加权值的和:  
  19. dst(I)=src1(I)*alpha+src2(I)*beta+gamma  
  20. 所有的数组必须有相同的类型相同的大小(或ROI大小)  

具体实现例题为:

  1. #include "StdAfx.h"  
  2. #include <stdio.h>    
  3. #include <cv.h>    
  4. #include <highgui.h>    
  5. #include <cxcore.h>    
  6. void sum_rgb( IplImage* src , IplImage* dst)    
  7. {    
  8.     IplImage* r = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);    
  9.     IplImage* g = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);    
  10.     IplImage* b = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);   
  11.     cvSplit( src, r, g, b,NULL );    
  12.     IplImage* s = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);    
  13.     cvAddWeighted( r, 1./3., g, 1./3., 0.0 , s);    
  14.     cvAddWeighted( s, 2./3., b, 1./3., 0.0 , s);    
  15.     cvThreshold( s, dst, 100, 100, CV_THRESH_TRUNC );    
  16.     cvReleaseImage( &r );    
  17.     cvReleaseImage( &g );    
  18.     cvReleaseImage( &b );    
  19.     cvReleaseImage( &s );    
  20. }    
  21. void main()    
  22. {    
  23.     cvNamedWindow( "src", 1 );    
  24.     cvNamedWindow( "cvThreshold", 1 );    
  25.     IplImage* src = cvLoadImage("lena.png");    
  26.     IplImage* dst = cvCreateImage(cvGetSize( src ), src->depth, 1);    
  27.     sum_rgb( src, dst );    
  28.     cvShowImage( "src", src );    
  29.     cvShowImage( "cvThreshold", dst );    
  30.     while( 1 )    
  31.     {    
  32.         if( cvWaitKey( 10 ) ==27 )    
  33.             break;    
  34.     }    
  35.     cvDestroyWindow( "cvThreshold" );    
  36.     cvReleaseImage( &src );    
  37.     cvReleaseImage( &dst );    
  38.   
  39. }    

运算结果为:


另外一种实现方式为,该种实现方式目标图像与原图像一致,再次采用cvConvertScale实现,

  1. ConvertScale  
  2. 使用线性变换转换数组  
  3. void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );  
  4. #define cvCvtScale cvConvertScale  
  5. #define cvScale  cvConvertScale  
  6. #define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )  
  7. src  
  8. 输入数组.  
  9. dst  
  10. 输出数组  
  11. scale  
  12. 比例因子.  
  13. shift  
  14. 该加数被加到输入数组元素按比例缩放后得到的元素上  
  15. 函数 cvConvertScale 有多个不同的目的因此就有多个同义函数(如上面的#define所示)。 该函数首先对输入数组的元素进行比例缩放,然后将shift加到比例缩放后得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最后可选的类型转换将结果拷贝到输出数组。  
  16. 多通道的数组对各个通道是独立处理的。  
  17. 类型转换主要用舍入和溢出截断来完成。也就是如果缩放+转换后的结果值不能用输出数组元素类型值精确表达,就设置成在输出数组数据轴上最接近该数的值。  
  18. 如果 scale=1, shift=0 就不会进行比例缩放. 这是一个特殊的优化,相当于该函数的同义函数名:cvConvert 。如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该函数的同义函数名:cvScale。  

还需要用到cvAcc函数,为

  1. Acc  
  2. 将帧叠加到累积器(accumulator)中  
  3. void cvAcc( const CvArr* image, CvArr* sum, const CvArr* mask=NULL );  
  4. image  
  5. 输入图像, 1- 或 3-通道, 8-比特或32-比特浮点数. (多通道的每一个通道都单独处理).  
  6. sum  
  7. 同一个输入图像通道的累积,32-比特或64-比特浮点数数组.  
  8. mask  
  9. 可选的运算 mask.  
  10. 函数 cvAcc 将整个图像 image 或某个选择区域叠加到 sum 中:  


具体实现代码:

  1. #include "StdAfx.h"  
  2. #include <stdio.h>    
  3. #include <cv.h>    
  4. #include <highgui.h>    
  5. #include <cxcore.h>    
  6. void sum_rgb( IplImage* src , IplImage* dst)    
  7. {    
  8.     IplImage* r = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);    
  9.     IplImage* g = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);    
  10.     IplImage* b = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1);   
  11.     cvSplit( src, r, g, b,NULL );    
  12.     IplImage* s = cvCreateImage( cvGetSize(src) , IPL_DEPTH_32F , 1);    
  13.     cvZero(s);  
  14.     cvAcc(b,s);  
  15.     cvAcc(g,s);  
  16.     cvAcc(r,s);  
  17.     cvThreshold(s,s,100,100,CV_THRESH_TRUNC);  
  18.     cvConvertScale(s,dst,1,0);  
  19.     cvReleaseImage( &r );    
  20.     cvReleaseImage( &g );    
  21.     cvReleaseImage( &b );    
  22.     cvReleaseImage( &s );    
  23. }    
  24. void main()    
  25. {    
  26.     cvNamedWindow( "src", 1 );    
  27.     cvNamedWindow( "cvThreshold", 1 );    
  28.     IplImage* src = cvLoadImage("lena.png");    
  29.     IplImage* dst = cvCreateImage(cvGetSize( src ), IPL_DEPTH_32F, 1);    
  30.     sum_rgb( src, dst );    
  31.     cvShowImage( "src", src );    
  32.     cvShowImage( "cvThreshold", dst );    
  33.     while( 1 )    
  34.     {    
  35.         if( cvWaitKey( 10 ) ==27 )    
  36.             break;    
  37.     }    
  38.     cvDestroyWindow( "cvThreshold" );    
  39.     cvReleaseImage( &src );    
  40.     cvReleaseImage( &dst );    
  41. }    

该运算结果有问题,显示结果为白色,还没找到原因。

如图,

参考文献:

1.学习OpenCV,于仕祺,刘瑞祯,清华大学出版社,pp.155-159

2.http://www.opencv.org.cn/index.php/Cxcore%E6%95%B0%E7%BB%84%E6%93%8D%E4%BD%9C

3.http://www.opencv.org.cn/index.php/Cv%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86#Threshold

4.http://blog.csdn.net/cartoonface/article/details/5998827

OpenCV图像的阈值化

图像阈值化的基本思想是,给定一个数组和一个阈值,然后根据数组中每个元素是低于还是高于阈值而进行一些处理。cvThreshold()函数如下:double cvThreshold(CvArr* src,...
  • Augusdi
  • Augusdi
  • 2013年09月10日 14:24
  • 5494

利用OpenCV的threshold函数实现双阈值法二值化操作的源码!

利用OpenCV的threshold函数实现双阈值法二值化操作的源码!
  • wenhao_ir
  • wenhao_ir
  • 2016年06月02日 14:23
  • 2863

Opencv3.0--第二篇【双阈值二值化图像】

数字图像处理最主要的就是对像素进行操作,然而Opencv提供了14中像素的操作方法,但是处理速度有所不一样,常用的可以用指针进行访问,本文采用的也是用指针进行访问,其次可以采用vector容器指针的方...
  • att0206
  • att0206
  • 2017年03月26日 16:30
  • 1625

OpenCV自适应阈值

int main(int argc, char** argv) { Mat image = imread("E:/VS2013/face/xuelian/png/1.png", CV_LOAD_IM...
  • fabulousli
  • fabulousli
  • 2016年05月24日 09:58
  • 5565

openCV—Python(10)—— 图像阈值化处理

一、函数简介1、threshold—图像简单阈值化处理函数原型:threshold(src, thresh, maxval, type, dst=None)src:图像矩阵thresh:阈值maxVa...
  • jnulzl
  • jnulzl
  • 2015年08月18日 16:05
  • 3642

OpenCV基于局部自适应阈值的图像二值化

opencv局部自适应阈值 二值化
  • l740450789
  • l740450789
  • 2015年08月05日 12:10
  • 1720

OpenCV自适应阈值化函数adaptiveThreshold详解,并附实例源码!

图像阈值化的一般目的是从灰度图像中分享目标区域和背景区域,然而仅仅通过设定固定阈值(固定阈值的求解可点此查看我写的博文)很难达到理想的分割效果。在实际应用中,我们可以通过某个像素的邻域以某种方法确定这...
  • wenhao_ir
  • wenhao_ir
  • 2016年06月02日 12:57
  • 11469

Opencv实现图像的灰度处理,二值化,阀值选择

前几天接触了图像的处理,发现用OPencv处理确实比较方便,毕竟是很多东西都封装好的,但是要研究里面的东西,还是比较麻烦的,首先,你得知道图片处理的一些知识,比如腐蚀,膨胀,仿射,透射等,还有很多算法...
  • honululu
  • honululu
  • 2014年10月29日 09:25
  • 3306

OpenCV学习之阈值化

OpenCV中图像阈值处理有两个函数,cvThreshold和cvAdaptiveThreshold。图像处理中可能最重要的一步就是图像的二值化处理,既然需要将图像二之化,那么就不得不使用这两个函数。...
  • u012535146
  • u012535146
  • 2013年12月02日 17:15
  • 684

Opencv2教程一:图像变换之阈值二值threshold

网名:无名   QQ:16349023 email:mengwzy@qq.com 以前很少写教程,写的可能有点乱希望大对家有帮助 threshold 方法是通过遍历灰度图中点,将图像信息二值化,处理过...
  • nnsword
  • nnsword
  • 2014年06月18日 12:00
  • 15985
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenCV学习笔记-阈值化
举报原因:
原因补充:

(最多只允许输入30个字)