欧美日韩在线第一页-欧美日韩在线观看精品-欧美日韩在线观看一区二区-欧美日韩在线免费看-欧美日韩在线视频不卡一区二区三区

圖像處理
新聞詳情

圖像處理基礎(8):圖像的灰度直方圖、直方圖均衡化、直方圖規定化(匹配)

發布時間:2021-01-14 14:41:29 最后更新:2021-01-14 15:46:47 瀏覽次數:4673

本文主要介紹了灰度直方圖相關的處理,包括以下幾個方面的內容:

?   利用OpenCV計算圖像的灰度直方圖,并繪制直方圖曲線

?   直方圖均衡化的原理及實現

?   直方圖規定化(匹配)的原理及實現

圖像的灰度直方圖

一幅圖像由不同灰度值的像素組成,圖像中灰度的分布情況是該圖像的一個重要特征。圖像的灰度直方圖就描述了圖像中灰度分布情況,能夠很直觀的展示出圖像中各個灰度級所占的多少。
圖像的灰度直方圖是灰度級的函數,描述的是圖像中具有該灰度級的像素的個數:其中,橫坐標是灰度級,縱坐標是該灰度級出現的頻率。

不過通常會將縱坐標歸一化到區間內,也就是將灰度級出現的頻率(像素個數)除以圖像中像素的總數。灰度直方圖的計算公式如下:


其中,是像素的灰度級,是具有灰度的像素的個數,是圖像中總的像素個數。

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, bool uniform = true, bool accumulate = false );

該函數能夠同時計算多個圖像,多個通道,不同灰度范圍的灰度直方圖.
其參數如下:

?   images,輸入圖像的數組,這些圖像要有相同大大小,相同的深度(CV_8U CV_16U CV_32F).

?   nimages ,輸入圖像的個數

?   channels,要計算直方圖的通道個數。

?   mask,可選的掩碼,不使用時可設為空。要和輸入圖像具有相同的大小,在進行直方圖計算的時候,只會統計該掩碼不為0的對應像素

?   hist,輸出的直方圖

?   dims,直方圖的維度

?   histSize,直方圖每個維度的大小

?   ranges,直方圖每個維度要統計的灰度級的范圍

?   uniform,是否進行歸一化,默認為true

?   accumulate,累積標志,默認值為false。

為了計算的靈活性和通用性,OpenCV的灰度直方圖提供了較多的參數,但對于只是簡單的計算一幅灰度圖的直方圖的話,又顯得較為累贅。這里對calcHist進行一次封裝,能夠方便的得到一幅灰度圖直方圖。

class Histogram1D
{
private:
    int histSize[1]; // 項的數量
    float hranges[2]; // 統計像素的最大值和最小值
    const float* ranges[1];
    int channels[1]; // 僅計算一個通道

public:
    Histogram1D()
    {
        // 準備1D直方圖的參數
        histSize[0] = 256;
        hranges[0] = 0.0f;
        hranges[1] = 255.0f;
        ranges[0] = hranges;
        channels[0] = 0;
    }

    MatND getHistogram(const Mat &image)
    {
        MatND hist;
        // 計算直方圖
        calcHist(&image ,// 要計算圖像的
            1,                // 只計算一幅圖像的直方圖
            channels,        // 通道數量
            Mat(),            // 不使用掩碼
            hist,            // 存放直方圖
            1,                // 1D直方圖
            histSize,        // 統計的灰度的個數
            ranges);        // 灰度值的范圍
        return hist;
    }

    Mat getHistogramImage(const Mat &image)
    {
        MatND hist = getHistogram(image);

        // 最大值,最小值
        double maxVal = 0.0f;
        double minVal = 0.0f;

        minMaxLoc(hist, &minVal, &maxVal);

        //顯示直方圖的圖像
        Mat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));

        // 設置最高點為nbins的90%
        int hpt = static_cast<int>(0.9 * histSize[0]);
        //每個條目繪制一條垂直線
        for (int h = 0; h < histSize[0]; h++)
        {
            float binVal = hist.at<float>(h);
            int intensity = static_cast<int>(binVal * hpt / maxVal);
            // 兩點之間繪制一條直線
            line(histImg, Point(h, histSize[0]), Point(h, histSize[0] - intensity), Scalar::all(0));
        }
        return histImg;
    }
};

Histogram1D提供了兩個方法:getHistogram返回統計直方圖的數組,默認計算的灰度范圍是[0,255];getHistogramImage將圖像的直方圖以線條的形式畫出來,并返回包含直方圖的圖像。測試代碼如下:

    Histogram1D hist;
    Mat histImg;
    histImg = hist.getHistogramImage(image);

    imshow("Image", image);
    imshow("Histogram", histImg);

其結果如下:

直方圖均衡化 Histogram Equalization

假如圖像的灰度分布不均勻,其灰度分布集中在較窄的范圍內,使圖像的細節不夠清晰,對比度較低。通常采用直方圖均衡化直方圖規定化兩種變換,使圖像的灰度范圍拉開或使灰度均勻分布,從而增大反差,使圖像細節清晰,以達到增強的目的。
直方圖均衡化,對圖像進行非線性拉伸,重新分配圖像的灰度值,使一定范圍內圖像的灰度值大致相等。這樣,原來直方圖中間的峰值部分對比度得到增強,而兩側的谷底部分對比度降低,輸出圖像的直方圖是一個較為平坦的直方圖。

均衡化算法

直方圖的均衡化實際也是一種灰度的變換過程,將當前的灰度分布通過一個變換函數,變換為范圍更寬、灰度分布更均勻的圖像。也就是將原圖像的直方圖修改為在整個灰度區間內大致均勻分布,因此擴大了圖像的動態范圍,增強圖像的對比度。通常均衡化選擇的變換函數是灰度的累積概率,直方圖均衡化算法的步驟:

