分析图像、物体和视频信息过程,我们常把看到的物体用直方图(histogram)表示,直方图可以用来描述各种不同的事情,如物体的色彩分布、物体边缘梯度模板,以及表示目标位置的概率分布。直方图广泛应用在计算机视觉应用中,简单说,直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中,bin中的数值是从数据中计算出的统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。直方图获得的是数据分布的统计图。
直方图有待深入理解!!
----------------------------------------------------------------------------------------------
cvCvtPixToPlane
openCV里面的一个函数
可以看作cvSplit是他的宏:
#define cvCvtPixToPlane cvSplit
void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 );
作用是:分割多通道数组成几个单通道数组或者从数组中提取一个通道
一般用法是cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,IplImage *dst4)
第一个参数是源图像,后面是分离出来每个通道的目标图像,如果原图像是3通道的,可以把最后一个参数设置为空。例如cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,NULL),NULL也可以写为0.
CreateHist
CreateHist
创建直方图
CvHistogram* cvCreateHist( int dims, int* sizes, int type,
float** ranges=NULL, int uniform=1 );
dims
直方图维数的数目
sizes
直方图维数尺寸的数组
type
直方图的表示格式: CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges
图中方块范围的数组. 它的内容取决于参数 uniform 的值。这个范围的用处是确定何时计算直方图或决定反向映射(backprojected ),每个方块对应于输入图像的哪个/哪组值。
uniform
归一化标识。 如果不为0,则ranges[i](0<=i<cDims,译者注:cDims为直方图的维数,对于灰度图为1,彩色图为3)是包含两个元素的范围数组,包括直方图第i维的上界和下界。在第i维上的整个区域 [lower,upper]被分割成 dims[i] 个相等的块(译者注:dims[i]表示直方图第i维的块数),这些块用来确定输入象素的第 i 个值(译者注:对于彩色图像,i确定R, G,或者B)的对应的块;如果为0,则ranges[i]是包含dims[i]+1个元素的范围数组,包括lower0, upper0, lower1, upper1 == lower2, ..., upperdims[i]-1, 其中lowerj 和upperj分别是直方图第i维上第 j 个方块的上下界(针对输入象素的第 i 个值)。任何情况下,输入值如果超出了一个直方块所指定的范围外,都不会被 cvCalcHist 计数,而且会被函数 cvCalcBackProject 置零。
函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。 如果数组的 ranges 是 0, 则直方块的范围必须由函数 cvSetHistBinRanges 稍后指定。虽然 cvCalcHist 和 cvCalcBackProject 可以处理 8-比特图像而无需设置任何直方块的范围,但它们都被假设等分 0..255 之间的空间。
创建直方图
CvHistogram* cvCreateHist( int dims, int* sizes, int type,
float** ranges=NULL, int uniform=1 );
dims
直方图维数的数目
sizes
直方图维数尺寸的数组
type
直方图的表示格式: CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges
图中方块范围的数组. 它的内容取决于参数 uniform 的值。这个范围的用处是确定何时计算直方图或决定反向映射(backprojected ),每个方块对应于输入图像的哪个/哪组值。
uniform
归一化标识。 如果不为0,则ranges[i](0<=i<cDims,译者注:cDims为直方图的维数,对于灰度图为1,彩色图为3)是包含两个元素的范围数组,包括直方图第i维的上界和下界。在第i维上的整个区域 [lower,upper]被分割成 dims[i] 个相等的块(译者注:dims[i]表示直方图第i维的块数),这些块用来确定输入象素的第 i 个值(译者注:对于彩色图像,i确定R, G,或者B)的对应的块;如果为0,则ranges[i]是包含dims[i]+1个元素的范围数组,包括lower0, upper0, lower1, upper1 == lower2, ..., upperdims[i]-1, 其中lowerj 和upperj分别是直方图第i维上第 j 个方块的上下界(针对输入象素的第 i 个值)。任何情况下,输入值如果超出了一个直方块所指定的范围外,都不会被 cvCalcHist 计数,而且会被函数 cvCalcBackProject 置零。
函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。 如果数组的 ranges 是 0, 则直方块的范围必须由函数 cvSetHistBinRanges 稍后指定。虽然 cvCalcHist 和 cvCalcBackProject 可以处理 8-比特图像而无需设置任何直方块的范围,但它们都被假设等分 0..255 之间的空间。
GetMinMaxHistValue
GetMinMaxHistValue
发现最大和最小直方块
void cvGetMinMaxHistValue( const CvHistogram* hist,
float* min_value, float* max_value,
int* min_idx=NULL, int* max_idx=NULL );
hist
直方图
min_value
直方图最小值的指针
max_value
直方图最大值的指针
min_idx
数组中最小坐标的指针
max_idx
数组中最大坐标的指针
函数 cvGetMinMaxHistValue 发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。
发现最大和最小直方块
void cvGetMinMaxHistValue( const CvHistogram* hist,
float* min_value, float* max_value,
int* min_idx=NULL, int* max_idx=NULL );
hist
直方图
min_value
直方图最小值的指针
max_value
直方图最大值的指针
min_idx
数组中最小坐标的指针
max_idx
数组中最大坐标的指针
函数 cvGetMinMaxHistValue 发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。
QueryHistValue_1D
QueryHistValue_1D
查询直方块的值
#define cvQueryHistValue_1D( hist, idx0 ) \
cvGetReal1D( (hist)->bins, (idx0) )
#define cvQueryHistValue_2D( hist, idx0, idx1 ) \
cvGetReal2D( (hist)->bins, (idx0), (idx1) )
#define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \
cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) )
#define cvQueryHistValue_nD( hist, idx ) \
cvGetRealND( (hist)->bins, (idx) )
hist
直方图
idx0, idx1, idx2, idx3
直方块的下标索引
idx
下标数组
宏 cvQueryHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方图的指定直方块的值。对稀疏直方图,如果方块在直方图中不存在,函数返回 0, 而且不创建新的直方块。
QueryHistValue_1D
查询直方块的值
#define cvQueryHistValue_1D( hist, idx0 ) \
cvGetReal1D( (hist)->bins, (idx0) )
#define cvQueryHistValue_2D( hist, idx0, idx1 ) \
cvGetReal2D( (hist)->bins, (idx0), (idx1) )
#define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \
cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) )
#define cvQueryHistValue_nD( hist, idx ) \
cvGetRealND( (hist)->bins, (idx) )
hist
直方图
idx0, idx1, idx2, idx3
直方块的下标索引
idx
下标数组
宏 cvQueryHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方图的指定直方块的值。对稀疏直方图,如果方块在直方图中不存在,函数返回 0, 而且不创建新的直方块。
CalcHist
CalcHist
计算图像image(s) 的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist,
int accumulate=0, const CvArr* mask=NULL );
image
输入图像s (虽然也可以使用 CvMat** ).
hist
直方图指针
accumulate
累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。
mask
操作 mask, 确定输入图像的哪个象素被计数
函数 cvCalcHist 计算单通道或多通道图像的直方图。 用来增加直方块的数组元素可从相应输入图像的同样位置提取。
Rectangle
Rectangle
绘制简单、指定粗细或者带填充的 矩形
void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
int thickness=1, int line_type=8, int shift=0 );
img
图像.
pt1
矩形的一个顶点。
pt2
矩形对角线上的另一个顶点
color
线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
thickness
组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
line_type
线条的类型。见cvLine的描述
shift
坐标点的小数点位数。
函数 cvRectangle 通过对角线上的两个顶点绘制矩形。
CalcHist
计算图像image(s) 的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist,
int accumulate=0, const CvArr* mask=NULL );
image
输入图像s (虽然也可以使用 CvMat** ).
hist
直方图指针
accumulate
累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。
mask
操作 mask, 确定输入图像的哪个象素被计数
函数 cvCalcHist 计算单通道或多通道图像的直方图。 用来增加直方块的数组元素可从相应输入图像的同样位置提取。
Rectangle
Rectangle
绘制简单、指定粗细或者带填充的 矩形
void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
int thickness=1, int line_type=8, int shift=0 );
img
图像.
pt1
矩形的一个顶点。
pt2
矩形对角线上的另一个顶点
color
线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
thickness
组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
line_type
线条的类型。见cvLine的描述
shift
坐标点的小数点位数。
函数 cvRectangle 通过对角线上的两个顶点绘制矩形。
----------------------------------------------------------------------------------------------
/*code*/
- #include <highgui.h>
- #include <cv.h>
- int main( int argc, char** argv )
- {
- IplImage* src;
- if( argc == 2 && ( src = cvLoadImage( argv[1], 1 ) ) != 0 )
- {
- IplImage* hsv = cvCreateImage( cvGetSize( src ), 8, 3 );
- cvCvtColor( src, hsv, CV_BGR2HSV ); //色彩空间的转换
- //计算直方图,并将其分解为单通道
- IplImage* h_plane = cvCreateImage( cvGetSize( src ), 8, 1 );
- IplImage* s_plane = cvCreateImage( cvGetSize( src ), 8, 1 );
- IplImage* v_plane = cvCreateImage( cvGetSize( src ), 8, 1 );
- IplImage* planes[] = { h_plane, s_plane };
- cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); //分割多通道数组成几个单通道数组或者从数组中提取一个通道,可以看作cvSplit是他的宏
- //构建直方图,并计算直方图
- int h_bins = 30, s_bins = 20;
- CvHistogram* hist;
- { //单独的模块
- int hist_size[] = { h_bins, s_bins }; //直方图矩阵大小
- float h_ranges[] = { 0, 180 };
- float s_ranges[] = { 0, 255 };
- float* ranges[] = { h_ranges, s_ranges };//二维数组
- hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); //创建直方图,参数是维度,矩阵大小,直方图的表示格式(CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 ),图中方块范围的数组
- };
- cvCalcHist( planes, hist, 0, 0 ); //计算图像image(s) 的直方图,planes是IplImage**类型
- //创建图像来显示直方图
- int scale = 10;
- IplImage* hist_img = cvCreateImage( cvSize( h_bins * scale, s_bins * scale ), 8, 3 );
- cvZero( hist_img );
- //填充
- float max_value = 0;
- cvGetMinMaxHistValue( hist, 0, &max_value, 0 ); //找到最大和最小直方块
- for( int h = 0; h < h_bins; h++ ) //遍历矩阵
- {
- for( int s = 0; s < s_bins; s++ )
- {
- float bin_val = cvQueryHistValue_2D( hist, h, s ); //查询二维直方块的值
- int intensity = cvRound( bin_val * 255 ); //将输入浮点数转换为整数
- cvRectangle( hist_img,
- cvPoint( h * scale, s * scale ),
- cvPoint( ( ( h+1 ) * scale - 1 ), ( ( s+1 ) * scale - 1 ) ),
- CV_RGB( intensity, intensity, intensity ),
- CV_FILLED
- ); //绘制矩形,确定矩形对角线的两个点
- }
- }
- cvNamedWindow( "source", 1 );
- cvShowImage( "source", src );
- cvNamedWindow( "H-S Histogram", 1 );
- cvShowImage( "H-S Histogram", hist_img );
- cvWaitKey(0);
- }
- return 0;
- }
/*result*/
source image
histogram image