直方图

基于OpenCV库绘制灰度图,彩色图的直方图。
灰度图为单通道图,每个像素只有一个采样颜色。cvConvertImage()函数可以将其他图转换为单通道图像。绘制灰度图直方图代码如下:

void grayImgHist(IplImage* inputImg)
{
    IplImage* grayImg = cvCreateImage(cvGetSize(inputImg), 8, 1);  
    cvCvtColor(inputImg, grayImg, CV_BGR2GRAY); //彩色图转灰度图

    int histSize = 256;//直方图宽度 
    int histHeight = 256;//直方图高度 
    float range[] = {0,255};  //灰度级的范围  
    float* ranges[] ={range};  

    //创建一维直方图,统计图像在[0 255]像素的均匀分布  
    CvHistogram* grayHist = cvCreateHist(1, &histSize, CV_HIST_ARRAY, ranges, 1);  

    //计算灰度图像的一维直方图  
    cvCalcHist(&grayImg, grayHist, 0, 0);  

    //归一化直方图  
    cvNormalizeHist(grayHist, 1.0);  

    //统计直方图中的最大直方块(做多的点数)  
    float maxValue = 0;  
    cvGetMinMaxHistValue(grayHist, 0, &maxValue, 0, 0);  

    //创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数  
    IplImage* histImage = cvCreateImage(cvSize(histSize, histHeight), 8, 3);  
    cvZero(histImage); //全部初始化为0

    //分别将每个直方块的值绘制到图中 
    //图像原点为左上角
    // cvRectangle通过对角线上点绘制矩形
    for(int i = 0; i < histSize; i++)  
    {  
        float binNum = cvQueryHistValue_1D(grayHist, i); //像素i对应的点数 
        int binHeight = cvRound(binNum / maxValue * histHeight);  //要绘制的高度  
        cvRectangle(histImage,  
            cvPoint(i, histHeight - 1),  
            cvPoint(i + 1, histHeight - binHeight),  
            CV_RGB(255,255,255));    
    }  
}

这里写图片描述

彩色图一般有RGB3个通道,或者RGBA4个通道。需要对每个通道分离,再单独处理。源代码如下

void colorImgHist(IplImage* inputImg)
{
    IplImage* r=cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_8U, 1);   
    IplImage* g=cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_8U, 1);   
    IplImage* b=cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_8U, 1);   

    cvSplit(inputImg, b, g, r,NULL); //各个通道分离  

    IplImage* grayHistImage = cvCreateImage(cvGetSize(inputImg), 8, 1);  
    cvCvtColor(inputImg, grayHistImage, CV_BGR2GRAY);  
    int histWidth = 256;
    int histHeight = 256;
    float range[]={0,255};  
    float* ranges[]={range};  

    CvHistogram* rHist = cvCreateHist(1, &histWidth, CV_HIST_ARRAY, ranges, 1);  
    CvHistogram* gHist = cvCreateHist(1, &histWidth, CV_HIST_ARRAY, ranges, 1);  
    CvHistogram* bHist = cvCreateHist(1, &histWidth, CV_HIST_ARRAY, ranges, 1);  

    //R通道
    cvCalcHist(&r, rHist, 0, NULL);  
    float rMax=0;  
    cvGetMinMaxHistValue(rHist, NULL, &rMax, NULL, NULL);  
    IplImage* rHistImage = cvCreateImage(cvSize(histWidth, histHeight), 8, 3);  
    cvZero(rHistImage); //全部初始化为0
    for(int i = 0; i < histWidth; i++)  
    {  
        float binNum = cvQueryHistValue_1D(rHist, i); //像素i对应的点数 
        int binHeight = cvRound(binNum / rMax * histHeight);  //要绘制的高度  
        cvRectangle(rHistImage,  
            cvPoint(i, histHeight - 1),  
            cvPoint(i + 1, histHeight - binHeight),  
            CV_RGB(255, 0, 0));    
    }  

    //G通道
    cvCalcHist(&g, gHist, 0, NULL);  
    float gMax=0;  
    cvGetMinMaxHistValue(gHist, NULL, &gMax, NULL, NULL);  
    IplImage* gHistImage = cvCreateImage(cvSize(histWidth, histHeight), 8, 3);  
    cvZero(gHistImage); //全部初始化为0
    for(int i = 0; i < histWidth; i++)  
    {  
        float binNum = cvQueryHistValue_1D(gHist, i); //像素i对应的点数 
        int binHeight = cvRound(binNum / gMax * histHeight);  //要绘制的高度  
        cvRectangle(gHistImage,  
            cvPoint(i, histHeight - 1),  
            cvPoint(i + 1, histHeight - binHeight),  
            CV_RGB(0, 255, 0));    
    }  

    //B通道
    cvCalcHist(&b, bHist, 0, NULL);  
    float bMax=0;  
    cvGetMinMaxHistValue(bHist, NULL, &bMax, NULL, NULL);  
    IplImage* bHistImage = cvCreateImage(cvSize(histWidth, histHeight), 8, 3);  
    cvZero(bHistImage); //全部初始化为0
    for(int i = 0; i < histWidth; i++)  
    {  
        float binNum = cvQueryHistValue_1D(bHist, i); //像素i对应的点数 
        int binHeight = cvRound(binNum / bMax * histHeight);  //要绘制的高度  
        cvRectangle(bHistImage,  
            cvPoint(i, histHeight - 1),  
            cvPoint(i + 1, histHeight - binHeight),  
            CV_RGB(0, 0, 255));    
    }  

    //对3通道直方图整合到同一张图
    IplImage* dst=cvCreateImage(cvSize(histWidth * 3, histHeight), 8, 3);  
    cvSetZero(dst);  
    CvRect rect = cvRect(0, 0, histWidth, histWidth);   
    cvSetImageROI(dst, rect);   
    cvCopy(rHistImage, dst);   

    rect = cvRect(histWidth, 0, histWidth, histHeight);  
    cvSetImageROI(dst, rect);   
    cvCopy(gHistImage, dst);  

    rect = cvRect(histWidth * 2, 0, histWidth, histHeight);  
    cvSetImageROI(dst, rect);   
    cvCopy(bHistImage, dst);  
    cvResetImageROI(dst);  
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值