系列文章目錄
C++ OpenCV4.5環境搭建(一)
C++ OpenCV4.5常用API查詢手冊(二)
C++ OpenCV4.5 圖像處理(三)
C++ OpenCV4.5 繪制形狀與文字(四)
C++ OpenCV4.5 圖像模糊(五)
C++ OpenCV4.5 項目實戰一(六)
C++ OpenCV4.5 形态學操作(七)
文章目錄
- 系列文章目錄
- 前言
- 一、像素值計算
- 二、使用cv::add
- 三、使用cv::addWeighted
- 四、主函數
- 總結
前言
本篇介紹如何調整圖像亮度和對比度的方法,效果等價于美圖app中的小功能,目測不止這幾種方式,持續更新!
一、像素值計算
通過對每個點的像素值進行加減計算,達到調整圖檔亮度的目的,示例代碼如下:
// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
int iWidth = img.cols;
int iHeight = img.rows;
int iChannels = img.channels();
// 直接挨個像素點加上某個值
for (int row = 0; row < iHeight; row++)
{
// 可以指針偏移,也可用使用數組下标通路
uchar* pCurRow = img.ptr<uchar>(row);
for (int col = 0; col < iWidth; col++)
{
if (iChannels == 1)
{
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
}
else if (iChannels == 3)
{
// saturate_cast 防止顔色溢出操作;像素值小于0時,指派0;大于255時,指派255
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
}
}
}
imshow(g_pOutputWinTitle, img);
}
二、使用cv::add
使用cv::add等API進行圖像像素計算,實作圖像對比度調整,示例代碼如下:
// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
Mat dst;
Mat src2 = Mat::zeros(img.size(), img.type());
src2 = Scalar(iPos, iPos, iPos);
// 功能:計算兩個圖像的像素值的和
// 參數:src1 第一個輸入圖像
// src2 第二個輸入圖像
// dst 與輸入圖像具有相同大小和通道數的輸出圖像;深度由dtype或src1/src2定義
// mask 可選操作掩碼-8位單通道圖像,指定要更改的輸出圖像元素。
// dtype 輸出圖像的可選深度,src1和src2深度相等時可設定值-1(預設)
add(img, src2, dst);
// 如果src1和src2深度相同,等價于
//dst = img + src2;
// 相減 subtract,參數清單同上,如果深度相同,等價于dst = src1 - src2;
// 相乘 multiply,參數清單同上,像素值之間的運算
// 相除 divide,參數清單同上,像素值之間的運算
imshow(g_pOutputWinTitle, dst);
}
三、使用cv::addWeighted
圖像混合函數addWeighted不但可以調整亮度,還可以調整對比度,代碼如下(示例):
// 增加 亮度/對比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
// addWeighted的兩張混合圖像的大小和類型必須一緻
Mat src2 = Mat::zeros(img.size(), img.type());
Mat dst;
/*******************************調整圖像亮度**********************************/
// 使用圖像混合函數(dst = src1*alpha + src2*beta + gamma;)
// 輸入圖像1權重為1,輸入圖像2的權重設定為0,增加gamma的值即可實作亮度調整
addWeighted(img, 1.0, src2, 0, iPos, dst);
imshow(g_pOutputWinTitle, dst);
/*******************************調整圖像對比度**********************************/
// 使用圖像混合函數(dst = src1*alpha + src2*beta + gamma;)
// 輸入圖像2的權重設定為0,gamma的值為0,修改輸入圖像1的權重、可實作對比度調整
//double dContrast = (double)iPos / 100.0;
//addWeighted(img, dContrast, src2, 0, 0, dst);
//imshow(g_pOutputWinTitle, dst);
}
四、主函數
代碼如下(示例):
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using std::cout;
using std::endl;
char* g_pOutputWinTitle = "輸出圖像";
int g_iBrightnessValue1 = 30;
int g_iBrightnessValue2 = 30;
int g_iBrightnessValue3 = 30;
int g_iBrightnessMax = 255;
// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata);
// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata);
// 增加 亮度/對比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata);
int main(void)
{
Mat img = imread("E:\\2.png");
if (img.empty())
{
cout << "load image fail." << endl;
return -1;
}
imshow("輸入圖像", img);
namedWindow(g_pOutputWinTitle);
createTrackbar("亮度調整方法一", g_pOutputWinTitle, &g_iBrightnessValue1, g_iBrightnessMax, IncreaseBrightness1, (void*)&img);
createTrackbar("亮度調整方法二", g_pOutputWinTitle, &g_iBrightnessValue2, g_iBrightnessMax, IncreaseBrightness2, (void*)&img);
createTrackbar("亮度調整方法三", g_pOutputWinTitle, &g_iBrightnessValue3, g_iBrightnessMax, IncreaseBrightness3, (void*)&img);
IncreaseBrightness1(g_iBrightnessValue1, (void*)&img);
waitKey(0);
return 0;
}
總結
純粹是學習道路上的一點記錄,很多地方了解的不是很透徹,不足的地方歡迎指正,會一直完善!