1. 程式人生 > >彩色影象的直方圖均衡化--基於OpenCV中EqualizeHist_Demo實現

彩色影象的直方圖均衡化--基於OpenCV中EqualizeHist_Demo實現



本文給出基於彩色影象直方圖均衡化的OpenCV程式碼與結果示例!

具體內容包含:

1. 灰度影象直方圖均衡化

2. 對RGB三通道各自均衡化後,再組合輸出結果

3. RGB影象轉化為HSI,YUV,YCbCr顏色空間後,對亮度通道進行均衡化運算後再轉回RGB空間

[cpp] view plaincopyprint?
  1. /** 
  2.  * @function EqualizeHist_Demo.cpp 
  3.  * @brief Demo code for equalizeHist function 
  4.  * @author OpenCV team 
  5.  */
  6. #include "opencv2/imgcodecs.hpp"
  7. #include "opencv2/highgui/highgui.hpp"
  8. #include "opencv2/imgproc/imgproc.hpp"
  9. #include <iostream>
  10. #include <stdio.h>
  11. usingnamespace cv;  
  12. usingnamespace std;  
  13. // add by frank, 2014-09-25
  14. Mat equalizeChannelHist(const Mat & inputImage)  
  15. {  
  16.     if( inputImage.channels() >= 3 )  
  17.     {  
  18.         vector<Mat> channels;  
  19.         split(inputImage, channels);  
  20.         Mat B,G,R;  
  21.         equalizeHist( channels[0], B );  
  22.         equalizeHist( channels[1], G );  
  23.         equalizeHist( channels[2], R );  
  24.         vector<Mat> combined;  
  25.         combined.push_back(B);  
  26.         combined.push_back(G);  
  27.         combined.push_back(R);  
  28.         Mat result;  
  29.         merge(combined, result);  
  30.         return result;  
  31.     }  
  32.     return Mat();  
  33. }  
  34. Mat equalizeIntensityHist(const Mat & inputImage)  
  35. {  
  36.     if(inputImage.channels() >= 3)  
  37.     {  
  38.         Mat ycrcb;  
  39.         cvtColor(inputImage, ycrcb, COLOR_BGR2YCrCb);  
  40.         vector<Mat> channels;  
  41.         split(ycrcb, channels);  
  42.         equalizeHist(channels[0], channels[0]);  
  43.         Mat result;  
  44.         merge(channels,ycrcb);  
  45.         cvtColor(ycrcb, result, COLOR_YCrCb2BGR);  
  46.         return result;  
  47.     }  
  48.     return Mat();  
  49. }  
  50. void getGrayImageHistImage(const Mat & src, Mat & histImage)  
  51. {  
  52.     Mat hist;  
  53.     int histSize = 256;  
  54.     calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, 0);  
  55.     normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);  
  56.     histImage = Scalar::all(255);  
  57.     int binW = cvRound((double)histImage.cols/histSize);  
  58.     forint i = 0; i < histSize; i++ )  
  59.         rectangle( histImage, Point(i*binW, histImage.rows),  
  60.         Point((i+1)*binW, histImage.rows - cvRound(hist.at<float>(i))),  
  61.         Scalar::all(0), -1, 8, 0 );  
  62. }  
  63. int main( intchar** argv )  
  64. {  
  65.     Mat src, dst;  
  66.     Mat intensity_color_dst;  
  67.     Mat channel_color_dst;  
  68.     constchar* source_gray_window = "Source Gray Image";  
  69.     constchar* equalized_gray_window = "Equalized Gray Image";  
  70.     constchar* source_color_window = "Source Color Image";  
  71.     constchar* equalized_intensity_color_window = "Equalized Intensity Color Image";  
  72.     constchar* equalized_channels_color_window = "Equalized Channels Color Image";  
  73.     /// Load image
  74.     src = imread( argv[1], 1 );  
  75.     if( src.empty() )  
  76.     {   
  77.         cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;  
  78.         return -1;  
  79.     }  
  80.     /// color image intensity equalization
  81.     {  
  82.         intensity_color_dst = equalizeIntensityHist(src);  
  83.         namedWindow( source_color_window, WINDOW_AUTOSIZE );  
  84.         namedWindow( equalized_intensity_color_window, WINDOW_AUTOSIZE );  
  85.         imshow( source_color_window, src );  
  86.         imshow( equalized_intensity_color_window, intensity_color_dst );  
  87.     }  
  88.     /// color image each channel equalization
  89.     {  
  90.         channel_color_dst = equalizeChannelHist(src);  
  91.         namedWindow( equalized_channels_color_window, WINDOW_AUTOSIZE );  
  92.         imshow( equalized_channels_color_window, channel_color_dst );  
  93.     }  
  94.     /// gray image equalization
  95.     {  
  96.         cvtColor( src, src, COLOR_BGR2GRAY );  
  97.         equalizeHist( src, dst );  
  98.         namedWindow( source_gray_window, WINDOW_AUTOSIZE );  
  99.         namedWindow( equalized_gray_window, WINDOW_AUTOSIZE );  
  100.         imshow( source_gray_window, src );  
  101.         imshow( equalized_gray_window, dst );  
  102.         /// get source gray image Histogram
  103.         Mat graySrc_histImage = Mat::ones(200, 260, CV_8U)*255;  
  104.         getGrayImageHistImage(src, graySrc_histImage);  
  105.         imshow("source gray image histogram", graySrc_histImage);  
  106.         /// get equalized gray image Histogram
  107.         Mat grayDst_histImage = Mat::ones(200, 260, CV_8U)*255;  
  108.         getGrayImageHistImage(dst, grayDst_histImage);  
  109.         imshow("Equalized gray image histogram", grayDst_histImage);  
  110.     }  
  111.     /// Wait until user exits the program
  112.     waitKey(0);  
  113.     return 0;  
  114. }  
