zoukankan      html  css  js  c++  java
  • 8.直方图

    一.直方图

    简单的说灰度直方图就是:一幅图像中灰度级与出现这种灰度的概率之间关系的图形,灰度直方图是一种统计表达,反映了不同灰度级出现的统计概率(个数),其横坐标是:灰度级,纵坐标是:出现的个数(概率)。
    (1)直方图的离散函数 h(rk)=nk。其中rk是第K级的灰度值,nk是图像中灰度为rk的像素的个数。
    (2)归一化直方图 p(rk)=nk/MN。其中k = 0,1,2.....L-1(灰度级的范围是[ 0 , L-1]),MN表示像素的总的个数。
    算法实现:
    Mat histogram_normalization(Mat& img, int a, int b)
    {
        int width = img.cols;
        int height = img.rows;
        int channel = img.channels();
    
        int c = 0, d = 0; //图片灰度阈值
        int val;
        Mat out = Mat::zeros(height, width, CV_8UC3);
    
        //get c, d
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                for (int _c = 0; _c < channel; _c++)
                {
                    val = (float)img.at<Vec3b>(y, x)[_c];
                    c = fmin(val, c);
                    d = fmax(val, d);
                }
            }
        }
    
        // histogram transformation
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                for (int _c = 0; _c < 3; _c++)
                {
                    val = (float)img.at<Vec3b>(y, x)[_c];
                    if (val < a)
                        out.at<Vec3b>(y, x)[_c] = (uchar)a;
                    else if (val >= c && val < d)
                        out.at<Vec3b>(y, x)[_c] = (uchar)(b - a) / (d - c)*(val - c) + a;
                    else
                        out.at<Vec3b>(y, x)[_c] = (uchar)b;
                }
            }
        }
        return out;
    }

    二. 直方图操作

     这种操作不能将图像灰度等级分布在整个灰度区域,但可以提高对比度。

     算法实现:

     1 cv::Mat histogram_transform(cv::Mat img, int m0, int s0)
     2 {
     3     // get height and width
     4     int width = img.cols;
     5     int height = img.rows;
     6     int channel = img.channels();
     7     cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);
     8     double val = 0;
     9     double sum = 0.0, squared_sum = 0.0;
    10     for (int y = 0; y < height; y++)
    11     {
    12         for (int x = 0; x < width; x++)
    13         {
    14             for (int c = 0; c < channel; c++)
    15             {
    16                 val = (float)img.at<Vec3b>(y, x)[c];
    17                 sum += val;
    18                 squared_sum += (val * val);
    19             }
    20         }
    21     }
    22     double m, sigma;
    23     //期望
    24     m = sum / (height*width*channel);
    25     //标准差
    26     sigma = sqrt(squared_sum / (height*width*channel) - m * m);
    27 
    28     cout << "期望 : " << m << endl;
    29     cout<<"标准差"<< sigma<<endl;
    30     // histogram transformation
    31     for (int y = 0; y < height; y++)
    32     {
    33         for (int x = 0; x < width; x++)
    34         {
    35             for (int c = 0; c < channel; c++)
    36             {
    37                 val = img.at<Vec3b>(y, x)[c];
    38                 out.at<Vec3b>(y, x)[c] = (uchar)(s0 / sigma * (val - m) + m0);
    39             }
    40 
    41         }
    42     }
    43     return out;
    44 }

    三、均衡化

     算法实现:

     1 // histogram equalization
     2 cv::Mat histogram_equalization(cv::Mat img)
     3 {
     4     // get height and width
     5     int width = img.cols;
     6     int height = img.rows;
     7     int channel = img.channels();
     8 
     9     // output image
    10     cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);
    11 
    12     // histogram equalization hyper-parameters
    13     double Zmax = 255;
    14     double hist[255] = { 0 };
    15     double S = height * width*channel;
    16     int val = 0;
    17     //统计像素个数
    18     for (int y = 0; y < height; y++)
    19     {
    20         for (int x = 0; x < width; x++)
    21         {
    22             for (int c = 0; c < channel; c++)
    23             {
    24                 val = (int)img.at<cv::Vec3b>(y, x)[c];
    25                 hist[val]++;
    26             }
    27         }
    28     }
    29 
    30     double hist_sum = 0;
    31     //均衡化处理
    32     for (int y = 0; y < height; y++)
    33     {
    34         for (int x = 0; x < width; x++)
    35         {
    36             for (int c = 0; c < channel; c++)
    37             {
    38                 val = (int)img.at<cv::Vec3b>(y, x)[c];
    39                 hist_sum = 0;
    40                 for (int k = 0; k < val; k++)
    41                 {
    42                     hist_sum += hist[k];
    43                 }
    44                 out.at<cv::Vec3b>(y, x)[c] = (uchar)(Zmax / S * hist_sum);
    45             }
    46         }
    47     }
    48     

     四、算法推到

       https://blog.csdn.net/u013355826/article/details/57417771 

  • 相关阅读:
    临时禁用大型列表上的列表视图阈值
    临时禁用大型列表上的列表视图阈值
    SharePoint Foundation 2010 托管客户端对象模型概述 创建 Windows 控制台托管的客户端对象模型应用程序
    如何隐藏MOSS2010的网站操作菜单
    MOSS2010的列表视图参数设置以及列表记录样式设置
    使用SharePoint Server 2010搜索PDF文档
    Sharepoint2010如何使用Linq to Sharepoint
    水晶報表字段超鏈結4/28
    4月21自考4/23
    [轉]統籌方法華羅庚
  • 原文地址:https://www.cnblogs.com/xingyuanzier/p/13283157.html
Copyright © 2011-2022 走看看