C++影像處理 — 線性亮度/對比調整

來源:互聯網
上載者:User

閱讀提示

    《C++影像處理》系列以代碼清晰,可讀性為主,全部使用C++代碼。

    《Delphi影像處理》系列以效率為側重點,一般代碼為PASCAL,核心代碼採用BASM。

    儘可能保持二者內容一致,可相互對照。

    本文代碼必須包括《C++影像處理 -- 資料類型及公用函數》文章中的BmpData.h標頭檔。

 

    本文代碼是在《C++影像處理 -- 亮度/對比調整》基礎上,通過改非亮度為線性亮度而成的。

映像亮度調整分為非線性和線性兩種方法。

    非線性映像亮度是將映像像素的R、G、B分別加上或減去某個值,其優點是代碼簡單,亮度調整速度快;缺點是映像資訊損失較大,調整過的 映像顯得平淡,無層次感。

    線性映像亮度一般是將映像像素的RGB轉換為HSL(HSV)等色彩空間,對L(V)部分進行增減調整後,再轉換為RGB色彩空間,優點是調整過映像層次感很強;缺點是代碼較複雜,調整速度慢,而且當映像亮度增減量較大時有很大的失真。

    針對上面兩種方法的優缺點,本人蔘照Photoshop的對比、飽和度調整原理(可參見本人的有關文章),對映像亮度調整方法進行了改進,經測試,效果還不錯,主要有不失真調整範圍寬、有較好的層次感、儘可能減少映像資訊損失量等;同時,在代碼處理上,採用了灰階表尋找法,先按製造了一個256個元素大小的線性亮度/對比尋找表,然後對映像資料逐像素按R、G、B分量值在尋找表中取得調整後的資料,因此處理速度同《C++影像處理 -- 亮度/對比調整》中的非線性亮度/對比是基本相同的。

    原理用公式表示為:

    如果亮度增減量value範圍為 -1  --  +1,當value > 0時:

      rgb = RGB + RGB * (1 / (1 - value) - 1)

    當value < 0時:

      rgb = RGB + RGB * value

    下面是映像線性亮度調整C/C++代碼(使用C++ Builder編譯器和GDI+庫),包括例子代碼:

//---------------------------------------------------------------------------FORCEINLINEINT CheckValue(INT value){return (value & ~0xff) == 0? value : value > 255? 255 : 0;}//---------------------------------------------------------------------------// 線性亮度/對比調整VOID LineBrightAndContrast(BitmapData *data, INT bright, INT contrast, BYTE threshold){if (bright == 0 && contrast == 0)return;FLOAT bv = bright <= -255? -1.0f : bright / 255.0f;if (bright > 0 && bright < 255)bv = 1.0f / (1.0f - bv) - 1.0f;FLOAT cv = contrast <= -255? -1.0f : contrast / 255.0f;if (contrast > 0 && contrast < 255)cv = 1.0f / (1.0f - cv) - 1.0f;BYTE values[256];for (INT i = 0; i < 256; i ++){INT v = contrast > 0? CheckValue(i + (INT)(i * bv + 0.5f)) : i;if (contrast >= 255)v = v >= threshold? 255 : 0;elsev = CheckValue(v + (INT)((v - threshold) * cv + 0.5f));values[i] = contrast <= 0? CheckValue(v + (INT)(v * bv + 0.5f)) : v;}PARGBQuad p = (PARGBQuad)data->Scan0;INT offset = data->Stride - data->Width * sizeof(ARGBQuad);for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset){for (UINT x = 0; x < data->Width; x ++, p ++){p->Blue= values[p->Blue];p->Green= values[p->Green];p->Red= values[p->Red];}}}//---------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender){Gdiplus::Bitmap *bmp =  new Gdiplus::Bitmap(L"..\\..\\media\\source1.jpg");Gdiplus::Graphics *g = new Gdiplus::Graphics(Canvas->Handle);g->DrawImage(bmp, 0, 0);BitmapData data;LockBitmap(bmp, &data);LineBrightAndContrast(&data, 20, 0, 121);UnlockBitmap(bmp, &data);g->DrawImage(bmp, data.Width, 0);delete g;delete bmp;}//---------------------------------------------------------------------------

    下面是用RGB非線性亮度調整(中)、HSL線性亮度調整(右)以及本文介紹的改進線性亮度調整方法(左)對同一照片的調整結果貼圖:

                      原圖:

 

    因水平有限,錯誤在所難免,歡迎指正和指導。郵箱地址:maozefa@hotmail.com

    這裡可訪問《C++影像處理 -- 文章索引》。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.