/**
 * @function EqualizeHist_Demo.cpp
 * @brief Demo code for equalizeHist function
 * @author OpenCV team
 */

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

// add by frank, 2014-09-25
Mat equalizeChannelHist(const Mat & inputImage)
{
	if( inputImage.channels() >= 3 )
	{
		vector<Mat> channels;
		split(inputImage, channels);

		Mat B,G,R;

		equalizeHist( channels[0], B );
		equalizeHist( channels[1], G );
		equalizeHist( channels[2], R );

		vector<Mat> combined;
		combined.push_back(B);
		combined.push_back(G);
		combined.push_back(R);

		Mat result;
		merge(combined, result);

		return result;
	}

	return Mat();
}

Mat equalizeIntensityHist(const Mat & inputImage)
{
	if(inputImage.channels() >= 3)
	{
		Mat ycrcb;

		cvtColor(inputImage, ycrcb, COLOR_BGR2YCrCb);

		vector<Mat> channels;
		split(ycrcb, channels);

		equalizeHist(channels[0], channels[0]);

		Mat result;
		merge(channels,ycrcb);

		cvtColor(ycrcb, result, COLOR_YCrCb2BGR);

		return result;
	}

	return Mat();
}

void getGrayImageHistImage(const Mat & src, Mat & histImage)
{
	Mat hist;
	int histSize = 256;

	calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, 0);
	normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);

	histImage = Scalar::all(255);
	int binW = cvRound((double)histImage.cols/histSize);

	for( int i = 0; i < histSize; i++ )
		rectangle( histImage, Point(i*binW, histImage.rows),
		Point((i+1)*binW, histImage.rows - cvRound(hist.at<float>(i))),
		Scalar::all(0), -1, 8, 0 );
}


int main( int, char** argv )
{
	Mat src, dst;
	Mat intensity_color_dst;
	Mat channel_color_dst;

	const char* source_gray_window = "Source Gray Image";
	const char* equalized_gray_window = "Equalized Gray Image";
	const char* source_color_window = "Source Color Image";
	const char* equalized_intensity_color_window = "Equalized Intensity Color Image";
	const char* equalized_channels_color_window = "Equalized Channels Color Image";

	/// Load image
	src = imread( argv[1], 1 );

	if( src.empty() )
	{ 
		cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;
		return -1;
	}

	/// color image intensity equalization
	{
		intensity_color_dst = equalizeIntensityHist(src);
		
		namedWindow( source_color_window, WINDOW_AUTOSIZE );
		namedWindow( equalized_intensity_color_window, WINDOW_AUTOSIZE );

		imshow( source_color_window, src );
		imshow( equalized_intensity_color_window, intensity_color_dst );
	}

	/// color image each channel equalization
	{
		channel_color_dst = equalizeChannelHist(src);
		namedWindow( equalized_channels_color_window, WINDOW_AUTOSIZE );
		imshow( equalized_channels_color_window, channel_color_dst );
	}

	/// gray image equalization
	{
		cvtColor( src, src, COLOR_BGR2GRAY );
		equalizeHist( src, dst );

		namedWindow( source_gray_window, WINDOW_AUTOSIZE );
		namedWindow( equalized_gray_window, WINDOW_AUTOSIZE );

		imshow( source_gray_window, src );
		imshow( equalized_gray_window, dst );

		/// get source gray image Histogram
		Mat graySrc_histImage = Mat::ones(200, 260, CV_8U)*255;
		getGrayImageHistImage(src, graySrc_histImage);
		imshow("source gray image histogram", graySrc_histImage);

		/// get equalized gray image Histogram
		Mat grayDst_histImage = Mat::ones(200, 260, CV_8U)*255;
		getGrayImageHistImage(dst, grayDst_histImage);
		imshow("Equalized gray image histogram", grayDst_histImage);
	}

	/// Wait until user exits the program
	waitKey(0);

	return 0;
}

