精华内容
下载资源
问答
  • OpenCV图像直方图

    千次阅读 2019-03-28 08:28:53
    OpenCV图像直方图 微信公众号:幼儿园的学霸 个人的学习笔记,关于OpenCV,关于机器学习, …。问题或建议,请公众号留言; 灰度直方图(Histogram)是数字图像处理中最简单、最有用的工具之一,它概括了一幅图像的灰度...

    OpenCV图像直方图

    微信公众号:幼儿园的学霸
    个人的学习笔记,关于OpenCV,关于机器学习, …。问题或建议,请公众号留言;

    灰度直方图(Histogram)是数字图像处理中最简单、最有用的工具之一,它概括了一幅图像的灰度级内容此处对直方图的数学原理以及OpenCV中的示例进行了展示。

    目录

    定义

    灰度直方图(histogram)是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率。横坐标是灰度级,纵坐标是灰度级出现的频率(对数字图像来说,意味着该灰度级像素的个数)。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aCUnuoVx-1611394568988)(https://s2.ax1x.com/2019/03/05/kjGWm4.png)]
    灰度直方图示例

    过通常会将纵坐标归一化到[0,1]区间内,也就是将灰度级出现的频率(像素个数)除以图像中像素的总数。

    对于连续图像,平滑地从中心的高灰度级变化到边缘的低灰度级。直方图定义为:
    H ( D ) = lim ⁡ Δ D → 0 A ( D ) − A ( D + Δ D ) Δ D = − d Δ D A ( D ) − − − − − ( 1 ) H(D) = \lim_{\Delta D \rightarrow0}\frac{A(D)-A(D+\Delta D)}{\Delta D} = -\frac{d}{\Delta D}A(D)-----(1) H(D)=ΔD0limΔDA(D)A(D+ΔD)=ΔDdA(D)(1)
    其中 A ( D ) A(D) A(D)为阈值面积函数:为一幅连续图像中被具有灰度级D的所有轮廓线所包围的面积。
    上式说明,一幅连续图像的直方图是其面积函数的导数的负值。
    若将图像看成是二维随机变量,则面积函数相当于其累计分布函数,灰度直方图相当于其概率密度函数。

    根据上式介绍的对直方图的定义,对公式进行积分:
    ∫ D ∞ H ( D ) d D = [ − A ( D ) ] D ∞ = A ( D ) \int^\infty_D H(D)dD = [-A(D)]^\infty_D = A(D) DH(D)dD=[A(D)]D=A(D)
    即为图像总面积。
    对于离散图像:
    ∑ 0 255 = N L ∗ N S = t h e . t o t a l . p i x e l ′ s . o f . i m a g e \sum^{255}_0 = NL * NS = the.total.pixel's.of.image 0255=NLNS=the.total.pixels.of.image
    即为图像总的像素数。

    回到式(1),对于离散函数,固定 Δ D \Delta D ΔD为1,则:
    H ( D ) = A ( D ) − A ( D + 1 ) H(D)=A(D)-A(D+1) H(D)=A(D)A(D+1)
    显然:对数字图像,任一灰度级D的面积函数就是大于或等于灰度级D的像素的个数。灰度直方图的计算公式如下:
    p ( r k ) = n k M ∗ N p(r_k) = \frac{n_k}{M*N} p(rk)=MNnk
    其中, r k r_k rk是像素的灰度级, n k n_k nk是具有灰度级 r k r_k rk的像素的个数, M , N M,N M,N是图像中总的像素个数。

    直方图的绘制

    1) 将图像的灰度归一化
    若图像的灰度级为0,1,……,L-1,令
    r k = k L − 1 , k = 0 , 1 , ⋯   , L − 1 r_k = \frac{k}{L-1},k=0,1,\cdots,L-1 rk=L1k,k=0,1,,L1
    0 ≤ r k ≤ 1 0≤r_k≤1 0rk1,L为灰度级的层数, Δ L k = r k + 1 − r k \Delta L_k = r_{k+1}-r_k ΔLk=rk+1rk为灰度间隔。
    2)计算各灰度级的像素频数(或概率
    n k n_k nk表示灰度级为 r k r_k rk的像素的个数, N N N为总的像素个数,计算像素频数的公式为:
    p r ( r k ) = n k N p_r(r_k) = \frac{n_k}{N} pr(rk)=Nnk
    3)作图
    建立直角坐标系,横轴表示灰度级 r k r_k rk的取值,纵轴表示灰度级对应的概率 p r ( r k ) p_r(r_k) pr(rk)

    下面为对一幅10X10的图像求其8级灰度直方图的示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rkZgcZhF-1611394568996)(https://s2.ax1x.com/2019/03/06/kvS3VA.png)]

    直方图的性质

    1)图像被缩减成直方图后,所有的空间信息都丢失了,也就是说,直方图不能提供像素在图像中的位置信息。因此不同的图像可以有相同的直方图。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Q7jMY3i-1611394568997)(https://s2.ax1x.com/2019/03/05/kj1rY6.png)]

    2)如果一幅图像包含一个灰度均匀一致的物体,且背景与物体的对比度很强,规定物体的边界时由灰度级$D_1$定义的轮廓线。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbWRkxJH-1611394568999)(https://s2.ax1x.com/2019/03/06/kvSoI1.png)]
    3)如果一幅图像由几个连接但不交叠(当然也不能有遗漏)的区域组成,每个区域的直方图已知,则整个图像的直方图是该几个区域的直方图之和。

    直方图的应用

    在使用轮廓线确定物体边界时,通过直方图更好的选择边界阈值,进行阈值化处理;对物体与背景有较强对比的景物的分割特别有用;简单物体的面积和综合光密度IOD可以通过图像的直方图求得。
    1)数字化参数
    可用来判断一幅图像是否合理地利用了全部被允许的灰度级范围。一幅图像应利用几乎全部的灰度级。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ESC98TgW-1611394569002)(https://s2.ax1x.com/2019/03/06/kvpAsg.png)]
    2)边界阈值选取
    1°确立图像中简单物体的边界,用于物体与背景有较强对比时的景物分割
    2°阈值化:使用轮廓线作为边界的技术
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SgFki1Iq-1611394569003)(https://s2.ax1x.com/2019/03/06/kvpJeJ.png)]

    OpenCV计算并绘制灰度直方图

    函数声明

    直方图的计算是很简单的,无非是遍历图像的像素,统计每个灰度级的个数。在OpenCV中封装了直方图的计算函数calcHist,为了更为通用,该函数的参数有些复杂,其声明如下:

    calcHist(
    const Mat* images,//输入图像的数组,这些图像要有仙童大小、深度(CV_8U,CV_16U,CV_32F)
    int images,// 图像数目
    const int* channels,// 通道数,要计算的通道数的下标,可以传一个数组 {0, 1} 表示计算第0通道与第1通道的直方图,此数组长度要与histsize ranges 数组长度一致
    InputArray mask,//输入mask,可选。如有,则表示只计算mask元素值为非0的位置的直方图
    OutputArray hist,//输出的直方图数据
    int dims,// 直方图的维度
    const int* histsize,//在每一维上直方图的个数。
                    //简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。
    const float* ranges,// 直方图每个维度要统计的灰度级的范围
    bool uniform,// true by default 是否归一化
    bool accumulate// false by defaut
    )
    
    

    代码演示

    下面这段代码展示了利用calcHist函数计算直方图,及动态调整直方图“竖条”的个数的过程。

    //====================================================================//
    // Created by liheng on 19-3-6.
    //Program:图像灰度直方图示例,及动态调整“竖条”数量,观察直方图效果
    //Data:2019.3.6
    //Author:liheng
    //Version:V1.0
    //====================================================================//
    
    #include <opencv2/opencv.hpp>
    
    
    cv::Mat src;//需要计算直方图的灰度图像
    cv::Mat histimg;//进行直方图展示的图
    cv::MatND hist;//计算得到的直方图结果
    
    int histSize = 50;     // 划分HIST的初始个数,越高越精确
    
    //滚动条函数
    void HIST(int t,void*)
    {
        char string[10];
    
        if(histSize==0)
        {
            printf("直方图条数不能为零!\n");
        }
        else
        {
            int dims = 1;
            float hranges[2] = {0, 255};
            const float *ranges[1] = {hranges};   // 这里需要为const类型
            int channels = 0;
    
            histimg.create(512,256*4,CV_8UC3);
            histimg.setTo(cv::Scalar(0,0,0));
    
            //计算图像的直方图
            calcHist(&src, 1, &channels, cv::Mat(), hist, dims, &histSize, ranges);    // cv 中是cvCalcHist
            //normalize(hist, hist, 0, histimg.rows*0.5, NORM_MINMAX, -1, Mat());//将直方图归一化,防止某一条过高,显示不全
    
    
            double maxVal = 0;
            cv::Point maxLoc;
            cv::minMaxLoc(hist, NULL, &maxVal, NULL, &maxLoc);//寻找最大值及其位置
    
    
            double bin_w =(double) histimg.cols / histSize;  // histSize: 条的个数,则 bin_w 为条的宽度
            double bin_u = (double)histimg.rows/ maxVal;  // maxVal: 最高条的像素个数,则 bin_u 为单个像素的高度
    
            // 画直方图
            for(int i=0;i<histSize-1;i++)
            {
                cv::Point p0=cv::Point(i*bin_w,histimg.rows);
    
                float binValue = hist.at<float>(i);           //   注意hist中是float类型
                cv::Point p1=cv::Point((i+1)*bin_w,histimg.rows-binValue*bin_u);
    
                cv::rectangle(histimg,p0,p1,cv::Scalar(0,255,0),2,8,0);
            }
    
            //曲线形式的直方图
            for (int i = 0; i < histSize; i++)
            {
                cv::line(histimg,
                        cv::Point(bin_w*i+bin_w/2, histimg.rows-hist.at<float>(i)*bin_u),
                        cv::Point(bin_w*(i+1)+bin_w/2, histimg.rows-hist.at<float>(i+1)*bin_u),
                        cv::Scalar(255, 0, 0), 2, 8, 0);//bin_w/2是为了保证折现位于直方图每条的中间位置
            }
    
            //画纵坐标刻度(像素个数)
            int kedu=0;
            for(int i=1;kedu<maxVal;i++)
            {
                kedu=i*maxVal/10;
                sprintf(string,"%d",kedu);//把一个整数转换为字符串
                //在图像中显示文本字符串
                cv::putText(histimg, string , cv::Point(0,histimg.rows-kedu*bin_u), cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0,255,255),1);
    
                cv::line( histimg,cv::Point(0,histimg.rows-kedu*bin_u),cv::Point(histimg.cols-1,histimg.rows-kedu*bin_u),cv::Scalar(0,0,255));
            }
            //画横坐标刻度(像素灰度值)
            kedu=0;
            for(int i=1;kedu<256;i++)
            {
                kedu=i*20;
                sprintf(string,"%d",kedu);//把一个整数转换为字符串
                //在图像中显示文本字符串
                putText(histimg, string , cv::Point(kedu*(histimg.cols / 256),histimg.rows), cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0,255,255),2);
            }
    
            cv::imshow( "Histogram", histimg );
        }
    }
    
    int main( int argc, char** argv )
    {
    
        src = cv::imread("../pictures/lena.jpg",0);
    
        cv::namedWindow( "src", 1);
        cv::imshow( "src", src);
        cv::namedWindow( "Histogram", 1 );
    
        int maxvalue = 256;
        cv::createTrackbar( "histSize", "src", &histSize, maxvalue, HIST );
        HIST(0,0);
        cv::waitKey(0);
    
        cv::destroyWindow("src");
        cv::destroyWindow("Histogram");
    
        return 0;
    }
    

    运行效果如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SdkKCJ7o-1611394569004)(https://s2.ax1x.com/2019/03/06/kvujOA.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i6GKgPkP-1611394569005)(https://s2.ax1x.com/2019/03/06/kvKB1e.png)]

    扩展

    利用直方图,还可以对图像进行直方图均衡化和规范化的操作。

    直方图均衡化

    大多数自然图像,其灰度分布集中在较窄的区间,引起图像细节不够清晰,采用直方图修正后可使图像的灰度间距拉开或使灰度分布均匀,从而增大反差,使图像细节清晰,达到增强的目的。例如一幅过曝光的图片,其灰度级都集中在高亮度范围内,而曝光不足的图片,其灰度集中在低亮度范围内,具有这样直方图的图片其可视效果比较差。
    直方图均衡化方法的基本思想是,对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。从而达到清晰图像的目的,增强图像的整体对比度。
    其基本处理思路是,把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。即在每个灰度级上都具有相同像素点数的过程。

    直方图规范化

    直方图均衡化的优点是能自动增强整个图像的对比度,但它的具体增强效果不易控制,处理的结果总是得到全局的均衡化的直方图。实际工作中,有时需要变换直方图使之成为某个特定的形状,从而有选择地增强某个灰度值范围内的对比度,这时可采用比较灵活的直方图规定化方法。
    直方图规范化是指将一幅图像通过灰度转换后,使其具有特定的直方图形式,如使图像与某一标准图像具有相同的直方图,或使图像具有某一特定函数形式的直方图。



    下面的是我的公众号二维码图片,欢迎关注。
    图注:幼儿园的学霸

    展开全文
  • opencv图像直方图对比

    2015-07-04 17:14:38
    利用OpenCV实现了四种方法的两张图像直方图的对比
  • opencv 图像直方图 calcHist

    千次阅读 2016-03-07 09:58:43
    图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。 图像是由像素构成,因为...

    图像直方图的概念

    图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。

    图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。在实际工程中,图像直方图在特征提取、图像匹配等方面都有很好的应用。

    利用OpenCV计算图像的直方图

    OpenCV中计算图像直方图像函数是calcHist,它的参数比较多,下面分析一下它的接口和用法。

    void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, booluniform=true, bool accumulate=false )

    const Mat* images:为输入图像的指针。

    int nimages:要计算直方图的图像的个数。此函数可以为多图像求直方图,我们通常情况下都只作用于单一图像,所以通常nimages=1。

    const int* channels:图像的通道,它是一个数组,如果是灰度图像则channels[1]={0};如果是彩色图像则channels[3]={0,1,2};如果是只是求彩色图像第2个通道的直方图,则channels[1]={1};

    IuputArray mask:是一个遮罩图像用于确定哪些点参与计算,实际应用中是个很好的参数,默认情况我们都设置为一个空图像,即:Mat()。

    OutArray hist:计算得到的直方图

    int dims:得到的直方图的维数,灰度图像为1维,彩色图像为3维。

    const int* histSize:直方图横坐标的区间数。如果是10,则它会横坐标分为10份,然后统计每个区间的像素点总和。

    const float** ranges:这是一个二维数组,用来指出每个区间的范围。

    后面两个参数都有默认值,uniform参数表明直方图是否等距,最后一个参数与多图像下直方图的显示与存储有关。

    OpenCV直方图例子

    灰度直方图

    int main()
    {
        Mat Image=imread("../cat.png");
        cvtColor(Image,Image,CV_BGR2GRAY);
     
        const int channels[1]={0};
        const int histSize[1]={256};
        float hranges[2]={0,255};
        const float* ranges[1]={hranges};
        MatND hist;
        calcHist(&Image,1,channels,Mat(),hist,1,histSize,ranges);
     
        return 0;
    }

    彩色直方图

    int main()
    {
        Mat Image=imread("../cat.png");
     
        const int channels[3]={0,1,2};
        const int histSize[3]={256,256,256};
        float hranges[2]={0,255};
        const float* ranges[3]={hranges,hranges,hranges};
        MatND hist;
        calcHist(&Image,1,channels,Mat(),hist,3,histSize,ranges);
     
        return 0;
    }

    不均匀(自定义区间)直方图

    我们分别统计0-50,50-80,80-150,150-230,230-255区间的灰度分布
    int main()
    {
        Mat Image=imread("../cat.png");
        cvtColor(Image,Image,CV_BGR2GRAY);
     
        const int channels[1]={0};
        int histSize[1]={5};
        float hranges[6]={0,50,80,150,230,255};
        const float* ranges[1]={hranges};
     
        MatND hist;
        calcHist(&Image,1,channels,Mat(),hist,1,histSize,ranges,false);
     
        return 0;
    }

    直方图的显示

    Mat getHistImg(const MatND& hist)
    {
        double maxVal=0;
        double minVal=0;
     
        
    //找到直方图中的最大值和最小值
        minMaxLoc(hist,&minVal,&maxVal,0,0);
        int histSize=hist.rows;
        Mat histImg(histSize,histSize,CV_8U,Scalar(255));
        
    // 设置最大峰值为图像高度的90%
        int hpt=static_cast<int>(0.9*histSize);
     
        for(int h=0;h<histSize;h++)
        {
            float binVal=hist.at<float>(h);
            int intensity=static_cast<int>(binVal*hpt/maxVal);
            line(histImg,Point(h,histSize),Point(h,histSize-intensity),Scalar::all(0));
        }
     
        return histImg;
    }



    展开全文
  • opencv 图像直方图

    2017-12-19 15:13:30
    图像直方图

    图像直方图

      要理解直方图,绕不开“亮度”这个概念。人们把照片的亮度分为0到255共256个数值,数值越大,代表的亮度越高。其中0代表纯黑色的最暗区域,255表示最亮的纯白色,而中间的数字就是不同亮度的灰色。

    这里写图片描述

      当我们用横轴代表0-255的亮度数值。竖轴代表照片中对应亮度的像素数量,这个函数图像就被称为直方图。直方图中柱子的高度,代表了画面中有多少像素是那个亮度,其实就可以看出来画面中亮度的分布和比例。比如下面一个直方图,波峰是在中间偏左的位置(阴影区域),说明画面中有很多深灰或者深色部分。
    图像直方图在opencv中的实现为:

    #include "stdafx.h"
    #include<opencv2\highgui\highgui.hpp>
    #define cvQueryHistValue_1D( hist, idx0 )  ((float)cvGetReal1D((hist)->bins, (idx0)))
    
    
    int main()
    {
        IplImage * src = cvLoadImage("13.jpg");
        cvSetImageROI(src, cvRect(0, src->height / 2, src->width, src->height / 2));
        IplImage* gray_plane = cvCreateImage(cvGetSize(src), 8, 1);
        cvCvtColor(src, gray_plane, CV_BGR2GRAY);
    
        int hist_size = 256;    //直方图尺寸  
        int hist_height = 256;
        float range[] = { 0, 255 };  //灰度级的范围  
        float* ranges[] = { range };
        float AreaSum1=0, AreaSum2=0;
        //创建一维直方图,统计图像在[0 255]像素的均匀分布  
        CvHistogram* gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
        //计算灰度图像的一维直方图  
        cvCalcHist(&gray_plane, gray_hist, 0, 0);
        //归一化直方图  
        cvNormalizeHist(gray_hist, 1.0);
    
        int scale = 2;
        //创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数(*scale)  
        IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale, hist_height), 8, 3);
        cvZero(hist_image);
        //统计直方图中的最大直方块  
        float max_value = 0;
        cvGetMinMaxHistValue(gray_hist, 0, &max_value, 0, 0);
    //  printf("最大值:%f",max_value);
    
        //分别将每个直方块的值绘制到图中  
        for (int i = 0; i<hist_size; i++)
        {
            float bin_val = cvQueryHistValue_1D(gray_hist, i); //像素i的概率  
            int intensity = cvRound(bin_val*hist_height / max_value);  //要绘制的高度  
            cvRectangle(hist_image,
                cvPoint(i*scale, hist_height - 1),
                cvPoint((i + 1)*scale - 1, hist_height - intensity),
                CV_RGB(255, 255, 255));
            if (i> 35 && i<85){
                AreaSum1 += intensity;
            }
            if(i>120 && i<170){
                AreaSum2 += intensity;
            }
            printf("像素%d对应的高度:%d\n",i,intensity);
        }
        printf("AreaSum1 = %f\n", AreaSum1);
        printf("AreaSum1 = %f\n", AreaSum2);
        cvNamedWindow("GraySource", 1);
        cvShowImage("GraySource", gray_plane);
        cvNamedWindow("H-S Histogram", 1);
        cvShowImage("H-S Histogram", hist_image);
    
        cvWaitKey(0);
    }

    如图所示为直方图的结果:

    这里写图片描述
    这里写图片描述

    展开全文
  • opencv 图像直方图绘制

    千次阅读 2017-04-21 11:40:08
    使用 OpenCV 或 Numpy 函数计算直方图 使用 Opencv 或者 Matplotlib 函数绘制直方图 将要学习的函数有: cv2.calcHist(), np.histogram()

    目标
    • 使用 OpenCV 或 Numpy 函数计算直方图
    • 使用 Opencv 或者 Matplotlib 函数绘制直方图
    • 将要学习的函数有: cv2.calcHist(), np.histogram()
    原理
      什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255), y 轴是图片中具有同一个灰度值的点的数目。
      直方图其实就是对图像的另一种解释。一下图为例,通过直方图我们可以对图像的对比度,亮度,灰度分布等有一个直观的认识。几乎所有的图像处理软件都提供了直方图分析功能。下图来自Cambridge in Color website,强烈推荐你到这个网站了解更多知识
        这里写图片描述
      让我们来一起看看这幅图片和它的直方图吧。 (要记住,直方图是根据灰度图像绘制的,而不是彩色图像)。直方图的左边区域像是了暗一点的像素数量,右侧显示了亮一点的像素的数量。从这幅图上你可以看到灰暗的区域比两的区域要大,而处于中间部分的像素点很少。

    1、 统计直方图

      现在我们知道什么是直方图了,那怎样获得一副图像的直方图呢?OpenCV 和 Numpy 都有内置函数做这件事。在使用这些函数之前我们有必要想了解一下直方图相关的术语。
    BINS: 上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到 255,就需要 256 个数来显示上面的直方图。但是,如果不需要知道每一个像素值的像素点数目的,而只希望知道两个像素值之间的像素点数目怎么办呢?举例来说,我们想知道像素值在 0 到 15 之间的像素点的数目,接着是 16 到 31,…., 240 到 255。我们只需要 16 个值来绘制直方图。 OpenCV Tutorials on histograms中例子所演示的内容。那到底怎么做呢?你只需要把原来的 256 个值等分成 16 小组,取每组的总和。而这里的每一个小组就被成为 BIN。第一个例子中有 256 个 BIN,第二个例子中有 16 个 BIN。在 OpenCV 的文档中用 histSize 表示 BINS。
    DIMS:表示我们收集数据的参数数目。在本例中,我们对收集到的数据
    只考虑一件事:灰度值。所以这里就是 1。
    RANGE:就是要统计的灰度值范围,一般来说为 [0, 256],也就是说所
    有的灰度值
    使用 OpenCV 统计直方图 函数 cv2.calcHist 可以帮助我们统计一幅图像的直方图。我们一起来熟悉一下这个函数和它的参数:
    cv2:calcHist(images; channels; mask; histSize; ranges[; hist[; accumulate]])
    images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该用中括号 [] 括起来,例如: [img]。
    channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0], [1], [2] 它们分别对应着通道 B, G, R。
    mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
    histSize:BIN 的数目。也应该用中括号括起来,例如: [256]。
    ranges: 像素值范围,通常为 [0, 256]
    让我们从一副简单图像开始吧。以灰度格式加载一幅图像并统计图像的直图。

    img = cv2.imread('home.jpg',0)
    hist = cv2.calcHist([img],[0],None,[256],[0,256])

    hist 是一个 256x1 的数组,每一个值代表了与次灰度值对应的像素点数目。
    使用 Numpy 统计直方图 Numpy 中的函数 np.histogram() 也可以帮
    我们统计直方图。你也可以尝试一下下面的代码:

    hist,bins = np.histogram(img.ravel(),256,[0,256])

    hist 与上面计算的一样。但是这里的 bins 是 257,因为 Numpy 计算bins 的方式为: 0-0.99,1-1.99,2-2.99 等。所以最后一个范围是 255-255.99。为了表示它,所以在 bins 的结尾加上了 256。但是我们不需要 256,到 255就够了。
    其 他: Numpy 还 有 一 个 函 数 np.bincount(), 它 的 运 行 速 度 是np.histgram 的 十 倍。 所 以 对 于 一 维 直 方 图, 我 们 最 好 使 用 这 个函 数。 使 用 np.bincount 时 别 忘 了 设 置 minlength=256。 例 如,hist=np.bincount(img.ravel(), minlength=256)
    注意: OpenCV 的函数要比 np.histgram() 快 40 倍。所以坚持使用OpenCV 函数。

    2、绘制直方图

    有两种方法来绘制直方图:
    1. Short Way(简单方法):使用 Matplotlib 中的绘图函数。
    2. Long Way(复杂方法):使用 OpenCV 绘图函数
    使用 Matplotlib Matplotlib 中有直方图绘制函数:matplotlib.pyplot.hist()它可以直接统计并绘制直方图。你应该使用函数 calcHist() 或 np.histogram()统计直方图。代码如下:

    import cv2
    import numpy as np 
    from matplotlib import pyplot as plt 
    
    img = cv2.imread('image/lufei.jpeg',0)
    plt.hist(img.ravel(),255,[0,256]);
    plt.title("Matplotlib Method")
    plt.show()

    这里写图片描述这里写图片描述
    或者你可以只使用 matplotlib 的绘图功能, 这在同时绘制多通道(BGR)
    的直方图,很有用。但是你首先要告诉绘图函数你的直方图数据在哪里。运行
    一下下面的代码:

    import cv2
    import numpy as np 
    from matplotlib import pyplot as plt 
    
    img = cv2.imread('image/lufei.jpeg')
    color = ('b','g','r')
    for i,col in enumerate(color):
        histr = cv2.calcHist([img], [i], None, [256], [0,256])
        plt.plot(histr,color = col)
        plt.xlim([0,256])
    plt.title("Matplotlib color Method")
    plt.show()

    结果图:
    这里写图片描述
    使用 OpenCV 使用 OpenCV 自带函数绘制直方图比较麻烦,这里不作介
    绍,有兴趣可以自己研究。可以参考 OpenCV-Python2 的官方示例。

    3、使用掩模

      要统计图像某个局部区域的直方图只需要构建一副掩模图像。将要统计的部分设置成白色,其余部分为黑色,就构成了一副掩模图像。然后把这个掩模图像传给函数就可以了。

    import cv2
    import numpy as np 
    from matplotlib import pyplot as plt 
    
    img = cv2.imread('image/lufei.jpeg',0)
    mask = np.zeros(img.shape[:2],np.uint8)
    mask[100:300,100:400] = 255
    masked_img = cv2.bitwise_and(img, img,mask = mask)
    hist_full = cv2.calcHist([img], [0], None, [256], [0,256])
    hist_mask = cv2.calcHist([img], [0], mask, [256], [0,256])
    
    plt.subplot(221),plt.imshow(img,'gray')
    plt.subplot(222),plt.imshow(mask,'gray')
    plt.subplot(223),plt.imshow(masked_img,'gray')
    plt.subplot(224),plt.plot(hist_full),plt.plot(hist_mask)
    plt.xlim([0,256])
    plt.show()

    结果图:
    这里写图片描述
    蓝线是整幅图像的直方图,绿线是进行掩模之后的直方图。

    参考:OpenCV官方教程中文版(For Python)

    展开全文
  • OpenCV图像灰度直方图

    2019-11-01 10:04:01
    OpenCV计算图像灰度直方图,绘制图像灰度直方图灰度分布
  • openCV 图像直方图

    2014-06-07 18:01:57
    //创建一维直方图,统计图像在[0 255]像素的均匀分布 CvHistogram* gray_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1); //计算灰度图像的一维直方图 cvCalcHist(&gray_plane,gray_hist,0,0); ...
  • OpenCV 图像直方图计算calcHist()

    千次阅读 2019-01-07 11:32:49
    图像直方图是对数据集合的一种统计方法,将统计结果分布于一系列预定义的bin中,bin是直方图中经常用到的一个概念,其数值是从数据中计算出的特征统计量,这些数据不仅仅指的灰度值,统计数据可能是任何能有效描述...
  • 图像直方图的基本概念: 统计各个灰度级别在图像中的出现次数或概率,并用直方图显示出来,一般直方图显示图像数据时会以左暗又亮的分布曲线形式呈现出来。 且具有图像平移、旋转、缩放不变性等众多优点,直方图在...
  • opencv图像直方图的计算及绘制

    万次阅读 2017-01-29 13:32:53
    OpenCV 中提供了 calcHist 函数来计算图像直方图,其函数原型是: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const ...
  • 本篇文章主要讲解灰度直方图的基本概念,Python调用OpenCV实现绘制图像直方图,基础性知识希望对您有所帮助。 1.灰度直方图基本概率 2.绘制直方图 3.使用OpenCV统计绘制直方图
  • OpenCv生成图像直方图

    2021-01-04 00:00:18
    数字图像直方图(一维和二维直方图生成) 参考博客:http://blog.csdn.net/xiaowei_cqu/article/details/7600666
  • 主要为大家详细介绍了Python OpenCV处理图像之图像直方图和反向投影,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 直方图均衡化图像增强算法,借鉴github
  • 基于opencv图像直方图显示与直方图均衡 下载必看: 1.程序默认处理的是灰度图像,彩色图像将转换成灰度图处理 2.程序基于opencv2.2的c++ API编写,编译前确保你配置的是opencv2.x环境,1.0没试过。
  • 直方图 ...opencv库计算直方图 使用 cv.calcHist(images, channels, mask, histSize, ranges) 计算,其中: 参数1:要计算的原图,以方括号的形式传入,如:[img] 参数2:选择图像的某个通道,计算直...
  • 彩色图像直方图和灰度图像直方图的原理是一样的,不同的是彩色图像需要分别计算BGR三个通道。 Cerasus.JPG import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('Cerasus.JPG', 1...
  • python与opencv进行图像处理基础总结,图像直方图的绘制;直方图应用,利用直方图均衡化可以实现增强图像对比度的效果,还可以利用直方图比较来对比两张图像相似度;直方图反向投影,用于图像分割或查找图像中感兴趣...
  • 同学们自己配代码里边的图片,此程序可以在图像库中挑出和原始图片直方图类似的那些图

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,830
精华内容 7,532
关键字:

opencv图像直方图分布