opencv 灰度直方图三维直方图//输出值是什么意思

opencv学习之路(151)
#include&opencv2/opencv.hpp&
#include&iostream&
#include&vector&
int main()
Mat srcImage = imread(&1.jpg&);
imshow(&【原图】&, srcImage);
//因为要计算H-S的直方图,所以需要得到一个HSV空间的图像
cvtColor(srcImage, hsvImage, CV_BGR2HSV);
imshow(&【HSV空间的原图】&, hsvImage);
//为计算直方图配置变量
//首先是需要计算的图像的通道,就是需要计算图像的哪个通道(bgr空间需要确定计算 b或g货r空间)
int channels[] = { 0, 1 };
//然后是配置输出的结果存储的 空间 ,用MatND类型来存储结果
MatND dstH
//接下来是直方图的每一个维度的 柱条的数目(就是将数值分组,共有多少组)
//如果这里写成int histSize = 256;
那么下面调用计算直方图的函数的时候,该变量需要写 &histSize
int histSize[] = { 30, 32 };
//最后是确定每个维度的取值范围,就是横坐标的总数
//首先得定义一个变量用来存储 单个维度的 数值的取值范围
float HRanges[] = { 0, 180 };
float SRanges[] = { 0, 256 };
const float *ranges[] = { HRanges, SRanges };
calcHist(&hsvImage, 1, channels, Mat(), dstHist, 2, histSize, ranges, true, false);
//calcHist
函数调用结束后,dstHist变量中将储存了 直方图的信息
用dstHist的模版函数 at&Type&(i)得到第i个柱条的值
//at&Type&(i, j)得到第i个并且第j个柱条的值
//开始直观的显示直方图——绘制直方图
//首先先创建一个黑底的图像,为了可以显示彩色,所以该绘制图像是一个8位的3通道图像
Mat drawImage = Mat::zeros(Size(300, 320), CV_8UC3);
//因为任何一个图像的某个像素的总个数,都有可能会有很多,会超出所定义的图像的尺寸,针对这种情况,先对个数进行范围的限制
//先用 minMaxLoc函数来得到计算直方图后的像素的最大个数
double g_dHistMaxV
minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);
//将像素的个数整合到 图像的最大范围内
//遍历直方图得到的数据
for (int i = 0; i & 30; i++)
for (int j = 0; j & 32; j++)
int value = cvRound(dstHist.at&float&(i, j) * 256 / g_dHistMaxValue);
rectangle(drawImage, Point(10 * i, j * 10), Point((i + 1) * 10 - 1, (j + 1) * 10 - 1), Scalar(value), -1);
imshow(&【直方图】&, drawImage);
waitKey(0);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:80641次
积分:2557
积分:2557
排名:第11783名
原创:182篇
评论:14条
(1)(30)(47)(23)(45)(1)(1)(1)(3)(16)(13)(2)在数字图像处理中,灰度直方图是一种最简单、最有用的工具之一,它概括了一幅图像的灰度级内容。一个图像是由不同颜色值的像值组成。像素值在图像中的分布情况是这幅图像的一个重要特征。OpenCV里面提供了不少有关直方图处理的函数。其中最基本的是计算直方图的函数calcHist( )。
首先来看看OpenCV1.1中函数calcHist()如下:
/* Calculates array histogram */CVAPI(void)
cvCalcArrHist( CvArr** arr, CvHistogram* hist,
int accumulate CV_DEFAULT(0),
const CvArr* mask CV_DEFAULT(NULL) );CV_INLINE
cvCalcHist( IplImage** image, CvHistogram* hist,
int accumulate CV_DEFAULT(0),
const CvArr* mask CV_DEFAULT(NULL) )
其中函数中参数:
image 输入图像s (虽然也可以使用 CvMat** ).
hist&&& 直方图指针
accumulate 累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。
mask 操作 mask, 确定输入图像的哪个象素被计数
函数 cvCalcHist 计算一张或多张单通道图像的直方图(若要计算多通道,可像以下例子那样用多个单通道图来表示)。 用来增加直方块的数组元素可从相应输入图像的同样位置提取。
接下来看看OpenCV2.xx中imgproc.hpp头文件有关于计算直方图的3个重载函数calcHist()中最重要的一个,如下所示:
//! computes the joint dense histogram for a set of images.CV_EXPORTS void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
OutputArray hist, int dims,
const int* histSize,const float** ranges,
bool uniform=true, bool accumulate=false );
其中函数中参数:
images 表示需要用来计算直方图的源图像序列,因此可以允许有多张大小一样,数据类型相同的图像被用来统计其直方图特征。
nimages 表示的就是使用多少张图像序列中的图像用于计算直方图。
channels的出现主要是考虑到输入的每一张图像有可能是多通道的,比如说RGB图就是3通道的,那么从统计意义上来讲,一张RGB图其实就是3张单通道的图像,而计算直方图时其本质也是针对单张图像进行的。这里虽然我们输入的图像序列images中有很多图片,但是并不是每一张图片的每一个通道都会被用来计算。所以参数3的功能是指定哪些通道的图像被用来计算(后面的解释都假设图像序列中图像是3通道的,那么有的图像可能有多个通道都被用来计算,有的图像可能连一个通道都没有被采用),这时参数3里面保存的是通道的序号,那么图像序列images中的第一张图片的通道序号(假设图像时3通道的)为0,1,2;images中第二张图片的图像序列接着上一次的,为3,4,5,;依次类推即可。
mask是mask掩膜操作,即指定每张图片的哪些像素被用于计算直方图,这个掩膜矩阵不能够针对特定图像设定特定的掩膜,因此在这里是一视同仁对待的。
hist是保存计算的直方图结果的矩阵,有可能是多维矩阵。
dims是需要计算的直方图的维数。
histSize是所需计算直方图的每一维的大小,即每一维bin的个数。
ranges是所需计算直方图的每一维的范围,如果参数9的uniform为true,这此时的参数8的大小为2,里面的元素值表示的是每一维的上下限这两个数字;如果参数9的uniform为false,则此时的参数8的大小为bin的个数,即参数7的值,参数8里面的元素值需要人为的指定,即每一维的坐标值不一定是均匀的,需要人为指定。
uniform 如果为true的话,则说明所需计算的直方图的每一维按照它的范围和尺寸大小均匀取值;如果为false的话,说明直方图的每一维不是均匀分布取值的,参考参数8的解释。
accumulate, 如果为false,则表示直方图输出矩阵hist在使用该函数的时候被清0了,如果为true,则表示hist在使用calcHist()函数时没有被清0,计算的结果会累加到前一次保存的值中。
使用该函数的时候需要注意,如果在默认参数的情况下uniform = true,则此时的ranges大小必须是histSize大小的两倍,并且channels的大小必须等于dims维数。从上面可以理解,channels里的值已经指定了使用哪些单通道的图像来计算目标直方图,因此当channels的尺寸确定,则对应的直方图的维数也就确定了,所以我们不能使用多张图像来计算一个一维的直方图。
另一个重载函数的形式如下:
//! computes the joint sparse histogram for a set of images.CV_EXPORTS void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
SparseMat& hist, int dims,
const int* histSize, const float** ranges,
bool uniform=true, bool accumulate=false );CV_EXPORTS_W void calcHist( InputArrayOfArrays images,
const vector&int&& channels,
InputArray mask, OutputArray hist,
const vector&int&& histSize,
const vector&float&& ranges,
bool accumulate=false );
虽然从名字上看第一个参数是一个图像序列,但是我们并不能通过该函数来计算这些图像序列的一个一维的直方图。这个函数中并不像前面的函数那样需要指定一个参数表明有多少图像参与计算,因为在images中已经体现有了。另外这个函数也不需要像上面的函数一样指定直方图的维数,因为使用这个重载函数就表示默认为直方图的维数和channels的尺寸一样。最后本重载函数中的uniform在函数内部设定了为true,表面直方图中每一维都必须是均匀分布的。总之,上面2个函数是计算多个图像的直方图,直方图可以是多维的,该维数等于最终用于计算直方图的单通道的图像的个数。
在使用OpenCV内部的判断条件时应该使用CV_Assert( )函数,而不是CV_ASSERT()。通过实验测试发现,虽然经过calcHist()函数计算过后的直方图保存在hist中,这里hist是一个Mat类型,并且如果计算的是一维的直方图的话,则hist是一个列向量。
现在,我们来使用不同版的OPENCV直方图计算。
C版OPENCV直方图计算
#include &stdafx.h&#include &cv.h&#include &cxcore.h&#include &highgui.h&IplImage* DrawHistogram(CvHistogram* hist,float scaleX =2,float scaleY =2){ float histMax =0; cvGetMinMaxHistValue(hist,0,&histMax,0); IplImage*imghist =cvCreateImage(cvSize(256*scaleX,64*scaleY),8,1); cvZero(imghist); for( int i=0; i&255; i++){
float histValue =cvQueryHistValue_1D(hist,i);
float nextValue =cvQueryHistValue_1D(hist,i+1);
CvPoint pt1 = cvPoint(
i*scaleX,64*scaleY);
CvPoint pt2 = cvPoint((i+1)*scaleX,64*scaleY);
CvPoint pt3 = cvPoint((i+1)*scaleX,64*scaleY-(nextValue/histMax)*64*scaleY);
CvPoint pt4 = cvPoint(i*scaleX,64*scaleY-(histValue/histMax)*64*scaleY);
int numPts =5;
CvPoint pts[5];
pts[0] = pt1;
pts[1] = pt2;
pts[2] = pt3;
pts[3] = pt4;
pts[4] = pt1;
cvFillConvexPoly(imghist,pts,numPts,cvScalar(255,250,0,0)); } }int _tmain(int argc, _TCHAR* argv[]){ IplImage*src = cvLoadImage(&iris.tif&); cvNamedWindow(&Sr&); cvShowImage(&Sr&,src); int bins =1; int dims =1; int size = 256/ float range[] ={0,255}; float* ranges[] ={range}; CvHistogram * hist = cvCreateHist(dims,&size,CV_HIST_ARRAY,ranges,1); cvClearHist(hist); IplImage *imgRed = cvCreateImage(cvGetSize(src),8,1); IplImage *imgGreen = cvCreateImage(cvGetSize(src),8,1); IplImage *imgBlue = cvCreateImage(cvGetSize(src),8,1); cvSplit(src,imgBlue,imgGreen,imgRed,NULL); cvCalcHist(&imgBlue,hist,0,0); IplImage*histBlue = DrawHistogram(hist); cvClearHist(hist); cvNamedWindow(&Blue&); cvShowImage(&Blue&,histBlue); cvCalcHist(&imgGreen,hist,0,0); IplImage* histGreen = DrawHistogram(hist); cvClearHist(hist); cvNamedWindow(&Green&); cvShowImage(&Green&,histGreen); cvCalcHist(&imgRed,hist,0,0); IplImage* histRed = DrawHistogram(hist); cvClearHist(hist); cvNamedWindow(&Red&); cvShowImage(&Red&,histRed); cvWaitKey(0); cvDestroyAllWindows(); return 0;}
输出结果如下图所示
C plus plus版OPENCV直方图计算
#include &stdafx.h&#include &opencv2/opencv.hpp&int _tmain(int argc, _TCHAR* argv[]){ Mat src = imread(&iris.tif&); //Load image M
if( !src.data ) exit(0);
// Separate the image in 3 places ( B, G and R ) vector&Mat& bgr_ split( src, bgr_planes );
int histSize = 256; // Establish the number of bins float range[] = { 0, 256 }; /// Set the ranges ( for B,G,R) ) const float* histRange = { range };
bool uniform =
bool accumulate = Mat b_hist, g_hist, r_
// Compute the histograms: calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histograms for B, G and R int hist_w = 600; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
// Normalize the result to [ 0, histImage.rows ] normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
// Draw for each channel for( int i = 1; i & histS i++ ){
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at&float&(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at&float&(i)) ),
Scalar( 255, 0, 0), 2, 8, 0
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at&float&(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at&float&(i)) ),
Scalar( 0, 255, 0), 2, 8, 0
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at&float&(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at&float&(i)) ),
Scalar( 0, 0, 255), 2, 8, 0
); } namedWindow(&calcHist&, CV_WINDOW_AUTOSIZE ); imshow(&calcHist&, histImage ); waitKey(0); return 0;}
输出结果如下:
在这里,输出图像整体反应了iris.tif 的图像直方图,但局部细节还待于优化。
Python版OpenCV计算直方图
下面来看下彩色图像的直方图处理。首先读取并分离各通道和接着计算每个通道的直方图,这里将其封装成一个函数calcAndDrawHist:
import cv2import numpy as npdef calcAndDrawHist(image, color):
hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0])
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)
histImg = np.zeros([256,256,3], np.uint8)
hpt = int(0.9* 256);
for h in range(256):
intensity = int(hist[h]*hpt/maxVal)
cv2.line(histImg,(h,256), (h,256-intensity), color)
return histIif __name__ == '__main__':
img = cv2.imread(&..//iris.tif&)
b, g, r = cv2.split(img)
histImgB = calcAndDrawHist(b, [255, 0, 0])
histImgG = calcAndDrawHist(g, [0, 255, 0])
histImgR = calcAndDrawHist(r, [0, 0, 255])
cv2.imshow(&histBlue&, histImgB)
cv2.imshow(&histGreen&, histImgG)
cv2.imshow(&histRed&, histImgR)
cv2.imshow(&Src&, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
这样就能得到三个通道的直方图了,如下:
abid rahman
的做法,无需分离通道,用折线来描绘直方图的边界可在一副图中同时绘制三个通道的直方图。方法如下:
import cv2
import numpy as np
img = cv2.imread('..//iris.tif')
h = np.zeros((256,256,3))
bins = np.arange(256).reshape(256,1)
color = [ (255,0,0),(0,255,0),(0,0,255) ]
for ch, col in enumerate(color):
originHist = cv2.calcHist([img],[ch],None,[256],[0,256])
cv2.normalize(originHist, originHist,0,255*0.9,cv2.NORM_MINMAX)
hist=np.int32(np.around(originHist))
pts = np.column_stack((bins,hist))
cv2.polylines(h,[pts],False,col)
h=np.flipud(h)
cv2.imshow('colorhist',h)
cv2.waitKey(0)
结果如下图所示:
这里的for循环是对三个通道遍历一次,每次绘制相应通道的直方图的折线。for循环的第一行是计算对应通道的直方图,经过上面的介绍,应该很容易就能明白。
这里所不同的是没有手动的计算直方图的最大值再乘以一个系数,而是直接调用了OpenCV的归一化函数。该函数将直方图的范围限定在0-255&0.9之间,与之前的一样。
语句hist= np.int32(np.around(originHist))先将生成的原始直方图中的每个元素四舍六入五凑偶取整(cv2.calcHist函数得到的是float32类型的数组),接着将整数部分转成np.int32类型。即61.123先转成61.0,再转成61。注意,这里必须使用np.int32(…)进行转换,numpy的转换函数可以对数组中的每个元素都进行转换,而Python的int(…)只能转换一个元素,如果使用int(…),将导致only length-1 arrays can be converted to Python scalars错误。
语句pts = np.column_stack((bins,hist))是将直方图中每个bin的值转成相应的坐标。比如hist[0] =3,…,hist[126] = 178,…,hist[255] = 5;而bins的值为[[0],[1],[2]…,[255]]。使用np.column_stack将其组合成[0, 3]、[126, 178]、[255, 5]这样的坐标作为元素组成的数组。
最后使用cv2.polylines函数根据这些点绘制出折线,第三个False参数指出这个折线不需要闭合。第四个参数指定了折线的颜色。
当所有完成后,别忘了用h = np.flipud(h)反转绘制好的直方图,因为绘制时,[0,0]在图像的左上角。
NumPy版的直方图计算
abid rahman
的资料时,发现他用NumPy的直方图计算函数
np.histogram也实现了相同的效果。如下:
import cv2
import numpy as np
img = cv2.imread('../iris.tif')
h = np.zeros((300,256,3))
bins = np.arange(257)
bin = bins[0:-1]
color = [ (255,0,0),(0,255,0),(0,0,255) ]
for ch,col in enumerate(color):
item = img[:,:,ch]
N,bins = np.histogram(item,bins)
N = np.int32(np.around((N*255)/v))
N=N.reshape(256,1)
pts = np.column_stack((bin,N))
cv2.polylines(h,[pts],False,col)
h=np.flipud(h)
cv2.imshow('img',h)
cv2.waitKey(0)
效果图和上面的一个相同。
未完待续。。。如有错误,请多多指正。谢谢!
[1]& Robert Lagnaiere &
OpenCV 2 Computer Vision Application Programming Cookbook
[2]& Daniel Lelis Baggio,Shervin Emami,&
Mastering OpenCV with Practical Computer Vision Projects
Joseph Howse
&OpenCV Computer Vision with Python
Gary Bradski, Adrian Kaehler
&Learing OpenCV Computer Vision with the OpenCV Library(the First Edition)&
=======================================================
转载请注明出处:
=======================================================
本文转载自:
欢迎加入我爱机器学习QQ9群:
微信扫一扫,关注我爱机器学习公众号
欢迎加入我爱机器学习QQ9群:
最新文章列表
NIPS 2016 — Day 1 Highlights NIPS 2016 — Day 2 Highlights:...
2017年二月 &(19)
2017年一月 &(54)
2016年十二月 &(62)
2016年十一月 &(97)
2016年十月 &(97)
2016年九月 &(124)
2016年八月 &(83)
2016年七月 &(13)
2016年六月 &(10)
2016年五月 &(6)
2016年四月 &(9)
2016年三月 &(7)
2016年二月 &(2)
2016年一月 &(3)
2015年十二月 &(5)
2015年十一月 &(4)
2015年十月 &(2)
2015年九月 &(2)
2015年八月 &(3)
2015年七月 &(6)
2015年六月 &(8)
2015年五月 &(4)
2015年四月 &(1)
2015年三月 &(3)
2015年二月 &(1)
2015年一月 &(2)
2014年十二月 &(4)
2014年十一月 &(2)
2014年十月 &(3)
2014年九月 &(4)
2014年八月 &(22)
2014年七月 &(40)
2014年六月 &(61)
2014年五月 &(63)
2014年四月 &(187)
2014年三月 &(4799)
2014年二月 &(764)
2014年一月 &(330)
2013年十二月 &(145)
2013年十一月 &(126)
2013年十月 &(216)
2013年九月 &(284)
2013年八月 &(327)
2013年七月 &(275)
2013年六月 &(315)
2013年五月 &(228)
2013年四月 &(175)
2013年三月 &(186)
2013年二月 &(118)
2013年一月 &(210)
2012年十二月 &(221)
2012年十一月 &(155)
2012年十月 &(144)
2012年九月 &(98)
2012年八月 &(99)
2012年七月 &(109)
2012年六月 &(75)
2012年五月 &(88)
2012年四月 &(78)
2012年三月 &(78)
2012年二月 &(50)
2012年一月 &(17)
2011年十二月 &(27)
2011年十一月 &(6)
2011年十月 &(11)
2011年九月 &(13)
2011年八月 &(13)
2011年七月 &(19)
2011年六月 &(18)
2011年五月 &(6)
2011年四月 &(12)
2011年三月 &(15)
2011年二月 &(6)
2011年一月 &(9)
2010年十二月 &(6)
2010年十一月 &(11)
2010年十月 &(5)
2010年九月 &(8)
2010年八月 &(5)
2010年七月 &(12)
2010年六月 &(4)
2010年五月 &(7)
2010年四月 &(6)
2010年三月 &(12)
2010年二月 &(7)
2010年一月 &(2)
2009年十二月 &(5)
2009年十一月 &(16)
2009年十月 &(6)
2009年九月 &(7)
2009年八月 &(7)
2009年七月 &(5)
2009年六月 &(6)
2009年五月 &(6)
2009年四月 &(4)
2009年三月 &(7)
2009年二月 &(6)
2009年一月 &(1)
2008年十二月 &(4)
2008年十一月 &(5)
2008年十月 &(1)
2008年八月 &(1)
2008年七月 &(3)
2008年六月 &(3)
2008年五月 &(3)
2008年三月 &(1)
2007年十二月 &(1)
2007年十月 &(1)
2007年八月 &(4)
2007年七月 &(1)OpenCV直方图的使用
OpenCV直方图的使用
发布时间: 0:26:24
编辑:www.fx114.net
本篇文章主要介绍了"OpenCV直方图的使用",主要涉及到OpenCV直方图的使用方面的内容,对于OpenCV直方图的使用感兴趣的同学可以参考一下。
主要涉及两个函数:
CvHistogram
cvCalcHist
#include&stdio.h&
#include&cv.h&
#include&highgui.h&
int main()
int hist_size[]={16,16,16};
float range[]={0,255};
float *ranges[]={range};
int i,j,bin_w;
float max_value,min_
int min_idx, max_
char *name[3]={&b&,&g&,&r&};
double mean=0,variance=0;
IplImage* img=cvLoadImage(&b.jpg&,1);
IplImage *pImage=NULL;
IplImage *pImg[3];
pImg[0]=cvCreateImage(cvGetSize(img),8,1);
pImg[1]=cvCreateImage(cvGetSize(img),8,1);
pImg[2]=cvCreateImage(cvGetSize(img),8,1);
cvSplit(img,pImg[0],pImg[1],pImg[2],NULL);
pImage=cvCloneImage(img);
CvRect rect= cvRect(0,0,500,600);
cvSetImageROI(pImage,rect);
//创建一个图像用来存放直方图
IplImage *histImage[3];
CvHistogram *hist[3];
for(j=0;j&3;j++){
histImage[j]=cvCreateImage(cvSize(320,200),8,3);
//cvZero(histImage[j]);
hist[j]=cvCreateHist(1,&hist_size[j],CV_HIST_ARRAY,ranges,1);
//计算直方图并作用到hist变量中
cvCalcHist(&pImg[j], hist[j], 0, NULL);
//得到直方图的最值及标号
cvGetMinMaxHistValue(hist[j],&min_value,&max_value,&min_idx,&max_idx);
//缩放其最大值和最小值让其融入图像
cvScale(hist[j]-&bins,hist[j]-&bins,((double)histImage[j]-&height)/max_value,0);
//设置所有的直方图的数值为255
cvSet(histImage[j],cvScalarAll(255),0);
//建一个比例因子 沿宽度释放
bin_w=cvRound((double)histImage[j]-&width/hist_size[j]);
for(i=0;i&hist_size[j];i++)
CvScalar scalar=cvScalarAll(0);
scalar.val[j]=(i*255/hist_size[j]);
cvRectangle(histImage[j],cvPoint(i*bin_w,histImage[j]-&height),
cvPoint((i+1)*bin_w,histImage[j]-&height-cvRound(cvGetReal1D(hist[j]-&bins,i))),scalar,-1,8,0);
float *bins=cvGetHistValue_1D(hist[j],i);
//增加均值
mean+=bins[0];
//std::cout&&bins[0]&&& &&&bins[1]&&std::
//printf(&%d %d\n&,bins[0],bins[1]);
cvNamedWindow(name[j],0);
cvShowImage(name[j],histImage[j]);
mean/=hist_size[j];
//根据均值计算变化量
for(i=0;i&hist_size[j];i++)
float* bins=cvGetHistValue_1D(hist[j],i);
variance+=pow((bins[0]-mean),2);
variance/=hist_size[j];
printf(&histgram Mean:%f\n&,mean);
//创建窗口
cvNamedWindow(&Original&,0);
cvShowImage(&Original&,pImage);
cvWaitKey(0);
cvReleaseImage(&img);
for(j=0;j&3;j++){
cvDestroyWindow(name[j]);
cvReleaseImage(&pImg[j]);
cvReleaseImage(&histImage[j]);
cvReleaseHist(&hist[j]);
cvDestroyWindow(&Original&);
CvHistogram结构
typedef struct CvHistogram
float thresh[CV_MAX_DIM][2]; /* for uniform histograms */
float** thresh2; /* for non-uniform histograms */
CvMatND /* embedded matrix header for array histograms */
bins&:用于存放直方图每个灰度级数目的数组指针,数组在cvCreateHist的时候创建,其维数由cvCreateHist确定(一般以一维比较常见)
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之间的空间。
计算图像image(s)的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist, &&&&&&&&&&&&&&&&& int accumulate=0, const CvArr* mask=NULL );
image输入图像s(虽然也可以使用CvMat**).hist直方图指针accumulate累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。mask操作
mask,确定输入图像的哪个象素被计数
函数&cvCalcHist&计算单通道或多通道图像的直方图。用来增加直方块的数组元素可从相应输入图像的同样位置提取。
计算图像image(s)的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );
image输入图像s(虽然也可以使用CvMat**).hist直方图指针accumulate累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。mask操作
mask,确定输入图像的哪个象素被计数
函数&cvCalcHist&计算单通道或多通道图像的直方图。用来增加直方块的数组元素可从相应输入图像的同样位置提取。
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&发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。
本文标题:
本页链接:}

我要回帖

更多关于 opencv 三维直方图 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信