OpenCV学习笔记-阈值化
来源:互联网 发布:卓越java招聘信息 编辑:程序博客网 时间:2024/06/05 23:05
需要的几个函数:
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, otherwisethreshold_type=CV_THRESH_BINARY_INV:dst(x,y) = 0, if src(x,y)>threshold max_value, otherwisethreshold_type=CV_THRESH_TRUNC:dst(x,y) = threshold, if src(x,y)>threshold src(x,y), otherwisethreshold_type=CV_THRESH_TOZERO:dst(x,y) = src(x,y), if (x,y)>threshold 0, otherwisethreshold_type=CV_THRESH_TOZERO_INV:dst(x,y) = 0, if src(x,y)>threshold src(x,y), otherwise
下面是圖形化的閾值描述:
Split分割多通道数组成几个单通道数组或者从数组中提取一个通道void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3 );#define cvCvtPixToPlane cvSplitsrc原数组.dst0...dst3目标通道函数 cvSplit 分割多通道数组成分离的单通道数组d。可获得两种操作模式 . 如果原数组有N通道且前N输出数组非NULL, 所有的通道都会被从原数组中提取,如果前N个通道只有一个通道非NULL函数只提取该指定通道,否则会产生一个错误,余下的通道(超过前N个通道的以上的)必须被设置成NULL,对于设置了COI的IplImage 结使用cvCopy 也可以从图像中提取单通道。
AddWeighted计算两数组的加权值的和void cvAddWeighted( const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst );src1第一个原数组.alpha第一个数组元素的权值src2第二个原数组beta第二个数组元素的权值dst输出数组gamma添加的常数项。函数 cvAddWeighted 计算两数组的加权值的和:dst(I)=src1(I)*alpha+src2(I)*beta+gamma所有的数组必须有相同的类型相同的大小(或ROI大小)
具体实现例题为:
#include "StdAfx.h"#include <stdio.h> #include <cv.h> #include <highgui.h> #include <cxcore.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); cvSplit( src, r, g, b,NULL ); IplImage* s = cvCreateImage( cvGetSize(src) , IPL_DEPTH_8U , 1); cvAddWeighted( r, 1./3., g, 1./3., 0.0 , s); 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 ); } void main() { cvNamedWindow( "src", 1 ); cvNamedWindow( "cvThreshold", 1 ); IplImage* src = cvLoadImage("lena.png"); IplImage* dst = cvCreateImage(cvGetSize( src ), src->depth, 1); sum_rgb( src, dst ); cvShowImage( "src", src ); cvShowImage( "cvThreshold", dst ); while( 1 ) { if( cvWaitKey( 10 ) ==27 ) break; } cvDestroyWindow( "cvThreshold" ); cvReleaseImage( &src ); cvReleaseImage( &dst ); }
运算结果为:
另外一种实现方式为,该种实现方式目标图像与原图像一致,再次采用cvConvertScale实现,
ConvertScale使用线性变换转换数组void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );#define cvCvtScale cvConvertScale#define cvScale cvConvertScale#define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 )src输入数组.dst输出数组scale比例因子.shift该加数被加到输入数组元素按比例缩放后得到的元素上函数 cvConvertScale 有多个不同的目的因此就有多个同义函数(如上面的#define所示)。 该函数首先对输入数组的元素进行比例缩放,然后将shift加到比例缩放后得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最后可选的类型转换将结果拷贝到输出数组。多通道的数组对各个通道是独立处理的。类型转换主要用舍入和溢出截断来完成。也就是如果缩放+转换后的结果值不能用输出数组元素类型值精确表达,就设置成在输出数组数据轴上最接近该数的值。如果 scale=1, shift=0 就不会进行比例缩放. 这是一个特殊的优化,相当于该函数的同义函数名:cvConvert 。如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该函数的同义函数名:cvScale。
还需要用到cvAcc函数,为
Acc将帧叠加到累积器(accumulator)中void cvAcc( const CvArr* image, CvArr* sum, const CvArr* mask=NULL );image输入图像, 1- 或 3-通道, 8-比特或32-比特浮点数. (多通道的每一个通道都单独处理).sum同一个输入图像通道的累积,32-比特或64-比特浮点数数组.mask可选的运算 mask.函数 cvAcc 将整个图像 image 或某个选择区域叠加到 sum 中:
具体实现代码:
#include "StdAfx.h"#include <stdio.h> #include <cv.h> #include <highgui.h> #include <cxcore.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); cvSplit( src, r, g, b,NULL ); IplImage* s = cvCreateImage( cvGetSize(src) , IPL_DEPTH_32F , 1); cvZero(s);cvAcc(b,s);cvAcc(g,s);cvAcc(r,s);cvThreshold(s,s,100,100,CV_THRESH_TRUNC);cvConvertScale(s,dst,1,0);cvReleaseImage( &r ); cvReleaseImage( &g ); cvReleaseImage( &b ); cvReleaseImage( &s ); } void main() { cvNamedWindow( "src", 1 ); cvNamedWindow( "cvThreshold", 1 ); IplImage* src = cvLoadImage("lena.png"); IplImage* dst = cvCreateImage(cvGetSize( src ), IPL_DEPTH_32F, 1); sum_rgb( src, dst ); cvShowImage( "src", src ); cvShowImage( "cvThreshold", dst ); while( 1 ) { if( cvWaitKey( 10 ) ==27 ) break; } cvDestroyWindow( "cvThreshold" ); cvReleaseImage( &src ); cvReleaseImage( &dst ); }
该运算结果有问题,显示结果为白色,还没找到原因。
如图,
参考文献:
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学习笔记-阈值化
- OpenCV学习笔记-阈值化
- OpenCV学习笔记-自适应阈值化
- OpenCV学习笔记-自适应阈值化
- Opencv学习笔记-----图像阈值化处理
- 【OpenCV学习笔记】十六、图像阈值化
- OpenCV学习笔记-自适应阈值化
- 学习OpenCV---阈值化
- openCV学习笔记(8)-- 图像阈值化
- opencv学习笔记 第二篇 图像阈值化
- OpenCV学习之阈值化
- OpenCV学习之阈值化
- opencv学习笔记(十九)单通道固定阈值cvThreshold()以及自适应阈值化 OTSU算法
- OpenCV学习笔记(2): 基本阈值操作
- opencv学习笔记--基本阈值操作
- opencv学习笔记—8,阈值操作
- opencv 学习之 阈值化<1> 单一阈值
- opencv 学习之 阈值化<2> 自适应阈值
- VI 行处理技巧数枚
- Java se 7 新特性研究(三)
- MySQL效能监控工具--mysqlreport
- Usaco 1.2.1 挤牛奶(Milking Cows)
- Lion企业应用测试(1):绑定Active Directory
- OpenCV学习笔记-阈值化
- Mysql监控工具小集合
- 你需要准备的五个面试问题
- 72法则
- VIM中常用的查找、替换、删除模式总结
- WinForm开发,窗体显示和窗体传值
- 关于Oracle数据库中行迁移/行链接的问题
- RM文件解析之RM文件格式
- CUDA4.0 X32 + Windows7 32bit + Visual Studio 2008+ Visual Assist安装指南By Richard