OpenCV成長之路:圖像直方圖的應用

正如第4篇文章所說的圖像直方圖在特徵提取方面有着很重要的作用,本文將舉兩個實際工程中非常實用的例子來說明圖像直方圖的應用。

一、直方圖的反向映射。

我們以人臉檢測舉例,在人臉檢測中,我們第一步往往需要先提取圖像中皮膚區域來縮小人臉的檢測範圍,這一般獲得皮膚的顏色範圍還需要定義閾值並不斷的調整,實際中參數太多而不容易控制。

這裏我們就可以考慮用直方圖的反射映射。

1,收集人臉皮膚樣本。

2,拼合樣本並計算其顏色直方圖。

3,將得到的樣本顏色直方圖反射映射到待檢測的圖片中,然後進行閾值化即可。

這裏爲了簡單起見,我們只用兩張人臉樣本,實際中可以進一步擴展。

image

在提取樣本皮膚的直方圖時,我們需要對這些樣本圖像做一些處理,比如把頭髮、眼睛等部位去除,我們這裏使用一個mask即可。

由於我們要計算彩色直方圖像,爲了簡化色彩,我們還需要對顏色降維,相關函數在本系列文章第2篇中已經有介紹了。

int main()
{
    Mat face=imread("../face.png");        // 樣本
    Mat ImgSrc=imread("../img.png");    // 待檢測的圖像
    //圖像降維
    colorReduce(face,face,32);
    colorReduce(ImgSrc,ImgSrc,32);
          
    // 計算顏色直方圖
    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(&face,1,channels,Mat(),hist,3,histSize,ranges);
    // 直方圖歸一化
    normalize(hist,hist,1.0);
    // 直方圖反向映射
    Mat result;
    calcBackProject(&ImgSrc,1,channels,hist,result,ranges,255);
    // 將結果進行閾值化
    threshold(result,result,255*(0.05),255,THRESH_BINARY);
return 0;
}

image

上面程序中有以下幾點值得說明:

1,在作彩色圖像直方圖的反向映射時,一般需要對圖像顏色進行降維。

2,OpenCV中提供的函數clacBackProject用於計算直方圖的反向映射,其參數和計算直方圖的參數大體相同。

3,threshold是一個閾值化的函數。

二、圖像相似性的比較

圖像相似性比較是比上面直方圖映射更加實用且普通的例子,前段時間淘寶或百度推出類似搜圖的功能都離不開圖像相似性判斷這個話題,當然本文這裏面不可能去深入探討那些解決方案的實現,只是利用OpenCV中的例程來簡單的實現圖片的匹配。
下面我們來計算兩幅圖像之間的相似度:我們以左邊一幅圖像作爲參考圖像,是沒有車輛停放時的圖像,右邊兩幅跟左邊比較計算相似性。中間一幅是有車輛停放時,右邊一幅是另一個時刻沒有車輛停放時。

這個例子實際可以應用在停車位上車輛檢測上面:

imageimageimage

int main()
{
    Mat refImg=imread("../ref.png");
    Mat image1=imread("../image1.png");
    Mat image2=imread("../image2.png");
      
    ColorHistogram imgHist;
    //圖像顏色降維
    refImg=imgHist.colorReduce(refImg,64);
    image1=imgHist.colorReduce(image1,64);
    image2=imgHist.colorReduce(image2,64);
    MatND refH=imgHist.getHistogram(refImg);
    MatND hist1=imgHist.getHistogram(image1);
    MatND hist2=imgHist.getHistogram(image2);
    double dist1,dist2;
    dist1=compareHist(refH,hist1,CV_COMP_BHATTACHARYYA);
    dist2=compareHist(refH,hist2,CV_COMP_BHATTACHARYYA);
    std::cout<<"dist1="<<dist1<<",dist2="<<dist2<<std::endl;
    return 0;
}

最終輸出結果爲:

dist1=0.69

dist2=0.08

上面程序中有以下幾點值得說明:

1,程序中ColorHistogram是自定義的一個類,其中包括了直方圖求取與圖像的顏色降維,

2,直方圖的比較函數爲compareHist(refH,imgH,CV_COMP_XX),最後一個參數是兩個矢量間距離計算的方法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章