圖像亮度通俗理解便是圖像的明暗程度,數字圖像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之間,則 f 值越接近0亮度越低,f 值越接近255亮度越高。而且我們也要把亮度和對比度區分開來,正如上述提的對比度指的是最高和最低灰度級之間的灰度差。
飽和度指的是圖像顏色種類的多少, 上面提到圖像的灰度級是[Lmin,Lmax],則在Lmin、Lmax 的中間值越多,便代表圖像的顏色種類多,飽和度也就更高,外觀上看起來圖像會更鮮艷,調整飽和度可以修正過度曝光或者未充分曝光的圖片。使圖像看上去更加自然
對於數字圖像變換,設原像素灰度為 f(i,j),轉化后的像素灰度為 g(i,j),則常用的線性變換是 g(i,j)= af(i,j) + b, 其中系數 a 影響圖像的對比度,系數 b 影響圖像的亮度,具體如下:
(1) a=1時是原圖;
(2) a>1時對比度增強,圖像看起來更加清晰;
(3) a<1時對比度減弱,圖像看起來變暗;
(4) b影響圖像的亮度,隨着增加b (b>0)和減小b (b>0),圖像整體的灰度值上移或者下移, 也就是圖像整體變亮或者變暗, 不會改變圖像的對比度
常用代碼:
在opencv中圖像數據是存放在Mat數據類型中,我們知道一個像素有rgb構成,所以Mat是個三維數組,一下就是簡單的獲取mat中圖像像素。
//三個for循環,執行運算 new_image(i,j) =a*image(i,j) + b for(int y = 0; y < image.rows; y++ ) { for(int x = 0; x < image.cols; x++ ) { for(int c = 0; c < 3; c++ ) { new_image.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (g_nContrastValue*0.01)*(image.at<Vec3b>(y,x)[c] ) + g_nBrightValue ); } } }
上述代碼中image.at<Vec3b>(y,x)[c] 其中,y是像素所在的行, x是像素所在的列, c是R、G、B(對應0、1、2)其中之一。
saturate_cast為了安全轉換,運算結果可能超出像素取值范圍(溢出),還可能是非整數(如果是浮點數的話),用saturate_cast對結果進行轉換,以確保它為有效值。
代碼如下:
//-----------------------------------【頭文件包含部分】--------------------------------------- // 描述:包含程序所依賴的頭文件 //---------------------------------------------------------------------------------------------- #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "opencv2/imgproc/imgproc.hpp" #include <iostream> //-----------------------------------【命名空間聲明部分】--------------------------------------- // 描述:包含程序所使用的命名空間 //----------------------------------------------------------------------------------------------- using namespace std; using namespace cv; //-----------------------------------【全局函數聲明部分】-------------------------------------- // 描述:全局函數聲明 //----------------------------------------------------------------------------------------------- static void ContrastAndBright(int, void *); //-----------------------------------【全局變量聲明部分】-------------------------------------- // 描述:全局變量聲明 //----------------------------------------------------------------------------------------------- int g_nContrastValue; //對比度值 int g_nBrightValue; //亮度值 Mat g_srcImage, g_dstImage; //-----------------------------------【main( )函數】-------------------------------------------- // 描述:控制台應用程序的入口函數,我們的程序從這里開始 //----------------------------------------------------------------------------------------------- int main() { //改變控制台前景色和背景色 system("color 2F"); // 讀入用戶提供的圖像 g_srcImage = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\cat.jpg"); if (!g_srcImage.data) { printf("讀取g_srcImage圖片錯誤~! \n"); return false; } g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type()); //設定對比度和亮度的初值 g_nContrastValue = 80; g_nBrightValue = 80; //創建窗口 namedWindow("【效果圖窗口】", 1); //創建軌跡條 createTrackbar("對比度:", "【效果圖窗口】", &g_nContrastValue, 300, ContrastAndBright); createTrackbar("亮 度:", "【效果圖窗口】", &g_nBrightValue, 200, ContrastAndBright); //調用回調函數 ContrastAndBright(g_nContrastValue, 0); ContrastAndBright(g_nBrightValue, 0); //輸出一些幫助信息 cout << endl << "\t運行成功,請調整滾動條觀察圖像效果\n\n" << "\t按下“q”鍵時,程序退出\n"; //按下“q”鍵時,程序退出 while (char(waitKey(1)) != 'q') {} return 0; } //-----------------------------【ContrastAndBright( )函數】------------------------------------ // 描述:改變圖像對比度和亮度值的回調函數 //----------------------------------------------------------------------------------------------- static void ContrastAndBright(int, void *) { // 創建窗口 namedWindow("【原始圖窗口】", 1); // 三個for循環,執行運算 g_dstImage(i,j) = a*g_srcImage(i,j) + b for (int y = 0; y < g_srcImage.rows; y++) { for (int x = 0; x < g_srcImage.cols; x++) { for (int c = 0; c < 3; c++) { g_dstImage.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue); } } } // 顯示圖像 imshow("【原始圖窗口】", g_srcImage); imshow("【效果圖窗口】", g_dstImage); }
效果圖: