久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

OpenCV成長(zhǎng)之路(4):圖像直方圖 - 博客 - 伯樂在線

 mzsm 2015-02-22
原文出處: Ronny 的博客(@RonnyYoung)   歡迎分享原創(chuàng)到伯樂頭條

一,、圖像直方圖的概念

圖像直方圖是反映一個(gè)圖像像素分布的統(tǒng)計(jì)表,其實(shí)橫坐標(biāo)代表了圖像像素的種類,,可以是灰度的,,也可以是彩色的??v坐標(biāo)代表了每一種顏色值在圖像中的像素總數(shù)或者占所有像素個(gè)數(shù)的百分比,。

圖像是由像素構(gòu)成,,因?yàn)榉从诚袼胤植嫉闹狈綀D往往可以作為圖像一個(gè)很重要的特征,。在實(shí)際工程中,圖像直方圖在特征提取,、圖像匹配等方面都有很好的應(yīng)用,。

二、利用OpenCV計(jì)算圖像的直方圖

OpenCV中計(jì)算圖像直方圖像函數(shù)是calcHist,,它的參數(shù)比較多,,下面分析一下它的接口和用法。

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:要計(jì)算直方圖的圖像的個(gè)數(shù),。此函數(shù)可以為多圖像求直方圖,我們通常情況下都只作用于單一圖像,,所以通常nimages=1,。

const int* channels:圖像的通道,它是一個(gè)數(shù)組,,如果是灰度圖像則channels[1]={0};如果是彩色圖像則channels[3]={0,1,2},;如果是只是求彩色圖像第2個(gè)通道的直方圖,則channels[1]={1};

IuputArray mask:是一個(gè)遮罩圖像用于確定哪些點(diǎn)參與計(jì)算,,實(shí)際應(yīng)用中是個(gè)很好的參數(shù),,默認(rèn)情況我們都設(shè)置為一個(gè)空?qǐng)D像,即:Mat(),。

OutArray hist:計(jì)算得到的直方圖

int dims:得到的直方圖的維數(shù),,灰度圖像為1維,彩色圖像為3維,。

const int* histSize:直方圖橫坐標(biāo)的區(qū)間數(shù),。如果是10,則它會(huì)橫坐標(biāo)分為10份,,然后統(tǒng)計(jì)每個(gè)區(qū)間的像素點(diǎn)總和,。

const float** ranges:這是一個(gè)二維數(shù)組,用來指出每個(gè)區(qū)間的范圍,。

后面兩個(gè)參數(shù)都有默認(rèn)值,,uniform參數(shù)表明直方圖是否等距,,最后一個(gè)參數(shù)與多圖像下直方圖的顯示與存儲(chǔ)有關(guān)。

下面我們來計(jì)算一幅圖像的灰度直方圖,,彩色直方圖以及自定義的灰度分布圖,。

灰度直方圖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}

彩色直方圖:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

不均勻直方圖,我們分別統(tǒng)計(jì)0-50,,50-80,,80-150,150-230,,230-255區(qū)間的灰度分布:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

三,、直方圖的顯示

從上面的例子中我們可以看出,直方圖計(jì)算得到的實(shí)際上是一個(gè)多維數(shù)組,,這并不夠直觀,,我們希望能夠像在Excel中把相關(guān)數(shù)據(jù)通過表的形式表示出來。

下面通過劃線函數(shù)來把一個(gè)灰度直方圖顯示出來:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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));
    // 設(shè)置最大峰值為圖像高度的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;
}

四,、直方圖變換

直方圖變換是圖像處理中一個(gè)很重要的概念,,圖像直方圖可以反映出圖像對(duì)比度,明暗程度等特征,,所以我們可以利用直方圖的變換進(jìn)行圖像畫面的調(diào)節(jié),。

直方圖變換在實(shí)際工程中的應(yīng)用很廣,一些美化照片的軟件很多工具都是在圖像的直方圖上作文章,,如果有讀者對(duì)這這方面感興趣的推薦:http://www.cnblogs.com/Imageshop/

下面介紹兩個(gè)簡(jiǎn)單的直方圖變換函數(shù):直方圖拉伸與直方圖均衡化,。

如果圖像的灰度在直方圖上顯示集中在某一個(gè)區(qū)間,則說明圖像色彩單一,,我們可以將其擴(kuò)展到更寬的灰度范圍內(nèi)讓圖像更有層次感,。

變換函數(shù):將圖像的一種灰度值經(jīng)過變換得到另一個(gè)灰度。

直方圖變換的核心就是變換函數(shù),,s=T(r),,r是變換前的灰度值,s是變換后的灰度值,,如要我們想將[a,b]區(qū)間的灰度變換到[0,255]范圍內(nèi),,則變換函數(shù)是:T(r)=255*(r-a)/(b-a)。

我們?cè)贠penCV中創(chuàng)建這樣一個(gè)變換函數(shù):

1
2
3
4
5
6
7
8
9
10
11
12
// 創(chuàng)建一個(gè)1*256的矢量
Mat lut(1,256,CV_8U);
for(int i=0;i<256;i++)
{
    if(lut.at<uchar>(i)<imin)
        lut.at<uchar>(i)=0;
    else if(lut.at<uchar>(i)>imax)
        lut.at<uchar>(i)=255;
    else
        lut.at<uchar>(i)=static_cast<uchar>(
        255.0*(i-imin)/(imax-imin)+0.5);
}

其中imax,imin是圖像中的最小灰度與最大灰度,。我們可以從直方圖中求出:

1
2
3
4
5
6
7
8
9
10
11
int imax,imin;
for(imin=0;imin<256;imin++)
{
    if(hist.at<uchar>(imin)>minValue)
        break;
}
for(imax=255;imax>-1;imax--)
{
    if(hist.at<uchar>(imax)>minValue)
        break;
}

最后我們應(yīng)用OpenCV中的LUT函數(shù),,把變換應(yīng)用在直方圖上即可。

LUT(image,lut,result);

第二個(gè)參數(shù)就像一個(gè)查找表一樣,,將原圖像中的灰度按表查找,,然后把灰度值替換為表中對(duì)應(yīng)的值。

有了上面灰度拉伸的例子就不難理解圖像的直方圖均衡了,,直方圖均衡化可以讓圖像灰度分布更加均勻,,讓圖像的對(duì)比度增強(qiáng),。

在OpenCV中直方圖均衡不用像灰度拉伸那樣先構(gòu)造一個(gè)變換函數(shù),它有直接對(duì)應(yīng)的函數(shù),,當(dāng)然你如果有興趣也可以去嘗試寫一下變換函數(shù)均衡化的變換原理會(huì)稍復(fù)雜一些,,在OpenCV這個(gè)系列里面,不會(huì)太多的介紹數(shù)字圖像中的算法,,以后有機(jī)會(huì)再專門來討論,。

1
2
3
4
5
6
7
8
9
10
int main()
{
    Mat Image=imread('../cat.png');
    cvtColor(Image,Image,CV_BGR2GRAY);
    Mat result;
    equalizeHist(Image,result);
    return 0;
}

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多