opencv實戰從0到N (6)—— 直方圖與均衡化

opencv實戰從0到N (6)—— 直方圖與均衡化

來自專欄機器視覺與深度學習

直方圖及均衡化

1,直方圖是求像素在各個數值上的統計數值,如0-255的圖像,其灰度直方圖即它各個數值出現次數的統計結果,

可以用直方圖的形式顯示。

函數:calcHist( &rgb[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );

參數:

&rgb[0]: 輸入數組(或數組集)

1: 輸入數組的個數 (這裡我們使用了一個單通道圖像,我們也可以輸入數組集 )

0: 需要統計的通道 (dim)索引 ,這裡我們只是統計了灰度 (且每個數組都是單通道)所以只要寫 0 就行了。

Mat(): 掩碼( 0 表示忽略該像素), 如果未定義,則不使用掩碼

r_hist: 儲存直方圖的矩陣

1: 直方圖維數

histSize: 每個維度的bin數目

histRange: 每個維度的取值範圍

uniform 和 accumulate: bin大小相同,清除直方圖痕迹

2,直方圖均衡化是將各個數值出現的次數均勻化,如圖像各個像素出現的都集中在一段區域,

可以用直方圖均衡化將其拉伸到各個區域。

函數:equalizeHist( InputArray src, OutputArray dst );

3,直方圖統計測試:

void main()

{

Mat src, dst;

/// 裝載圖像

src = imread("2.jpg");

/// 分割成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);

}

4,直方圖均衡化測試:

void main()

{

Mat src, dst;

/// 裝載圖像

src = imread("2.jpg",0);

imshow("src", src);

equalizeHist(src, dst);

imshow("dst", dst);

waitKey(0);

}

推薦閱讀:

python圖像識別精講之OpenCV模塊(1)
機器視覺領域,實驗台的簡便性,對機器視覺方案的產出也有很大影響
每天一練P2 Python和OpenCV做圖像處理(cvtColor)
OpenCV之二值化處理
每天一練P1 Python和OpenCV做圖像處理(imread)

TAG:圖像處理 | 計算機視覺 | OpenCV |