執行結果,如下圖所示:

         

           原灰度影象                                                          直方圖均衡化增強後圖像

     

             原彩色影象               RGB各通道直方圖均衡化後圖像           YCbCr 亮度通道Y直方圖均衡化後圖像

分RGB通道均衡化後圖像顏色有失真情況,而亮度通道均衡化結果不會,主要原因:

Histogram equalization is a non-linear process. Channel splitting and equalizing each channel separately is not the proper way for equalization of contrast. Equalization involves Intensity values of the image not the color components. So for a simple RGB color image, HE should not be applied individually on each channel. Rather, it should be applied such that intensity values are equalized without disturbing the color balance of the image. So, the first step is to convert the color space of the image from RGB into one of the color space which separates intensity values from color components. Some of these are:
  HSV/HLS
  YUV
  YCbCr
Convert the image from RGB to one of the above mentioned color spaces. YCbCr is preferred as it is designed for digital images.Perform HE of the intensity plane Y. Convert the image back to RGB.

相關推薦

彩色影象直方圖均衡化--基於OpenCVEqualizeHist_Demo實現

 本文給出基於彩色影象直方圖均衡化的OpenCV程式碼與結果示例! 具體內容包含: 1. 灰度影象直方圖均衡化 2. 對RGB三通道各自均衡化後,再組合輸出結果 3. RGB影象轉化為HSI,YUV,YCbCr顏色空間後,對亮度通道進行均衡化運算後再轉回RGB空間

使用C++實現彩色影象直方圖均衡化的三種方法

