1. 程式人生 > >(轉)opencv--直方圖&最大熵分割

(轉)opencv--直方圖&最大熵分割

原來一直覺得OpenCV裡的直方圖函式十分簡單,今天臨時需要用才發現原來OpenCV的calcHist功能如此強大,不僅能計算常見的1D Hist, calcHist理論上支援32維以下的Hist.(32維啊 有木有!)

image: 輸入影象序列

nimages: 源影象數量

channels: 用於計算hist的通道List

mask:不解釋

hist:生成的hist

dims:hist的維數(必須大於0,目前版本支援不大於CV_MAX_DIMS=32

histSzie:每一維的size(即bins)

ranges: 直方圖每一維的bins的邊界的序列

uniform:是否對齊

accumlate:如果set為true,則直方圖在使用之前不clear,用於在一個hist內儲存多個影象集的直方圖,或者及時更新hist。

實現程式碼:

在此實現兩個直方圖繪製函式,分別繪製1D,2D直方圖。

BGR三通道1D直方圖:


附帶的在程式裡實現了一個視窗內顯示多幅影象,也可以使用Mat1.put_back(Mat2),但是push_back是向y軸方向push mat ,醬紫顯示的就是細長細長視窗,所以還是使用ROI的使用者體驗比較好。

Mat drawHist(Mat hist,int bins,int height,Scalar rgb)  
{  
    double maxVal=0;  
    minMaxLoc(hist,0,&maxVal,0,0);  
    int scale=1;  
    Mat histImg = Mat::zeros(height, bins, CV_8UC3);  
    float *binVal = hist.ptr<float>(0);  
    for (int i=0; i<bins; i++)  
    {  
        int intensity = cvRound(binVal[i]*height/maxVal);  
        rectangle(histImg,Point(i*scale,0),  
            Point((i+1)*scale,(intensity)),rgb,CV_FILLED);  
    }  
    flip(histImg,histImg,0);  
    return histImg;  
}  
  
void darwHistRGB(const Mat& src)  
{  
    Mat histB,histG,histR;  
  
    int bins=256;  
    int histSize[] = {bins};  
    float range[] = {0,256};  
    const float* ranges[] = {range};  
    int channelsB[] = {0};  
        int channelsG[] = {1};  
        int channelsR[] = {2};  
    calcHist(&src,1,channelsB,Mat(),histB,1,histSize,ranges,true,false);  
    calcHist(&src,1,channelsG,Mat(),histG,1,histSize,ranges,true,false);  
    calcHist(&src,1,channelsR,Mat(),histR,1,histSize,ranges,true,false);  
  
    Mat histBImg = drawHist(histB,bins,200,Scalar(255,0,0));  
    Mat histGImg = drawHist(histG,bins,200,Scalar(0,255,0));  
    Mat histRImg = drawHist(histR,bins,200,Scalar(0,0,255));  
      
    //在一個視窗中顯示多幅影象  
    Mat display(200,bins*3,CV_8UC3);  
    Mat displayROI = display(Rect(0,0,bins,200));  
    resize(histBImg,displayROI,displayROI.size());  
    displayROI = display(Rect(bins,0,bins,200));  
    resize(histGImg,displayROI,displayROI.size());  
    displayROI = display(Rect(bins*2,0,bins,200));  
    resize(histRImg,displayROI,displayROI.size());  
  
    imshow("histRGB",display);  
    waitKey();  
}  
  
int main()  
{  
   	Mat src = imread("e:/test/5.jpg",1);
	/*或者可以做Mat hsv=Mat::zeros( src.rows, src.cols, CV_8UC3 );;

	cvtColor(src,hsv,CV_RGB2HSV,0);
	imshow("hsv",hsv);*/
    darwHistRGB(src);  
    return 1;  
}  



HSV的H-S通道2D直方圖:


灰度值的大小代表了直方圖的高度。可以看做是一個從上向下(-Z軸方向)看的三維柱狀圖。

[cpp] view plaincopyprint?
  1. int main(  )  
  2. {  
  3.     Mat src, hsv;  
  4.     src = imread("D:/demo.jpg", 1);  
  5.     cvtColor(src, hsv, CV_BGR2HSV);  
  6.     // Quantize the hue to 30 levels
  7.     // and the saturation to 32 levels
  8.     int hbins = 30, sbins = 32;  
  9.     int histSize[] = {hbins, sbins};  
  10.     // hue varies from 0 to 179, see cvtColor
  11.     float hranges[] = { 0, 180 };  
  12.     // saturation varies from 0 (black-gray-white) to
  13.     // 255 (pure spectrum color)
  14.     float sranges[] = { 0, 256 };  
  15.     constfloat* ranges[] = { hranges, sranges };  
  16.     MatND hist;  
  17.     // we compute the histogram from the 0-th and 1-st channels
  18.     int channels[] = {0, 1};  
  19.     calcHist( &hsv, 1, channels, Mat(), // do not use mask
  20.         hist, 2, histSize, ranges,  
  21.         true// the histogram is uniform
  22.         false );  
  23.     double maxVal=0;  
  24.     minMaxLoc(hist, 0, &maxVal, 0, 0);  
  25.     int scale = 10;  
  26.     Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);  
  27.     forint h = 0; h < hbins; h++ )  
  28.         forint s = 0; s < sbins; s++ )  
  29.         {  
  30.             float binVal = hist.at<float>(h, s);  
  31.             int intensity = cvRound(binVal*255/maxVal);  
  32.             rectangle( histImg, Point(h*scale, s*scale),  
  33.                 Point( (h+1)*scale - 1, (s+1)*scale - 1),  
  34.                 Scalar::all(intensity),  
  35.                 CV_FILLED );  
  36.         }  
  37.         namedWindow( "Source", 1 );  
  38.         imshow( "Source", src );  
  39.         namedWindow( "H-S Histogram", 1 );  
  40.         imshow( "H-S Histogram", histImg );  
  41.         waitKey();  
  42. }  

