OpenCV学习笔记(2)之图像通道分离和RGB三通道直方图显示

要点:

1、读取一直彩色图片

2、从一副彩色图像中分离出R、G、B三个通道(cvSplit),并且显示

3.  分别对每个通道图像创建直方图,并显示


首先介绍一下opencv中的cvSplit函数:

函数原型:

[cpp]  view plain copy
  1. 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;



你可能感兴趣的:(OpenCV)