引言 本文主要介紹如何實現彩色影象的直方圖均衡化,達到影象增強效果的三種方法: 1. 對RGB三個通道影象分別進行直方圖均衡化,然後再合併三個通道; 2. 提取RGB三個通道影象,計算其平均直方圖結果,然後再進行均衡化; 3. RGB空間轉為HSI空間影象,對I(亮度,Intensi

opencv影象直方圖均衡化cv2.equalizeHist

目錄 一、影象直方圖 二、繪製直方圖 三、直方圖均衡化 四、直方圖均衡化效果展示   一、影象直方圖   影象的構成是有畫素點構成的,每個畫素點的值代表著該點的顏色(灰度圖或者彩色圖)。所謂直方圖就是對影象的中的這些畫素點的值進行統計,得到一個

opencv影象直方圖均衡化及其原理

直方圖均衡化是什麼有什麼用 先說什麼是直方圖均衡化,通俗的說,以灰度圖為例,原圖的某一個畫素為x,經過某個函式變為y.形成新的圖.新的圖的灰度值的分佈是均勻的,這個過程就叫直方圖均衡化. 影象直方圖均衡化作用:用來增強對比度. 這種方法通常用來增加許多影象的全域性對比度,尤其是當影象的有用資料的對比度相當接

對傾斜的影象進行修正——基於opencv 透視變換

這篇文章主要解決這樣一個問題: 有一張傾斜了的圖片(當然是在Z軸上也有傾斜,不然直接旋轉得了o(╯□╰)o),如何儘量將它糾正到端正的狀態。 而要解決這樣一個問題,可以用到透視變換。 關於透視變換的原理,網上已經有一大推了,這裡就不再做介紹了。

影象處理基礎02直方圖均衡化的推導和程式設計實現

1 簡介 直方圖均衡化是將影象轉化為另一幅影象,轉化後圖像畫素值的分佈更接近均勻分佈。原本影象的畫素值(灰度值)可能集中在某一區域,這樣我們看到的影象其實是比較模糊的,灰度沒有層次感。直方圖均衡化能夠

Matlab 彩色圖片直方圖均衡化處理 line()函式實現

好了,不說這麼多了,直奔主題,本次分別做了兩次實現,分別是:彩色圖片轉灰度圖直方圖均衡化處理以及彩色圖片的直方圖均衡化處理,大家可以按需觀看。 一、程式原始碼 (1)彩色圖片轉灰度圖直方圖均衡化處理: %讀取圖片 I=imread('test.jpg');

matlab 影象直方圖均衡化

1.讀入一幅影象,計算並繪製圖像的直方圖 >> sample = imread('sample.jpg'); >> imshow(sample); >> [M,N]

影象直方圖均衡化次數不同,結果相同簡要說明

背景介紹 如果一幅影象灰度級分佈不均、很密,集中在某個區域,那麼其對比度就較差,顯示效果不好。直方圖均衡化就是把影象灰度級進行平均展寬,使其儘可能均勻分佈,從而進而提高了對比度和灰度色調的變化,使影象更加清晰,顯示效果更好。 理論證明 設影象灰度級為L

【SVM理論到實踐4】基於OpenCv的SVM的手寫體數字識別

//由於本人每天時間非常緊張,所以細節寫的不詳細,部落格僅供各位參考,裡面的程式碼都是執行過的,直接可以執行 本章的學習目標:      1)手寫體數字識別資料庫MNIST      2)基於SVM訓練的具體步驟   1)手寫體數字識別資料庫MNIST MNIST(Mixe

直方圖均衡化的原理及C++實現

直方圖均衡化的作用是影象增強。 有兩個問題比較難懂,一是為什麼要選用累積分佈函式,二是為什麼使用累積分佈函式處理後像素值會均勻分佈。 第一個問題。均衡化過程中,必須要保證兩個條件:①畫素無論怎麼對映,一定要保證原來的大小關係不變,較亮的區域,依舊是較亮的,較暗依舊暗,只是對

Gabor濾波簡介與Opencv實現及引數變化實驗

Gabor濾波是一種非常常見的特徵提取演算法,在人臉識別等領域有著很廣泛的應用,在這裡我主要介紹一下Gabor濾波器的公式及Opencv下的程式碼實現,以及我做的一些引數變化的實驗。 一、Gabor濾波簡介 注意,這裡我介紹的Gabor演算法與在人臉識別

直方圖均衡化 原理及其C++程式碼實現

演算法原理 直方圖均衡化,是對影象進行非線性拉伸,使得一定範圍內畫素值的數量的大致相同。這樣原來直方圖中的封頂部分對比度得到了增強,而兩側波谷的對比度降低,輸出的直方圖是一個較為平坦的分段直方圖。具體來講可以表現為下面這個圖: 通過這種方法可以按照需要對影象的亮度進行調整,並且,這

基於OpenCV和C++實現最大閾值分割演算法

程式碼如下:: /********************************************************************************************************** *檔案說明: * 基於Ope

SAD立體匹配演算法在opencv實現

SAD演算法具體原理見相關影象處理書籍。 該程式是opencv中文論壇的牛人貢獻的,感謝他的工作。 [c-sharp] view plaincopyprint? // Sum of Absolute Difference(SAD) #include <

LSD在opencv實現

LSD演算法是一種直線檢測的演算法,比hough效果好,作者將程式碼和文章上傳了,詳見http://www.ipol.im/pub/art/2012/gjmr-lsd/。 opencv3.0也集成了其演算法,這邊說下如何在opencv裡面呼叫。下面程式碼其實也是opencv

各種距離在opencv實現

1、歐氏距離,用L2實現 struct CV_EXPORTS L2 { enum { normType = NORM_L2 }; typedef T ValueType; typedef typename Accumulator&l

Canny邊緣檢測演算法(基於OpenCV的Java實現

目錄 Canny邊緣檢測演算法(基於OpenCV的Java實現) 緒論 Canny邊緣檢測演算法的發展歷史 Canny邊緣檢測演算法的處理流程 用高斯濾波器平滑影象 彩色RGB

0016-在OpenCV環境下進行影象直方圖均衡化

對於一些過度曝光的影象,實質上是影象的亮度值分佈集中在某一個區域,導致影象的對比度過低。為了解決這個問題,引出了直方圖均衡化這個技術,將亮度值分佈很集中的直方圖的亮度範圍拉大至整一個亮度區域(如8位灰度圖就是到0-255)。OpenCV提供了equalizeHist這個函式來進行灰度影象的直方圖均衡

opencv equalizeHist()均衡化直方圖

1、EqualizeHist函式 函式作用: 直方圖均衡化,,用於提高影象的質量 2、EqualizeHist函式呼叫形式 C++: void equalizeHist(InputArray src, OutputArray dst) #include <op