影像對比度和亮度

dbdxnuliba發表於2020-12-31

影像對比度和亮度

影像亮度通俗理解便是影像的明暗程度,數字影像 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 );
                     }
              }
       }

複製程式碼//g_nContrastValue是對比度, g_nBrightValu是亮度;及對應g(i,j)= af(i,j) + b, 其中係數 a 影響影像的對比度,係數 b 影響影像的亮度;

複製程式碼

上述程式碼中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);
}

複製程式碼

效果圖:

 

相關文章