日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【OpenCV 】直方图均衡化,直方图计算,直方图对比

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OpenCV 】直方图均衡化,直方图计算,直方图对比 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

1.直方圖均衡化?

1.1 原理

1.2 直方圖均衡化

1.3 直方圖均衡化原理

1.4 代碼實例

1.5 運行效果

2. 直方圖計算?

2.1 目標

2.2 直方圖

2.3 代碼實例

2.4 運行結果

3 直方圖對比?

3.1 目標

3.2 原理

3.3 代碼

3.4 運行結果


1.直方圖均衡化?

  • 什么是圖像的直方圖和為什么圖像的直方圖很有用

  • 用OpenCV函數 equalizeHist 對圖像進行直方圖均衡化

1.1 原理

  • 直方圖是圖像中像素強度分布的圖形表達方式.

  • 它統計了每一個強度值所具有的像素個數.

1.2 直方圖均衡化

  • 直方圖均衡化是通過拉伸像素強度分布范圍來增強圖像對比度的一種方法.

  • 說得更清楚一些, 以上面的直方圖為例, 你可以看到像素主要集中在中間的一些強度值上. 直方圖均衡化要做的就是 拉伸 這個范圍. 見下面左圖: 綠圈圈出了 少有像素分布其上的 強度值. 對其應用均衡化后, 得到了中間圖所示的直方圖. 均衡化的圖像見下面右圖.

1.3 直方圖均衡化原理

OpenCV 【九】——calcHist ——圖像直方圖統計

  • 1.4 代碼實例

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
?
using namespace cv;
using namespace std;
?
/**  @function main */
int main( int argc, char** argv )
{Mat src, dst;
?char* source_window = "Source image";char* equalized_window = "Equalized Image";
?/// 加載源圖像src = imread( argv[1], 1 );
?if( !src.data ){ cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;return -1;}
?/// 轉為灰度圖cvtColor( src, src, CV_BGR2GRAY );
?/// 應用直方圖均衡化equalizeHist( src, dst );
?/// 顯示結果namedWindow( source_window, CV_WINDOW_AUTOSIZE );namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );
?imshow( source_window, src );imshow( equalized_window, dst );
?/// 等待用戶按鍵退出程序waitKey(0);
?return 0;
}

?

1.5 運行效果

直方圖均衡化

?

2. 直方圖計算?

2.1 目標

  • 如何使用OpenCV函數 split 將圖像分割成單通道數組。

  • 如何使用OpenCV函數 calcHist 計算圖像陣列的直方圖。

  • 如何使用OpenCV函數 normalize 歸一化數組。

2.2 直方圖

詳見OpenCV 【九】——calcHist ——圖像直方圖統計

  • 讓我們再來搞清楚直方圖的一些具體細節:

    1. dims: 需要統計的特征的數目, 在上例中,?dims = 1?因為我們僅僅統計了灰度值(灰度圖像)。
    2. bins: 每個特征空間?子區段?的數目,在上例中,?bins = 16
    3. range: 每個特征空間的取值范圍,在上例中,?range = [0,255]
  • 怎樣去統計兩個特征呢? 在這種情況下, 直方圖就是3維的了,x軸和y軸分別代表一個特征, z軸是掉入?

  • ?組合中的樣本數目。 同樣的方法適用于更高維的情形 (當然會變得很復雜)。

2.3 代碼實例

  • 本程序做什么?

    • 裝載一張圖像

    • 使用函數 split 將載入的圖像分割成 R, G, B 單通道圖像

    • 調用函數 calcHist 計算各單通道圖像的直方圖

    • 在一個窗口疊加顯示3張直方圖

  • 下載代碼: 點擊 這里

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
?
using namespace std;
using namespace cv;
?
/** @函數 main */
int main(int argc, char** argv)
{Mat src, dst;
?/// 裝載圖像src = imread("C:\\Users\\guoqi\\Desktop\\ch7\\4.jpg", 1);
?if (!src.data){return -1;}
?/// 分割成3個單通道圖像 ( R, G 和 B )vector<Mat> rgb_planes;split(src, rgb_planes);
?/// 設定bin數目int histSize = 255;
?/// 設定取值范圍 ( R,G,B) )float range[] = { 0, 255 };const float* histRange = { range };
?bool uniform = true; bool accumulate = false;
?Mat r_hist, g_hist, b_hist;
?/// 計算直方圖:calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
?// 創建直方圖畫布int hist_w = 400; int hist_h = 400;int bin_w = cvRound((double)hist_w / histSize);
?Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
?/// 將直方圖歸一化到范圍 [ 0, histImage.rows ]normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
?/// 在直方圖畫布上畫出直方圖for (int i = 1; i < histSize; i++){line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))),Scalar(0, 0, 255), 2, 8, 0);line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))),Scalar(0, 255, 0), 2, 8, 0);line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))),Scalar(255, 0, 0), 2, 8, 0);}
?/// 顯示直方圖namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE);imshow("calcHist Demo", histImage);
?waitKey(0);return 0;
}

?

2.4 運行結果

?

3 直方圖對比?

HSV 顏色空間

基于上述理由,在圖像處理中使用較多的是 HSV 顏色空間,它比 RGB 更接近人們對彩色的感知經驗。非常直觀地表達顏色的色調、鮮艷程度和明暗程度,方便進行顏色的對比。

在 HSV 顏色空間下,比 BGR 更容易跟蹤某種顏色的物體,常用于分割指定顏色的物體。

HSV 表達彩色圖像的方式由三個部分組成:

  • Hue(色調、色相)

  • Saturation(飽和度、色彩純凈度)

  • Value(明度)

用下面這個圓柱體來表示 HSV 顏色空間,圓柱體的橫截面可以看做是一個極坐標系 ,H 用極坐標的極角表示,S 用極坐標的極軸長度表示,V 用圓柱中軸的高度表示。

?

Hue 用角度度量,取值范圍為0~360°,表示色彩信息,即所處的光譜顏色的位置。,表示如下:

?

顏色圓環上所有的顏色都是光譜上的顏色,從紅色開始按逆時針方向旋轉,Hue=0 表示紅色,Hue=120 表示綠色,Hue=240 表示藍色等等。

在 GRB中 顏色由三個值共同決定,比如黃色為即 (255,255,0);在HSV中,黃色只由一個值決定,Hue=60即可。

HSV 圓柱體的半邊橫截面(Hue=60):

?

其中Saturation*水平方向表示飽和度,飽和度表示顏色接近光譜色的程度飽和度越高,說明顏色越深,越接近光譜色飽和度越低,說明顏色越淺,越接近白色。飽和度為0表示純白色。取值范圍為0~100%,值越大,顏色越飽和。**

Value(明度):豎直方向表示明度,決定顏色空間中顏色的明暗程度,明度越高,表示顏色越明亮,范圍是 0-100%。明度為0表示純黑色(此時顏色最暗)。

可以通俗理解為:

在Hue一定的情況下,飽和度減小,就是往光譜色中添加白色,光譜色所占的比例也在減小,飽和度減為0,表示光譜色所占的比例為零,導致整個顏色呈現白色。

明度減小,就是往光譜色中添加黑色,光譜色所占的比例也在減小,明度減為0,表示光譜色所占的比例為零,導致整個顏色呈現黑色。

HSV 對用戶來說是一種比較直觀的顏色模型。我們可以很輕松地得到單一顏色,即指定顏色角H,并讓V=S=1,然后通過向其中加入黑色和白色來得到我們需要的顏色。增加黑色可以減小V而S不變,同樣增加白色可以減小S而V不變。例如,要得到深藍色,V=0.4 S=1 H=240度。要得到淺藍色,V=1 S=0.4 H=240度。

HSV 的拉伸對比度增強就是對 S 和 V 兩個分量進行歸一化(min-max normalize)即可,H 保持不變。

RGB顏色空間更加面向于工業,而HSV更加面向于用戶,大多數做圖像識別這一塊的都會運用HSV顏色空間,因為HSV顏色空間表達起來更加直觀!

3.1 目標

  • 如何使用OpenCV函數 compareHist 產生一個表達兩個直方圖的相似度的數值。

  • 如何使用不同的對比標準來對直方圖進行比較。

