1.更改圖像和視頻的亮度
更改亮度
更改圖像的亮度是常用的點操作。在此操作中,圖像中每個像素的值應增加/減少一個常數。要更改視頻的亮度,應對視頻中的每一幀執行相同的操作。
如果要增加圖像的亮度,則必須為圖像中的每個像素添加一些正常量值。
new_image (i, j) = image(i, j) + c
如果要降低圖像的亮度,則必須從圖像中的每個像素中減去一些正常量值。
new_image (i, j) = 圖像(i, j) - c
例如,說,這是您的原始圖像。假設圖像的數據類型是CV_8U(即 - 圖像中的像素是 8 位無符號的。因此,圖像中每個像素的有效值范圍應為 0 - 255。
![]() |
---|
原始圖像 |
假設您想將原始圖像的亮度提高 60。因此,您應該為原始圖像中的每個像素添加 60。您必須通過在原始圖像上加 60 來確保輸出圖像中的像素值不應超過允許的最大限制。如果超過最大限制,則必須分配最大值而不是正確的值。
這是亮度增加60的輸出圖像。您可能已經注意到,(3, 1) 位置的像素值為 255,盡管在 200 上加上 60 后,它應該是 260。這是因為此圖像的最大允許像素值為 255。
假設您想將原始圖像的亮度降低 20。因此,您應該從原始圖像中的每個像素中減去 20。您必須確保從原始圖像中減去 20 后,輸出圖像中的像素值不應低于允許的最小限制。如果它低于最小限制,則必須分配最小值而不是正確的值。
這是亮度降低20的輸出圖像。您可能已經注意到 (0, 0) 位置的像素值為 0,盡管從 8 中減去 20 后它應該是 -12。這是因為具有無符號數據類型的圖像的最小允許像素值為 0。
使用 OpenCV 更改圖像的亮度
需要在QT中配置包含路徑及類庫路徑
1 2
INCLUDEPATH += D:\Application\opencvdev\opencv3.4.6\rebuild_for_qt\install\include LIBS += D:\Application\opencvdev\opencv3.4.6\rebuild_for_qt\lib\libopencv_*.a
將上述代碼片段復制并粘貼到 IDE 中并運行它。
#include <QCoreApplication> #include <opencv2/opencv.hpp>using namespace std; using namespace cv;int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 讀取圖像String rootDir = "D:/Gerry/project/opencvproj/singleandslot/OpenCV-2/ImageAndVideoHandle/resources/lena.png";Mat image = imread(rootDir);// 對圖片進行亮度增強Mat imageBright50;image.convertTo(imageBright50, -1, 1, 50);Mat imageBright100;image.convertTo(imageBright100, -1, 1, 100);// 對圖像進行亮度減少Mat imageDark50;image.convertTo(imageDark50, -1, 1, -50);Mat imageDark100;image.convertTo(imageDark100, -1, 1, -100);// 定義窗口標題String OriginWind = "原圖像";String Bright50Wind = "增亮50";String Bright100Wind = "增亮100";String Dark50Wind = "減少亮度50";String Dark100Wind = "減少亮度100";// 創建四個窗體namedWindow(OriginWind, WINDOW_NORMAL);namedWindow(Bright50Wind, WINDOW_NORMAL);namedWindow(Bright100Wind, WINDOW_NORMAL);namedWindow(Dark50Wind, WINDOW_NORMAL);namedWindow(Dark100Wind, WINDOW_NORMAL);// 分別在四個窗口中顯示出來完成的圖像imshow(OriginWind, image);imshow(Bright50Wind, imageBright50);imshow(Bright100Wind, imageBright100);imshow(Dark50Wind, imageDark50);imshow(Dark100Wind, imageDark100);waitKey(0);destroyAllWindows();return a.exec(); }
![]() |
---|
亮度增加 |
![]() |
---|
亮度降低 |
解釋
讓我們逐行瀏覽上面的示例。
// Read the image file Mat image = imread("D:/My OpenCV Website/My Guitar.jpg");// Check for failure if (image.empty()) {cout << "Could not open or find the image" << endl;cin.get(); //wait for any key pressreturn -1; }
此代碼段從指定文件加載圖像。如果加載圖像失敗,程序將退出。
上面的代碼段將像素值增加指定的量,并將其存儲在給定的輸出圖像中。如果指定的值為正,則輸出圖像的亮度將增加。如果指定的值為負,則輸出圖像的亮度將降低。
Mat imageBrighnessHigh50; image.convertTo(imageBrighnessHigh50, -1, 1, 50); //increase the brightness by 50Mat imageBrighnessHigh100; image.convertTo(imageBrighnessHigh100, -1, 1, 100); //increase the brightness by 100Mat imageBrighnessLow50; image.convertTo(imageBrighnessLow50, -1, 1, -50); //decrease the brightness by 50Mat imageBrighnessLow100; image.convertTo(imageBrighnessLow100, -1, 1, -100); //decrease the brightness by 100
void Mat::convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const
此函數將每個像素值轉換為目標數據類型,并按照以下公式更改值。
pixel_value_of_output_image(x, y) = pixel_value_of_input_image(x, y) *?alpha?+?beta;
- m?- 輸出圖像。如果需要,將重新分配此數據結構。
- rtype?- 輸出圖像的類型。如果 rtype 為負值,則輸出圖像的類型將與輸入圖像的類型相同。
- alpha?- 在分配給輸出圖像之前,輸入圖像中的每個像素將乘以此數字。
- beta?- 此值將添加到輸入圖像中的每個像素并分配給輸出圖像。
//Defining window names for above images String windowNameOriginalImage = "Original Image"; String windowNameBrightnessHigh50 = "Brightness Increased by 50"; String windowNameWithBrightnessHigh100 = "Brightness Increased by 100"; String windowNameBrightnessLow50 = "Brightness Decreased by 50"; String windowNameBrightnessLow100 = "Brightness Decreased by 100";//Create and open windows for above images namedWindow(windowNameOriginalImage, WINDOW_NORMAL); namedWindow(windowNameBrightnessHigh50, WINDOW_NORMAL); namedWindow(windowNameWithBrightnessHigh100, WINDOW_NORMAL); namedWindow(windowNameBrightnessLow50, WINDOW_NORMAL); namedWindow(windowNameBrightnessLow100, WINDOW_NORMAL);//Show above images inside the created windows. imshow(windowNameOriginalImage, image); imshow(windowNameBrightnessHigh50, imageBrighnessHigh50); imshow(windowNameWithBrightnessHigh100, imageBrighnessHigh100); imshow(windowNameBrightnessLow50, imageBrighnessLow50); imshow(windowNameBrightnessLow100, imageBrighnessLow100);
上面的代碼片段將創建窗口并在其中顯示圖像。
上面的代碼段將等待,直到按下任何鍵。按鍵后,所有創建的窗口將被銷毀。
1 2 3
waitKey(0); // Wait for any key strokedestroyAllWindows(); //destroy all open windows
使用 OpenCV 更改視頻的亮度
#include <QCoreApplication> #include <opencv2/opencv.hpp>using namespace std; using namespace cv;int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 讀取圖像String VideoDir = "D:/Gerry/project/opencvproj/singleandslot/OpenCV-2/ImageAndVideoHandle/resources/點云應用.mp4";// 打開視頻文件并進行數據讀取VideoCapture cap(VideoDir);// 定義窗口標題String OriginWind = "原視頻";String Bright50Wind = "增亮50";String Bright100Wind = "增亮100";String Dark50Wind = "減少亮度50";String Dark100Wind = "減少亮度100";// 創建四個窗體namedWindow(OriginWind, WINDOW_NORMAL);namedWindow(Bright50Wind, WINDOW_NORMAL);namedWindow(Bright100Wind, WINDOW_NORMAL);namedWindow(Dark50Wind, WINDOW_NORMAL);namedWindow(Dark100Wind, WINDOW_NORMAL);while(true){// 可以把視頻中每一幀看成一張圖像來進行處理Mat frame;// 通過視頻捕獲對象來獲取每一幀cap.read(frame);// 對圖片進行亮度增強Mat imageBright50;frame.convertTo(imageBright50, -1, 1, 50);Mat imageBright100;frame.convertTo(imageBright100, -1, 1, 100);// 對圖像進行亮度減少Mat imageDark50;frame.convertTo(imageDark50, -1, 1, -50);Mat imageDark100;frame.convertTo(imageDark100, -1, 1, -100);// 分別在四個窗口中顯示出來完成的圖像imshow(OriginWind, frame);imshow(Bright50Wind, imageBright50);imshow(Bright100Wind, imageBright100);imshow(Dark50Wind, imageDark50);imshow(Dark100Wind, imageDark100);if (waitKey(10) == 27){cout << "ESC退出程序";break;}}destroyAllWindows();return a.exec(); }
2.更改圖像和視頻的對比度
更改圖像的對比度也是一種常用的點操作。在此操作中,圖像中每個像素的值應乘以不等于 1 的正常數。要更改視頻的對比度,應對視頻中的每個幀執行相同的操作。為了增加圖像的對比度,圖像中的每個像素都應乘以大于1的正常數。
new_image (i, j) = image(i, j) * c (c > 1)
為了降低圖像的對比度,圖像中的每個像素都應乘以小于該常數的正常數。
new_image (i, j) = image(i, j) * c (0 < c < 1)
例如,說,這是您的原始圖像。假設圖像的數據類型為 CV_8U.(即 - 圖像中的像素是 8 位無符號的。請參閱?OpenCV C++ API?了解更多信息。因此,圖像中每個像素的有效值范圍應為 0 - 255。
![]() |
---|
原始圖像 |
假設您想將原始圖像的對比度提高 2 倍。因此,您應該將原始圖像中的每個像素乘以 2。必須確保輸出圖像中的像素值在乘法后不應超過允許的最大限制。如果超過最大限制,則必須分配最大值而不是正確的值。
這是對比度增加 2 倍的圖像。您可能已經注意到 (0, 0) 位置的像素值為 255,盡管將 288 乘以 144 后它應該是 2。這是因為此圖像的最大允許像素值為 255。
![]() |
---|
對比度增加 2 倍的圖像 |
比如說,你想將原始圖像的對比度減半。因此,您應該將原始圖像中的每個像素乘以 0.5。這是對比度降低的圖像。
使用 OpenCV 更改圖像的對比度
#include <QCoreApplication> #include <opencv2/opencv.hpp>using namespace std; using namespace cv;int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 從文件讀取到對象中String rootDir = "D:/Gerry/project/opencvproj/singleandslot/OpenCV-2/ImageAndVideoHandle/resources/lena.png";Mat image = imread(rootDir);// 增加圖像對比度Mat constrast2;image.convertTo(constrast2, -1, 2, 0);Mat constrast4;image.convertTo(constrast4, -1, 4, 0);// 減少圖形對比度Mat constrastLow_0_5;image.convertTo(constrastLow_0_5, -1, 0.5, 0);Mat constrastLow_0_2_5;image.convertTo(constrastLow_0_2_5, -1, 0.25, 0);// 定義窗口標題String OriginWind = "原圖像";String Bright50Wind = "增加2倍";String Bright100Wind = "增加4倍";String Dark50Wind = "減少0.5倍";String Dark100Wind = "減少0.25倍";// 創建四個窗體namedWindow(OriginWind, WINDOW_NORMAL);namedWindow(Bright50Wind, WINDOW_NORMAL);namedWindow(Bright100Wind, WINDOW_NORMAL);namedWindow(Dark50Wind, WINDOW_NORMAL);namedWindow(Dark100Wind, WINDOW_NORMAL);// 分別在四個窗口中顯示出來完成的圖像imshow(OriginWind, image);imshow(Bright50Wind, constrast2);imshow(Bright100Wind, constrast4);imshow(Dark50Wind, constrastLow_0_5);imshow(Dark100Wind, constrastLow_0_2_5);waitKey(0);destroyAllWindows();return a.exec(); }
![]() |
---|
對比度增加 |
![]() |
---|
對比度降低 |
代碼解釋
// Read the image file Mat image = imread("D:/My OpenCV Website/Christmas.jpg");// Check for failure if (image.empty()) {cout << "Could not open or find the image" << endl;cin.get(); //wait for any key pressreturn -1; }
此代碼段從指定文件加載圖像。如果加載圖像失敗,程序將退出。
上面的代碼段將像素值乘以指定的量,并將其存儲在給定的輸出圖像中。如果指定的值大于 1,則輸出圖像的對比度將增加。如果指定的值小于 1,則輸出圖像的對比度將降低。
Mat imageContrastHigh2; image.convertTo(imageContrastHigh2, -1, 2, 0); //increase the contrast by 2Mat imageContrastHigh4; image.convertTo(imageContrastHigh4, -1, 4, 0); //increase the contrast by 4Mat imageContrastLow0_5; image.convertTo(imageContrastLow0_5, -1, 0.5, 0); //decrease the contrast by 0.5Mat imageContrastLow0_25; image.convertTo(imageContrastLow0_25, -1, 0.25, 0); //decrease the contrast by 0.25
void Mat::convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const
此函數將每個像素值轉換為目標數據類型,并按照以下公式更改值。
pixel_value_of_output_image(x, y) = pixel_value_of_input_image(x, y) *?alpha?+?beta;
- m?- 輸出圖像。如果需要,將重新分配此數據結構。
- rtype?- 輸出圖像的類型。如果 rtype 為負值,則輸出圖像的類型將與輸入圖像的類型相同。
- alpha?- 在分配給輸出圖像之前,輸入圖像中的每個像素將乘以此數字。
- beta?- 此值將添加到輸入圖像中的每個像素并分配給輸出圖像。
//Defining window names for above images String windowNameOriginalImage = "Original Image"; String windowNameContrastHigh2 = "Contrast Increased by 2"; String windowNameContrastHigh4 = "Contrast Increased by 4"; String windowNameContrastLow0_5 = "Contrast Decreased by 0.5"; String windowNameContrastLow0_25 = "Contrast Decreased by 0.25";//Create and open windows for above images namedWindow(windowNameOriginalImage, WINDOW_NORMAL); namedWindow(windowNameContrastHigh2, WINDOW_NORMAL); namedWindow(windowNameContrastHigh4, WINDOW_NORMAL); namedWindow(windowNameContrastLow0_5, WINDOW_NORMAL); namedWindow(windowNameContrastLow0_25, WINDOW_NORMAL);//Show above images inside the created windows. imshow(windowNameOriginalImage, image); imshow(windowNameContrastHigh2, imageContrastHigh2); imshow(windowNameContrastHigh4, imageContrastHigh4); imshow(windowNameContrastLow0_5, imageContrastLow0_5); imshow(windowNameContrastLow0_25, imageContrastLow0_25);
上面的代碼片段將創建窗口并在其中顯示圖像。由于窗口是通過傳遞標志WINDOW_NORMAL創建的,因此可以自由調整窗口大小。
上面的代碼段將等待,直到按下任何鍵。按鍵后,所有創建的窗口將被銷毀。
1 2
waitKey(0); // Wait for any key stroke destroyAllWindows(); //destroy all open windows
使用 OpenCV 更改視頻的對比度
#include <QCoreApplication> #include <opencv2/opencv.hpp>using namespace std; using namespace cv;int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);String VideoDir = "D:/Gerry/project/opencvproj/singleandslot/OpenCV-2/ImageAndVideoHandle/resources/點云應用.mp4";// 打開視頻文件并進行數據讀取VideoCapture cap(VideoDir);// 定義窗口標題String OriginWind = "原視頻";String Bright50Wind = "增加2倍對比度";String Bright100Wind = "增加4倍對比度";String Dark50Wind = "減少0.5倍對比度";String Dark100Wind = "減少0.25倍對比度";// 創建四個窗體namedWindow(OriginWind, WINDOW_NORMAL);namedWindow(Bright50Wind, WINDOW_NORMAL);namedWindow(Bright100Wind, WINDOW_NORMAL);namedWindow(Dark50Wind, WINDOW_NORMAL);namedWindow(Dark100Wind, WINDOW_NORMAL);while(true){// 可以把視頻中每一幀看成一張圖像來進行處理Mat frame;// 通過視頻捕獲對象來獲取每一幀cap.read(frame);// 對圖片進行對比度增強Mat imageConstrast2;frame.convertTo(imageConstrast2, -1, 2, 0);Mat imageConstrast4;frame.convertTo(imageConstrast4, -1, 4, 0);// 對圖像進行對比度減少Mat imageDark0_5;frame.convertTo(imageDark0_5, -1, 0.5, 0);Mat imageDark0_2_5;frame.convertTo(imageDark0_2_5, -1, 0.25, 0);// 分別在四個窗口中顯示出來完成的圖像imshow(OriginWind, frame);imshow(Bright50Wind, imageConstrast2);imshow(Bright100Wind, imageConstrast4);imshow(Dark50Wind, imageDark0_5);imshow(Dark100Wind, imageDark0_2_5);if (waitKey(10) == 27){cout << "ESC退出程序";break;}}destroyAllWindows();return a.exec(); }