图像的灰度直方图
2016-03-25 20:01
381 查看
1、一维直方图:单通道,bin是一条直线 二维直方图:双通道,bin是一个矩形
2、直方图的结构体:CvHistogram typedef struct CvHistogram
{
int type;
CvArr* bins; 存放直方图在每一维上直方柱的具体数据,由于存在多维直方图。如果是一维直方图,那么bins就是一个一维的矩阵;如果是二维直方图,那么bins就是一个二维 的矩阵,等等。
float thresh[CV_MAX_DIM][2]; /* 直方柱的划分 是统一划分的,即均等划分的 */
float** thresh2; /*不均等划分,可以自动设定每一个直方柱的取值范围。之所以是二级指针,每一个柱的取值范围用一级指针表示,又存在多个直方柱,所以需要二级指针才 能表示。每一个不在指定范围的值,会被忽略掉。*/
CvMatND mat; /* 存放直方图的数据 */
}
3、CvHistogram* cvCreateHist( int dims, int* sizes, int type,float** ranges=NULL, int uniform=1 ); 创建一个直方图的函数
dims:表示直方图的维度
sizes:每一维上直方柱(bin)的数据
type:直方图存储数据的方式:CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges:直方图在每一维度上的范围。
uniform:存每一维的坐标的取值范围。该值为0时,表示bin的范围是程序员自由设定的。当该值为非零时,表示bin的划分,是均等划分。
注:在创建完一个直方图后,必须调用cvClearHist(hist)函数,去掉一些不必要的随机值
4、给某个通道分配相应的空间:IplImage* b_img=cvCreateImage(cvGetSize(img),8,1);
5、cvSplit(img,b_img,g_img,r_img,NULL); 把图img像分解成四个通道,且这三个通道的顺序必须是B、G、R
6、计算每一个通道的直方图,即每个通道上的每个直方柱的大小(高度):cvCalcHist(&b_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
7、找出htist这个直方图里面哪个直方柱的值最大,并将该最大值存在histmax里面,为了做归一化: float histmax=0; cvGetMinMaxHistValue(hist,0,&histmax,0,0);
8、获取直方图hist里边第i个bin的值:float pt=cvQueryHistValue_1D(hist,i);
// 图像的灰度直方图.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
IplImage* DrawHistogram(CvHistogram* hist,int scaleX=1,int scaleY=1)
{
float histmax=0;
cvGetMinMaxHistValue(hist,0,&histmax,0,0);
IplImage* histImg=cvCreateImage(cvSize(256*scaleX,64*scaleY),8,1);
cvZero(histImg);
for(int i=0;i<255;i++)
{
float pt=cvQueryHistValue_1D(hist,i); //获取直方图hist里边第i个bin的值
float pt_next=cvQueryHistValue_1D(hist,i+1); //获取直方图hist里边第i+1个bin的值
CvPoint pt1=cvPoint(i*scaleX,64*scaleY); //第i个点的坐标
CvPoint pt2=cvPoint((i+1)*scaleX,64*scaleY); //第i+1个点的坐标
CvPoint pt3=cvPoint((i+1)*scaleX,(64-pt_next/histmax*64)*scaleY); //归一化
CvPoint pt4=cvPoint(i*scaleX,(64-pt/histmax*64)*scaleY);
CvPoint pts[5];
int numPts=5;
pts[0]=pt1;
pts[1]=pt2;
pts[2]=pt3;
pts[3]=pt4;
pts[4]=pt1;
//不能直接这样子赋值:CvPoint pts[5]={pt1,pt2,pt3,pt4,pt5};
cvFillConvexPoly(histImg,pts,numPts,cvScalar(255)); //填充由这四个点构成的矩形
}
return histImg;
}
int main(int argc, char* argv[])
{
IplImage* img=cvLoadImage("E:\\大四上\\openCV\\图片\\机器猫.jpg");
IplImage* b_img=cvCreateImage(cvGetSize(img),8,1); //单通道图像
IplImage* g_img=cvCreateImage(cvGetSize(img),8,1);
IplImage* r_img=cvCreateImage(cvGetSize(img),8,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); //清除直方图,去掉一些不必要的随机值
cvSplit(img,b_img,g_img,r_img,NULL); //把图像分解成四个通道
cvCalcHist(&b_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
b_img=DrawHistogram(hist);
cvNamedWindow("b_img");
cvShowImage("b_img",b_img);
cvClearHist(hist);
cvCalcHist(&g_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
g_img=DrawHistogram(hist);
cvNamedWindow("g_img");
cvShowImage("g_img",g_img);
cvClearHist(hist);
cvCalcHist(&r_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
r_img=DrawHistogram(hist);
cvNamedWindow("r_img");
cvShowImage("r_img",r_img);
cvClearHist(hist);
cvWaitKey(0);
//(1) 释放源图像
cvReleaseImage(&img);
//(2) 释放三个通道的图像
cvReleaseImage(&r_img);
cvReleaseImage(&g_img);
cvReleaseImage(&b_img);
//(4)释放直方图空间
cvReleaseHist(&hist);
return 0;
}
2、直方图的结构体:CvHistogram typedef struct CvHistogram
{
int type;
CvArr* bins; 存放直方图在每一维上直方柱的具体数据,由于存在多维直方图。如果是一维直方图,那么bins就是一个一维的矩阵;如果是二维直方图,那么bins就是一个二维 的矩阵,等等。
float thresh[CV_MAX_DIM][2]; /* 直方柱的划分 是统一划分的,即均等划分的 */
float** thresh2; /*不均等划分,可以自动设定每一个直方柱的取值范围。之所以是二级指针,每一个柱的取值范围用一级指针表示,又存在多个直方柱,所以需要二级指针才 能表示。每一个不在指定范围的值,会被忽略掉。*/
CvMatND mat; /* 存放直方图的数据 */
}
3、CvHistogram* cvCreateHist( int dims, int* sizes, int type,float** ranges=NULL, int uniform=1 ); 创建一个直方图的函数
dims:表示直方图的维度
sizes:每一维上直方柱(bin)的数据
type:直方图存储数据的方式:CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges:直方图在每一维度上的范围。
uniform:存每一维的坐标的取值范围。该值为0时,表示bin的范围是程序员自由设定的。当该值为非零时,表示bin的划分,是均等划分。
注:在创建完一个直方图后,必须调用cvClearHist(hist)函数,去掉一些不必要的随机值
4、给某个通道分配相应的空间:IplImage* b_img=cvCreateImage(cvGetSize(img),8,1);
5、cvSplit(img,b_img,g_img,r_img,NULL); 把图img像分解成四个通道,且这三个通道的顺序必须是B、G、R
6、计算每一个通道的直方图,即每个通道上的每个直方柱的大小(高度):cvCalcHist(&b_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
7、找出htist这个直方图里面哪个直方柱的值最大,并将该最大值存在histmax里面,为了做归一化: float histmax=0; cvGetMinMaxHistValue(hist,0,&histmax,0,0);
8、获取直方图hist里边第i个bin的值:float pt=cvQueryHistValue_1D(hist,i);
// 图像的灰度直方图.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
IplImage* DrawHistogram(CvHistogram* hist,int scaleX=1,int scaleY=1)
{
float histmax=0;
cvGetMinMaxHistValue(hist,0,&histmax,0,0);
IplImage* histImg=cvCreateImage(cvSize(256*scaleX,64*scaleY),8,1);
cvZero(histImg);
for(int i=0;i<255;i++)
{
float pt=cvQueryHistValue_1D(hist,i); //获取直方图hist里边第i个bin的值
float pt_next=cvQueryHistValue_1D(hist,i+1); //获取直方图hist里边第i+1个bin的值
CvPoint pt1=cvPoint(i*scaleX,64*scaleY); //第i个点的坐标
CvPoint pt2=cvPoint((i+1)*scaleX,64*scaleY); //第i+1个点的坐标
CvPoint pt3=cvPoint((i+1)*scaleX,(64-pt_next/histmax*64)*scaleY); //归一化
CvPoint pt4=cvPoint(i*scaleX,(64-pt/histmax*64)*scaleY);
CvPoint pts[5];
int numPts=5;
pts[0]=pt1;
pts[1]=pt2;
pts[2]=pt3;
pts[3]=pt4;
pts[4]=pt1;
//不能直接这样子赋值:CvPoint pts[5]={pt1,pt2,pt3,pt4,pt5};
cvFillConvexPoly(histImg,pts,numPts,cvScalar(255)); //填充由这四个点构成的矩形
}
return histImg;
}
int main(int argc, char* argv[])
{
IplImage* img=cvLoadImage("E:\\大四上\\openCV\\图片\\机器猫.jpg");
IplImage* b_img=cvCreateImage(cvGetSize(img),8,1); //单通道图像
IplImage* g_img=cvCreateImage(cvGetSize(img),8,1);
IplImage* r_img=cvCreateImage(cvGetSize(img),8,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); //清除直方图,去掉一些不必要的随机值
cvSplit(img,b_img,g_img,r_img,NULL); //把图像分解成四个通道
cvCalcHist(&b_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
b_img=DrawHistogram(hist);
cvNamedWindow("b_img");
cvShowImage("b_img",b_img);
cvClearHist(hist);
cvCalcHist(&g_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
g_img=DrawHistogram(hist);
cvNamedWindow("g_img");
cvShowImage("g_img",g_img);
cvClearHist(hist);
cvCalcHist(&r_img,hist,0,0); //计算b_img这个通道的直方图的大小,结果存在hist里面
r_img=DrawHistogram(hist);
cvNamedWindow("r_img");
cvShowImage("r_img",r_img);
cvClearHist(hist);
cvWaitKey(0);
//(1) 释放源图像
cvReleaseImage(&img);
//(2) 释放三个通道的图像
cvReleaseImage(&r_img);
cvReleaseImage(&g_img);
cvReleaseImage(&b_img);
//(4)释放直方图空间
cvReleaseHist(&hist);
return 0;
}
相关文章推荐
- 3-1 rpm包命名规则
- String to Integer---8
- linux vim编译器修改为强大的IDE
- UItableView 或者UIcollectionview,点击cell时,无反应,
- Matlab---在多个axes之间切换
- Activity原理
- 我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
- linux系统编程:进程间通信-mmap
- 时间日志和缺陷日志
- 第3章 rpm命令管理
- oracle中tablespace使用
- ubuntu下允许设置root权限,ssh远程登录
- Hibernate中一对多和多对一关系
- 心得体会
- 关于Java继承的 向上转型和向下转型
- 并查集模版
- status bar 、action bar、navigation bar height
- android小功能:checkbox使用自己的背景点击切换背景
- codeforces_612D. The Union of k-Segments(排序)
- 复习 lamp安装环境