• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • opencv 繪制直方圖

    一、話說直方圖

    說到直方圖,同學們一定會想到統計學里的直方圖(沒有想起來的抓緊去翻下中學數學課本)。所謂直方圖啊,就是把一大坨東西分成好幾部分(橫坐標),然后看看每一部分有多少(縱坐標)。比如說康娜醬的班里要做個人愛好的統計,喜歡跳繩的有5人,喜歡唱歌的有8人,喜歡讀書的有6人,超喜歡康娜醬的有1人(才川同學了解一下)。那么圖像中的直方圖又是個啥子呢?喜歡攝影的同學一定見過。圖像中常見的直方圖是亮度直方圖(在CV中還有一種H-S直方圖,即在HSV空間中計算,若沒有特殊說明,將會默認介紹亮度直方圖),橫坐標表示像素值的分布(通常0~255),縱坐標為像素個數,那么圖像直方圖的含義就是數數看每個像素值對應的像素個數,進一步講,橫坐標的左側為暗的區域,右側為亮的區域,所以圖像的亮度分布情況就可以反應在亮度直方圖中。

    二、繪制直方圖

    在OpenCV中,我們使用函數calcHist來計算直方圖(僅僅是計算),如果使用python,則可借助matplotlib繪制出直方圖(python的話當然也可以用OpenCV中的繪圖函數,但有matplotlib這么好的工具為什么不用呢)。

    API:

    hist=cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
    
    • hist:直方圖的數據,是一個二維數組
    • image:數組集合,這里就是圖像集合,可以是一幅或多幅圖像,需要有相同的深度(CV_8U或CV_32F)和尺寸
    • channels:要統計哪個通道的像素,彩色圖像的話就有3個通道
    • mask:掩膜,當我們想要對圖像中某一區域做直方圖時就要在圖像上加一層掩膜
    • histSize:步長,要把橫軸分成多少份,有些教程中叫做bin的長度
    • ranges:統計量的取值范圍,注意不是縱軸的取值范圍,比如統計量是像素,那么通常就是像素值的取值范圍

    注意

    • 參數images、channels、histSize和ranges參數都要寫成列表的形式,因為這個函數允許處理多幅圖像或多個通道
    • 當要處理多幅圖像或多個通道時,histSize和ranges中參數的順序是與待處理的矩陣一一對應,比如channels寫成[0,1],那么ranges寫成[0,180,0,256],即通道0的ranges是[0,180],通道2的ranges是[0,256],這個數值組合其實是分析HSV時用到的。

    好的,我們來看一個Demo,要做下面幾個事,素材取自番劇《比宇宙更遠的地方》第13話:

    • 計算并繪制灰度圖像的直方圖
    • 計算并繪制彩色圖像的直方圖
    • 使用掩膜來繪制直方圖,掩膜是通過確定ROI并進行邏輯運算得到的
    實驗代碼:
    	Mat srcImage = imread("D:\\cv_study\\隨機練\\2.jpg");
    	MatND dstHist;//得到的直方圖     
    	int dims = 1;//得到的直方圖的維數 灰度圖的維數為1
    	float hranges[2] = { 0, 255 };
    	const float *ranges[1] = { hranges };   // 這里需要為const類型,二維數組用來指出每個區間的范圍  
    	int size = 256;//直方圖橫坐標的區間數 即橫坐標被分成256份
    	int channels = 0;//圖像得通道 灰度圖的通道數為0
    					 //計算圖像的直方圖  
    	calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
    	int scale = 1;
    	Mat dstImage(size * scale, size, CV_8U, Scalar(0));
    	//獲取最大值和最小值  
    	double minValue = 0;
    	double maxValue = 0;
    	minMaxLoc(dstHist, &minValue, &maxValue, 0, 0); //找到直方圖中的最大值和最小值 
    													//繪制出直方圖  
    	int hpt = saturate_cast<int>(0.9 * size);//防止溢出
    	for (int i = 0; i < 256; i++)
    	{
    		float binValue = dstHist.at<float>(i);
    		int realValue = saturate_cast<int>(binValue * hpt / maxValue);
    		line(dstImage, Point(i*scale, size - 1), Point((i + 1)*scale - 1, size - realValue), Scalar(255));
    	}
    	imshow("一維直方圖", dstImage);
    	waitKey();
    	return 0;

    實驗結果如圖:

    三、直方圖均衡化

    上面講到亮度直方圖描述的是亮度的統計分布情況。所以一幅較亮的圖像中,直方圖將會偏向右側,較暗的圖像則會偏向左側。然而,一幅理想的圖像應該是亮暗適中,因此對應的亮度直方圖應該呈均勻分布的樣子,對于較亮或較暗的圖像我們需要進行直方圖的拉伸,這就是直方圖均衡化要做的事情。
    dst=cv2.equalizeHist(src[, dst])
    
    • src:需要進行均衡化處理的圖像
    • dist:均衡化后的圖像
    實驗代碼:
    	cvtColor(srcImage, srcImage, CV_BGR2GRAY);
    	equalizeHist(srcImage, m0);
    	waitKey();

    四、直方圖比較

    亮度直方圖反應了一幅圖像的亮度分布,這一特性可以用來比較兩幅圖像的相似性,也可以研究不同光照對同一幅圖像的影響。

    要用到函數compareHist,函數原型:

    retval=cv2.compareHist(H1, H2, method)
    
    • retval:兩個直方圖的相似度
    • H1和H2:需要比較的兩個直方圖
    • method:比較方法,這里介紹三種,其他的方法可以查閱API
    1. Correlation ( CV_COMP_CORREL )

      其中


      N 是直方圖中bin的數目。

    2. Chi-Square ( CV_COMP_CHISQR )


    3. Intersection ( CV_COMP_INTERSECT )


    4. Bhattacharyya 距離( CV_COMP_BHATTACHARYYA )

    實驗代碼:

    int main()
    {
    
    	Mat srcImage = imread("D:\\cv_study\\隨機練\\1.jpg");
    	Mat compareImage = imread("D:\\cv_study\\隨機練\\2.jpg");
    	imshow("【原圖】", srcImage);
    	imshow("【需要比較的圖像】", compareImage);
    
    	//在比較直方圖時,最佳操作是在HSV空間中操作,所以需要將BGR空間轉換為HSV空間  
    	Mat srcHsvImage;
    	Mat compareHsvImage;
    	cvtColor(srcImage, srcHsvImage, CV_BGR2HSV);
    	cvtColor(compareImage, compareHsvImage, CV_BGR2HSV);
    
    	//采用H-S直方圖進行處理  
    	//首先得配置直方圖的參數  
    	MatND srcHist, compHist;
    	//H、S通道  
    	int channels[] = { 0, 1 };
    	int histSize[] = { 30, 32 };
    	float HRanges[] = { 0, 180 };
    	float SRanges[] = { 0, 256 };
    	const float *ranges[] = { HRanges, SRanges };
    
    	//進行原圖直方圖的計算  
    	calcHist(&srcHsvImage, 1, channels, Mat(), srcHist, 2, histSize, ranges, true, false);
    	//對需要比較的圖進行直方圖的計算  
    	calcHist(&compareHsvImage, 1, channels, Mat(), compHist, 2, histSize, ranges, true, false);
    
    	//注意:這里需要對兩個直方圖進行歸一化操作  
    	normalize(srcHist, srcHist, 0, 1, NORM_MINMAX);
    	normalize(compHist, compHist, 0, 1, NORM_MINMAX);
    
    	//對得到的直方圖對比  
    	double g_dCompareRecult = compareHist(srcHist, compHist, 0);
    	cout << "方法一:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
    
    	g_dCompareRecult = compareHist(srcHist, compHist, 1);
    	cout << "方法二:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
    
    	g_dCompareRecult = compareHist(srcHist, compHist, 2);
    	cout << "方法三:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
    
    	g_dCompareRecult = compareHist(srcHist, compHist, 3);
    	cout << "方法四:兩幅圖像比較的結果為:" << g_dCompareRecult << endl;
    	waitKey();
    	return 0;
    }




    好了,這就是今天要講的直方圖。

    版權聲明:本文為zhangjunp3原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/zhangjunp3/article/details/79781424

    智能推薦

    使用Opencv繪制灰度直方圖/對比

    一.所需結構體 結構體原型: 二.所需函數 1.cvCalcHist: 函數功能:用于計算圖像直方圖 函數原型: 參數介紹: 返回值:無 2.CvCreateHist: 函數功能:用于創建直方圖 函數原型: 參數介紹: 返回值:成功返回一個指向堆中CvHistogram結構體的CvHistogram指針 3.cvGetMinMaxHistValue: 函數功能:用于統計直方圖中最小值和最大值 函數...

    opencv 繪制圖像直方圖

    為圖像繪制直方圖,效果圖如下: 代碼如下:...

    OpenCV python 繪制圖片直方圖

    OpenCV python 繪制圖片直方圖 處理圖片[source.jpg] 處理結果:...

    opencv(18)---直方圖計算以及繪制

    基本概念 直方圖是對數據進行統計的一種方法, 可以直觀表現圖像某屬性的數值(頻率)分布情況, 包括灰度直方圖、RGB直方圖等 數字直方圖 圖像直方圖 相關概念 函數原型 1.dims: 需要統計得特征的數目, 只統計灰度值—dims=1 統計RGB值—dims=3 2.bins: 每個特征空間子區域段的數目,也 可稱為組距(簡單理解為直方圖分 成幾個柱子組成) 3.rang...

    猜你喜歡

    (Python+OpenCV)繪制灰度直方圖

    繪制單通道直方圖和RGB三通道直方圖。   IDE:Jupyter Lab   原圖: 對原圖進行降維: 直方圖: RGB三通道直方圖:...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