?   計算原圖像的灰度直方圖 ,其中為像素總數,為灰度級的像素個數

?   計算原始圖像的累積直方圖 

?   ,其中 是目的圖像的像素,是源圖像灰度為i的累積分布,L是圖像中最大灰度級(灰度圖為255)

其代碼實現如下:

?   在上面中封裝了求灰度直方圖的類,這里直接應用該方法得到圖像的灰度直方圖;

?   將灰度直方圖進行歸一化,計算灰度的累積概率;

?   創建灰度變化的查找表

?   應用查找表,將原圖像變換為灰度均衡的圖像

具體代碼如下:

void equalization_self(const Mat &src, Mat &dst)
{
    Histogram1D hist1D;
    MatND hist = hist1D.getHistogram(src);

    hist /= (src.rows * src.cols); // 對得到的灰度直方圖進行歸一化
    float cdf[256] = { 0 }; // 灰度的累積概率
    Mat lut(1, 256, CV_8U); // 灰度變換的查找表
    for (int i = 0; i < 256; i++)
    {
        // 計算灰度級的累積概率
        if (i == 0)
            cdf[i] = hist.at<float>(i);
        else
            cdf[i] = cdf[i - 1] + hist.at<float>(i);

        lut.at(i) = static_cast(255 * cdf[i]); // 創建灰度的查找表
    }

    LUT(src, lut, dst); // 應用查找表,進行灰度變化,得到均衡化后的圖像

}

上面代碼只是加深下對均衡化算法流程的理解,實際在OpenCV中也提供了灰度均衡化的函數equalizeHist,該函數的使用很簡單,只有兩個參數:輸入圖像,輸出圖像。下圖為,上述代碼計算得到的均衡化結果和調用equalizeHist的結果對比

最左邊為原圖像,中間為OpenCV封裝函數的結果,右邊為上面代碼得到的結果。

直方圖規定化

從上面可以看出,直方圖的均衡化自動的確定了變換函數,可以很方便的得到變換后的圖像,但是在有些應用中這種自動的增強并不是最好的方法。有時候,需要圖像具有某一特定的直方圖形狀(也就是灰度分布),而不是均勻分布的直方圖,這時候可以使用直方圖規定化
直方圖規定化,也叫做直方圖匹配,用于將圖像變換為某一特定的灰度分布,也就是其目的的灰度直方圖是已知的。這其實和均衡化很類似,均衡化后的灰度直方圖也是已知的,是一個均勻分布的直方圖;而規定化后的直方圖可以隨意的指定,也就是在執行規定化操作時,首先要知道變換后的灰度直方圖,這樣才能確定變換函數。規定化操作能夠有目的的增強某個灰度區間,相比于,均衡化操作,規定化多了一個輸入,但是其變換后的結果也更靈活。

在理解了上述的均衡化過程后,直方圖的規定化也較為簡單。可以利用均衡化后的直方圖作為一個中間過程,然后求取規定化的變換函數。具體步驟如下:

?   將原始圖像的灰度直方圖進行均衡化,得到一個變換函數,其中s是均衡化后的像素,r是原始像素

?   對規定的直方圖進行均衡化,得到一個變換函數,其中v是均衡化后的像素,z是規定化的像素

?   上面都是對同一圖像的均衡化,其結果應該是相等的,,且

通過,均衡化作為中間結果,將得到原始像素規定化后像素之間的映射關系。

詳解規定化過程

對圖像進行直方圖規定化操作,原始圖像的直方圖和以及規定化后的直方圖是已知的。假設表示原始圖像的灰度概率密度,表示規定化圖像的灰度概率密度(r和z分別是原始圖像的灰度級,規定化后圖像的灰度級)。

?   對原始圖像進行均衡化操作,則有

?   對規定化的直方圖進行均衡化操作,則

?   由于是對同一圖像的均衡化操作,所以有

?   規定化操作的目的就是找到原始圖像的像素到規定化后圖像像素的之間的一個映射。有了上一步的等式后,可以得到,因此要想找到相對應的只需要在進行迭代,找到使式子的絕對值最小即可。

?   上述描述只是理論的推導過程,在實際的計算過程中,不需要做兩次的均衡化操作,具體的推導過程如下:$$



文章轉自Brook_icv   https://www.cnblogs.com/wangguchangqing/p/7098213.html

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13310869691
主站蜘蛛池模板: 国产日韩不卡免费精品视频| 精品日韩二区三区精品视频| 色婷婷六月丁香在线观看| a级黄色大片在线观看视频男男| 日韩欧美一区二区精品久久| 成人精品国产亚洲欧洲| 国产91色拍| 国产原创在线观看| 综合久久91| www.久久精品| 国产亚洲精品久久久极品美女 | 亚洲第一页中文字幕| 欧美一级亚洲一级| 国产区香蕉精品系列在线观看不卡| 看一级特黄a大一片| 韩国一级黄色| 露脸在线| 国产麻豆高清视频在线第一页| 免费网站在线看| 色天天色综合| 亚洲成人自拍| 亚洲日韩欧美视频| 1000日本xxxxxxxxx25| xxxxchina麻豆免费视频| 小明台湾成人永久免费看看| 日本毛片大全| 日本特黄特色免费大片| 午夜亚洲国产| 丝袜无码一区二区三区| 亚洲精品色综合区| 成人免费小视频| 成年大片免费播放视频人| 免费的黄色毛片| 青青久操| 免费在线看黄网址| 欧美一级毛片不卡免费观看| 欧美国产日韩911在线观看| 国产a级三级三级三级| 国产一级毛片午夜| 国产二区自拍| 国内一级一级毛片a免费|