要点:
1、读取一直彩色图片
2、从一副彩色图像中分离出R、G、B三个通道(cvSplit),并且显示
3. 分别对每个通道图像创建直方图,并显示
函数原型:
- void cvSplit(const CvArr* src,CvArr *dst0,CvArr *dst1, CvArr *dst2, CvArr *dst3);
有些时候处理多通道图像时不是很方便,在这种情况下,可以利用cvSplit()分别复制每个通道到多个单通道图像,如果需要,cvSplit()函数将复制src(即源多通道图像)的各个通道到图像dst0、dst1、dst2、dst3中。目标图像必须与源图像在大小和数据类型上匹配,当然也应该是单通道的图像。如果源图像少于4个通道(这种情况经常出现),那么传递给cvSplit()的不必要的目标参数可设置为NULL。
//分别统计rgb的直方图显示,并且显示单通道图像
//
#include "stdafx.h"
using namespace std;
const char* pstrSrcWnd = "Src";
const char* pstrBHistWnd = "b Histogram";
const char* pstrGHistWnd = "g Histogram";
const char* pstrRHistWnd = "r Histogram";
//计算和绘制直方图(R,G,B)
/* img 通道图像
* hist_img: 直方图的绘图图像
* pstrWndName: 绘图窗口
*/
void draw_histogram(IplImage* img,IplImage* hist_img,const char* pstrWndName)
{
CvHistogram* hist = NULL;
int bin_count = 256;
float range[] = {0,255};
float* ranges[]={range};
hist = cvCreateHist(1, //一维
&bin_count, //每一维上bin(直方柱)的个数, 此处为 256 【由上述两个参数,函数就会创建一个1*256的矩阵】
CV_HIST_ARRAY,
ranges,
1);
cvClearHist(hist); //防止初始化时有其它数据,先清理一下
cvCalcHist(&img,hist,0,0);
//得到直方图的最值及标号
float min,max;
int min_idx,max_idx;
cvGetMinMaxHistValue(hist,&min,&max,&min_idx,&max_idx);
//cout<<"min: "<
if (max == 0)
{
cout<<"max =0 err!"<
max = 100;
}
//缩放直方图的大小,和图像相适应
cvScale(hist->bins,hist->bins,((double)hist_img->height)/max,0);
//设置所有的直方图的数值为255
cvSet(hist_img,cvScalarAll(255),0);
// 平均每个直放柱的宽度
int bin_w=cvRound((double)hist_img->width/bin_count);
//画直方图
for(int i=0;i
{
cvRectangle(hist_img,
cvPoint(i*bin_w,hist_img->height), //左下角的点(i*bin_w,height)
cvPoint((i+1)*bin_w, hist_img->height-cvRound(cvGetReal1D(hist->bins,i))),//右上角的点((i+1)*bin_w,图像高度-直方柱的高度)
cvScalarAll(0),
-1,
8,
0);
}
// 显示直方图
cvShowImage(pstrWndName,hist_img);
}
int main(int argc, char* argv[])
{
// 创建窗口
cvNamedWindow(pstrSrcWnd,1);
cvNamedWindow(pstrBHistWnd,1);
cvNamedWindow(pstrGHistWnd,1);
cvNamedWindow(pstrRHistWnd,1);
IplImage *frame = cvLoadImage("lena.jpg");
//cvShowImage(pstrSrcWnd,frame);
// B G R 通道
CvSize img_size;
img_size.width = frame->width;
img_size.height = frame->height;
IplImage* b = cvCreateImage(img_size,8,1);
IplImage* g = cvCreateImage(img_size,8,1);
IplImage* r = cvCreateImage(img_size,8,1);
// 直方图
CvSize size;
size.width = 320;
size.height = 200;
IplImage* b_hist_img = cvCreateImage(size,8,1);
IplImage* g_hist_img = cvCreateImage(size,8,1);
IplImage* r_hist_img = cvCreateImage(size,8,1);
cvSplit(frame,b,g,r,0);
cvShowImage(pstrSrcWnd,frame);
// 绘制直方图
draw_histogram(b,b_hist_img,pstrBHistWnd);
draw_histogram(g,g_hist_img,pstrGHistWnd);
draw_histogram(r,r_hist_img,pstrRHistWnd);
//单通道图像
cvShowImage("r_img",r);
cvShowImage("g_img",g);
cvShowImage("b_img",b);
waitKey(0);
cvReleaseImage(&frame);
cvReleaseImage(&b);
cvReleaseImage(&g);
cvReleaseImage(&r);
cvReleaseImage(&b);
cvReleaseImage(&g);
cvReleaseImage(&r);
cvDestroyAllWindows();
system("pause");
return 0;
}
参考:
http://blog.csdn.net/yankai0219/article/details/6630911;
http://blog.csdn.net/augusdi/article/details/10003781;
http://blog.csdn.net/augusdi/article/details/8865211;