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)