OpenCV圖像處理|1.7 調整圖像亮度與對比度
來自專欄 OpenCV圖像處理教程
1.7 調整圖像亮度與對比度
(b * alpha + beta)
(1)理論
圖像變換可以看作如下:
1)像素變換 – 點操作,用在調整圖像亮度和對比度等操作上。
2)鄰域操作 – 區域,用在圖像卷積、特徵提取、梯度計算、模式匹配識別、角點檢測、模糊、平滑等操作上。
調整圖像亮度和對比度(contrast and brightness change)屬於像素變換-點操作,公式為:
float alpha = 1.2; //對比度係數,小於1變暗,大於1變亮float beta = 30; //亮度增益Mat m1;src.convertTo(m1, CV_32F); //src數據類型轉變為m1的32位,切換成浮點型float b = m1.at<Vec3f>(row, col)[0];//讀三通道像素,不能直接用Vec3f,要用Vec3b,因為是opencv是8UC的數據,除非提前src.convertTo轉換類型dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta); //寫像素,修改亮度和對比度,確保值在0-255內
亮度:增益變數就是在前面基礎上再加多少,亮度表示0-255之間的像素值大小,越亮越向白的靠攏,像素值就該越大,整體要提高亮度就要擴大增益變數beta;
對比度:提高對比度就是擴大兩圖像像素的差值,增大alpha。提高對比度就是增大差值,大的越大,小的越小。對比度係數alpha,小於1變暗,大於1變亮。
(2)重要的API
f(i,j)、g(i,j)表示輸入、輸出圖像的一個像素點;圖像就是數據,數據可以千變萬化,可以是浮點double等各種類型的數據。RGB是最常見的圖像的數據,必須是正數取值範圍0~255,而TIF的數據格式可能有負數。
空白圖像:
Mat new_image = Mat::zeros( image.size(), image.type() ); 創建一張跟原圖像大小和類型一致的空白圖像、像素值初始化為0
dst = Mat::zeros(src.size(), src.type());
確保值:
saturate_cast<uchar>(value); 確保值大小範圍為0~255之間
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta); //寫像素,修改亮度和對比度
寫像素:
Mat.at<Vec3b>(y,x)[index]=value; 給每個像素點每個通道賦值。
完整程序:
/*1.7 亮度和對比度*/#include <opencv2/opencv.hpp>#include <iostream> using namespace cv; //使用cv命名空間int main(int argc, char** argv) { //argc 表示命令行輸入參數的個數(以空白符分隔),argv中存儲了所有的命令行參數 Mat src, dst; src = imread("E:/OpenCV/testimage/test5.jpg"); //輸入圖像默認讀進來的方式RGB,但是三個通道的排序是BGR if (src.empty()) { printf("could not load image...
"); return -1; } char input_win[] = "input image"; //字元命名// cvtColor(src, src, CV_BGR2GRAY);//灰度 namedWindow(input_win,CV_WINDOW_AUTOSIZE); imshow(input_win, src); /*亮度和對比度修改 contrast and brightness change*/ int height = src.rows; int width = src.cols; dst = Mat::zeros(src.size(), src.type()); float alpha = 1.2; //對比度係數,小於1變暗,大於1變亮 float beta = 30; //亮度增益 Mat m1; src.convertTo(m1, CV_32F); //src數據類型轉變為m1的32位,切換成浮點型 for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { if (src.channels() == 3) { float b = m1.at<Vec3f>(row, col)[0];//讀三通道像素,不能直接用Vec3f,要用Vec3b,因為是opencv是8UC的數據,除非提前src.convertTo轉換類型 float g = m1.at<Vec3f>(row, col)[1];//green float r = m1.at<Vec3f>(row, col)[2];//red dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta); //寫像素,修改亮度和對比度 dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta); dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta); } else if (src.channels() == 1) { float v = src.at<uchar>(row, col); //讀一通道像素 dst.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta); } } } char output_title[] = "contrast and brightness change demo"; namedWindow(output_title, CV_WINDOW_AUTOSIZE); imshow(output_title, dst); waitKey(0); return 0;}
運行結果:
推薦閱讀:
※使用 OpenCV 進行高動態範圍(HDR)成像
※每天一練P3-Python和OpenCV做圖像處理(inRange)
※OpenCV 之windows下安裝
※霍夫圓檢測