最大熵分割

利用Hist實現最大熵模型

資訊熵:

最大熵分割:


 

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include <opencv/cv.h>
  3. #include <opencv/highgui.h>
  4. usingnamespace std;  
  5. usingnamespace cv;  
  6. typedefenum {back,object} entropy_state;  
  7. float total;  
  8. //繪製hist;
  9. Mat drawHist(Mat hist,int bins,int height,Scalar rgb)  
  10. {  
  11.     double maxVal=0;  
  12.     minMaxLoc(hist,0,&maxVal,0,0);  
  13.     int scale=1;  
  14.     Mat histImg = Mat::zeros(height, bins, CV_8UC3);  
  15.     float *binVal = hist.ptr<float>(0);  
  16.     for (int i=0; i<bins; i++)  
  17.     {  
  18.         int intensity = cvRound(binVal[i]*height/maxVal);  
  19.         rectangle(histImg,Point(i*scale,0),  
  20.             Point((i+1)*scale,(intensity)),rgb,CV_FILLED);  
  21.     }  
  22.     flip(histImg,histImg,0);  
  23.     return histImg;  
  24. }  
  25. //計算直方圖;
  26. Mat Hist(const Mat& src)  
  27. {  
  28.     Mat hist;  
  29.     int bins=256;  
  30.     int histSize[] = {bins};  
  31.     float range[] = {0,256};  
  32.     constfloat* ranges[] = {range};  
  33.     int channels[] = {0};  
  34.     calcHist(&src,1,channels,Mat(),hist,1,histSize,ranges,true,false);  
  35.     Mat histImg = drawHist(hist,bins,200,Scalar(255,0,0));  
  36.     imshow("histRGB",histImg);  
  37.     return hist;  
  38. }  
  39. //計算當前熵;
  40. float calEntropy(const Mat& hist,int threshold)  
  41. {  
  42.     float total_back=0,total_object=0;  
  43.     float entropy_back=0,entropy_object=0;  
  44.     float entropy = 0;  
  45.     int i=0;  
  46.     constfloat* hist_p = (float*) hist.ptr<float>(0);  
  47.     for (i=0; i<threshold; i++)  
  48.     {  
  49.         total_back += hist_p[i];  
  50.     }  
  51.     total_object=total-total_back;  
  52.     //背景熵;
  53.     for (i=0; i<threshold; i++)  
  54.     {  
  55. //      if(hist_p[i]==0)
  56. //          continue;
  57.         float percentage = hist_p[i]/total_back;  
  58.         entropy_back += -percentage * logf(percentage); // 能量的定義公式
  59.     }  
  60.     //前景熵;
  61.     for (i=threshold; i<hist.cols; i++)  
  62.     {  
  63. //      if(hist_p[i]==0)
  64. //      {
  65. //          continue;
  66. //      }
  67.         float percentage = hist_p[i]/total_object;  
  68.         entropy_object += -percentage * logf(percentage); // 能量的定義公式;
  69.     }  
  70.     entropy = entropy_object+entropy_back;  
  71.     return entropy;  
  72. }  
  73. void MaxEntropy(Mat img, Mat hist)  
  74. {  
  75.     total = sum(hist)[0];  
  76.     float MaxEntropyValue = 0.0, MaxEntropyThreshold=0.0;  
  77.     float tmp;  
  78.     for (int i=0; i<hist.cols; i++)  
  79.     {  
  80.         tmp = calEntropy(hist,i);  
  81.         if(tmp>MaxEntropyValue)  
  82.         {  
  83. 相關推薦

    ()opencv--直方圖&分割

    原來一直覺得OpenCV裡的直方圖函式十分簡單,今天臨時需要用才發現原來OpenCV的calcHist功能如此強大,不僅能計算常見的1D Hist, calcHist理論上支援32維以下的Hist.(32維啊 有木有!) image: 輸入影象序列 nimages

    【閾值分割分割

    第一次嘗試寫部落格,希望能堅持下去。。。 最近在做紅外小目標檢測,用到一個最大熵分割法,ok,下面介紹一下。 最大熵分割法 現在主要用的熵演算法有 P 氏熵演算法,KSW 熵演算法、JM 熵演算法下面以經典的 KSW 熵演算法為例介紹其原理和計算過程。 KSW熵演算法

    OpenCV程式設計:閾值分割演算法實現(程式碼可執行)

            將資訊理論中的 shannon 熵概念用於影象分割, 其依據是使得影象中目標與背景分佈的資訊量最大,即通過測量影象灰度直方圖的熵,找出最佳閾值。根據 shannon 熵的概念,對於灰度範圍為 0,1,2,…,L-1 的影象,其直方圖的熵定義為(僅僅是定義)

    七種常見閾值分割程式碼(Otsu、、迭代法、自適應閥值、手動、迭代法、基本全域性閾值法)

    整理了一些主要的分割方法,以後用省的再查,其中大部分為轉載資料,轉載連結見資料; 一、工具:VC+OpenCV 二、語言:C++ 三、原理    (1) otsu法(最大類間方差法,有時也稱之為大津演算法)使用的是聚類的思想,把影象的灰度數按灰度級分成2個部分,使得兩

    閾值分割演算法

    #include <opencv2\opencv.hpp> #include <opencv\cv.h> using namespace cv; int HistogramBins = 256; float HistogramRange1[2

    matlab基於遺傳演算法的值法的雙閾值影象分割

    利用最佳直方圖熵法(KSW熵法)及傳統遺傳演算法實現灰度影象二閾值分割 matlab程式碼如下: 1、main.m(主函式): %%%利用最佳直方圖熵法(KSW熵法)及傳統遺傳演算法實現灰度影象二閾值分割 %%%主程式 %% 初始部分,讀取影象及計算

    影象閾值分割

        影象最大熵閾值分割的原理:使選擇的閾值分割影象目標區域、背景區域兩部分灰度統計的資訊量為最大。     具體描述: 1. 根據資訊熵定義,計算原始影象的資訊熵H0,選擇最大、最小灰度灰度的均值為初始閾值T0; 2. 根據T0將影象分割為G1和G2兩個區域,均值分

    影象分割:1.基於閾值的影象分割方法(分割法)

     利用影象熵為準則進行影象分割有一定歷史了,學者們提出了許多以影象熵為基礎進行影象分割的方法。我們介紹一種由Kapuret al提出來,現在仍然使用較廣的一種影象熵分割方法。 給定一個特定的閾值q(0<=q<K-1),對於該閾值所分割的兩個影象區域C0,C1,其估

    學習筆記(一)預備知識

    color wrap targe dsm entropy plus 文件 eight 相關鏈接 生活中我們常常聽到人們說“不要把雞蛋放到一個籃子裏”。這樣能夠減少風險。深究一下,這是為什麽呢?事實上,這裏邊包括了所謂的最大熵原理(The Maxim

    模型

    定性 全部 投資 情況 進行 算法 出了 信息 簡單 我們不要把雞蛋都放在一個籃子裏面講得就是最大熵原理,從投資的角度來看這就是風險最小原則。從信息論的角度來說,就是保留了最大的不確定性,也就是讓熵達到了最大。最大熵院裏指出,對一個隨機事件的概率分布進行預測的時候,我

    通俗理解模型

    log logs ima 最大熵 ges es2017 最大熵模型 blog image 通俗理解最大熵模型

    class-邏輯回歸

    l-bfgs max-width net 觀點 通過 離散 n) 自然 等價 我們知道,線性回歸能夠進行簡單的分類,但是它有一個問題是分類的範圍問題,只有加上一個邏輯函數,才能使得其概率值位於0到1之間,因此本次介紹邏輯回歸問題。同時,最大熵模型也是對數線性模型,在介紹最大

    Win8 Metro(C#)數字圖像處理--2.57一維法圖像二值化

    rgb ack stream toa tail 函數代碼 ble param nor 原文:Win8 Metro(C#)數字圖像處理--2.57一維最大熵法圖像二值化

    淺談模型中的特徵

    最近在看到自然語言處理中的條件隨機場模型時,發現了裡面涉及到了最大熵模型,這才知道最大熵模型自己還是一知半解,於是在知乎上查閱了很多資料,發現特別受用,飲水思源,我將自己整理的一些資料寫下來供大家參考 僅僅對輸入抽取特徵。即特徵函式為 對輸入和輸出同時抽取特徵。即特徵函式為

    斯坦福大學-自然語言處理入門 筆記 第十一課 模型與判別模型(2)

    一、最大熵模型 1、模型介紹 基本思想:我們希望資料是均勻分佈的,除非我們有其他的限制條件讓給我們相信資料不是均勻分佈的。均勻分佈代表高熵(high entropy)。所以,最大熵模型的基本思想就是我們要找的分佈是滿足我們限制條件下,同時熵最高的分佈。 熵:表示分佈的不

    斯坦福大學-自然語言處理入門 筆記 第八課 模型與判別模型

    一、生成模型與判別模型 1、引言 到目前為止,我們使用的是生成模型(generative model),但是在實際使用中我們也在大量使用判別模型(discriminative model),主要是因為它有如下的優點: 準確性很高 更容易包含很多和

    原理

    相關數學知識: 1、拉格朗日乘子法 2、拉格朗日對偶性 3、凸函式 4、Jensen 不等式 5、經驗分佈 --- 參考資料1:皮果提的文章《最大熵學習筆記》系列 https://blog.csdn.net/itplus/article/details/26550597 其他參考資料: 李航·統計學習

    ml課程:與EM演算法及應用(含程式碼實現)

    以下是我的學習筆記,以及總結,如有錯誤之處請不吝賜教。 本文主要介紹最大熵模型與EM演算法相關內容及相關程式碼案例。 關於熵之前的文章中已經學習過,具體可以檢視:ml課程:決策樹、隨機森林、GBDT、XGBoost相關(含程式碼實現),補充一些 基本概念: 資訊量:資訊的度量,即

    【統計學習方法-李航-筆記總結】六、邏輯斯諦迴歸和模型

    本文是李航老師《統計學習方法》第六章的筆記,歡迎大佬巨佬們交流。 主要參考部落格: http://www.cnblogs.com/YongSun/p/4767100.html https://blog.csdn.net/tina_ttl/article/details/53519391

    統計學習---邏輯斯蒂迴歸與模型

    邏輯斯蒂迴歸和最大熵模型 邏輯斯蒂分佈 邏輯斯蒂迴歸模型 將權值向量和輸入向量加以擴充後的邏輯斯蒂模型為 模型引數估計 極大似然估計法 最大熵模型 最大熵原理:在所有可能的概率模型中,熵最大的模型是最好的模型。通常用約