3.2 原理

  • ?and??), 首先必須要選擇一個衡量直方圖相似度的?對比標準?() 。

  • OpenCV 函數?compareHist?執行了具體的直方圖對比的任務。該函數提供了4種對比標準來計算相似度:

    1. 要比較兩個直方圖(??and??), 首先必須要選擇一個衡量直方圖相似度的?對比標準?() 。

    2. OpenCV 函數?compareHist?執行了具體的直方圖對比的任務。該函數提供了4種對比標準來計算相似度:

      1. Correlation ( CV_COMP_CORREL )

        其中

        ?是直方圖中bin的數目。

    3. Chi-Square ( CV_COMP_CHISQR )

    4. Intersection ( CV_COMP_INTERSECT )

    5. Bhattacharyya 距離( CV_COMP_BHATTACHARYYA )

3.3 代碼

  • 本程序做什么?

    • 裝載一張 基準圖像 和 兩張 測試圖像 進行對比。

    • 產生一張取自 基準圖像 下半部的圖像。

    • 將圖像轉換到HSV格式。

    • 計算所有圖像的H-S直方圖,并歸一化以便對比。

    • 基準圖像 直方圖與 兩張測試圖像直方圖,基準圖像半身像直方圖,以及基準圖像本身的直方圖分別作對比。

    • 顯示計算所得的直方圖相似度數值。

  • 下載代碼: 點擊 這里

  • 代碼一瞥:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
?
using namespace std;
using namespace cv;
?
/** @函數 main */
int main( int argc, char** argv )
{Mat src_base, hsv_base;Mat src_test1, hsv_test1;Mat src_test2, hsv_test2;Mat hsv_half_down;
?/// 裝載三張背景環境不同的圖像if( argc < 4 ){ printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n");return -1;}
?src_base = imread( argv[1], 1 );src_test1 = imread( argv[2], 1 );src_test2 = imread( argv[3], 1 );
?/// 轉換到 HSVcvtColor( src_base, hsv_base, CV_BGR2HSV );cvtColor( src_test1, hsv_test1, CV_BGR2HSV );cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
?hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
?/// 對hue通道使用30個bin,對saturatoin通道使用32個binint h_bins = 50; int s_bins = 60;int histSize[] = { h_bins, s_bins };
?// hue的取值范圍從0到256, saturation取值范圍從0到180float h_ranges[] = { 0, 256 };float s_ranges[] = { 0, 180 };
?const float* ranges[] = { h_ranges, s_ranges };
?// 使用第0和第1通道int channels[] = { 0, 1 };
?/// 直方圖MatND hist_base;MatND hist_half_down;MatND hist_test1;MatND hist_test2;
?/// 計算HSV圖像的直方圖calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
?calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
?calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
?calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
?///應用不同的直方圖對比方法for( int i = 0; i < 4; i++ ){ int compare_method = i;double base_base = compareHist( hist_base, hist_base, compare_method );double base_half = compareHist( hist_base, hist_half_down, compare_method );double base_test1 = compareHist( hist_base, hist_test1, compare_method );double base_test2 = compareHist( hist_base, hist_test2, compare_method );
?printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );}
?printf( "Done \n" );
?return 0;}

?

3.4 運行結果

  1. 第一張為基準圖像,其余兩張為測試圖像。同時我們會將基準圖像與它自身及其半身圖像進行對比。

  2. 我們應該會預料到當將基準圖像直方圖及其自身進行對比時會產生完美的匹配, 當與來源于同一樣的背景環境的半身圖對比時應該會有比較高的相似度, 當與來自不同亮度光照條件的其余兩張測試圖像對比時匹配度應該不是很好:

  3. 下面顯示的是結果數值:

對比標準基準 - 基準基準 - 半身基準 - 測試1基準 - 測試2
Correlation1.0000000.9307660.1820730.120447
Chi-square0.0000004.94046621.18453649.273437
Intersection24.39154814.9598093.8890295.775088
Bhattacharyya0.0000000.2226090.6465760.801869

對于 CorrelationIntersection 標準, 值越大相似度越大。因此可以看到對于采用這兩個方法的對比,基準 - 基準 的對比結果值是最大的, 而 基準 - 半身 的匹配則是第二好(跟我們預測的一致)。而另外兩種對比標準,則是結果越小相似度越大。 我們可以觀察到基準圖像直方圖與兩張測試圖像直方圖的匹配是最差的,這再一次印證了我們的預測。

總結

以上是生活随笔為你收集整理的【OpenCV 】直方图均衡化,直方图计算,直方图对比的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。